vue3-基础

vue3

  • 2020年9月18日发布,但是大多数公司还未使用。

  • 2022年2月7日成为默认版本。

  • vue2配合的是vuex3和vue-router3使用。

  • vue3配合的是vuex4和vue-router4使用。

vue3优点:

  1. 首次渲染更快

  2. diff算法更快

  3. 内存占用更少

  4. 打包体积更小

  5. 更好的Typescript支持(Typescript是js的升级版)

  6. Composition API 组合 API(方法,工具函数)

回顾vue2、webpack

vue2通过vue/cli 也是webpack创建的,他提供了devServer开发服务器,但是会把所有代码打包再放到devServer,才能看到网页,所以项目越大启动时间越长。

webpack是打包,所有代码不管用不用都打包,让放到devServer开发服务器。

vite

  • vite的原理:利用原生ESM方法提供源码,实际上是让浏览器接管了打包程序的部分工作。

  • vite只需要在浏览器请求源码时进行转换并 按需提供源码。

  • 根据情境动态带入代码,即只在当前屏幕上实际使用时才会被处理。

创建vue3

创建vue2 ,要全局安装:npm i @vue/cli -g ,再创建项目:vue create 项目名

创建vue3项目 :

yarn create vite 或 npm create vite@latest

安装nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
常用nvm命令
# 安装指定node版本
nvm install v14.15.0
# 运行指定node版本
nvm use v14.15.0
# 切换到最新的node版本
nvm use node
# 远程服务器上所有的可用版本
nvm ls-remote
# 给不同的版本号设置别名
nvm alias node_cms 14.15.0
# 使用该别名
nvm use node_cms
# 查看已安装node列表
nvm ls

vue2和vue3区别

插件不同

  • vue2的vetur插件需要禁用,vue3用的volar插件需要安装。

组件一个根节点非必需

  • template中可以多个节点

<template>
  <div>节点1</div>
  <div>节点2</div>
</template>

创建应用挂载到根容器

  • 在main.js中写法的区别

  • *vue2写法:导入Vue和App.vue 挂载到唯一的App组件上

import Vue from 'vue'
import App from './App.vue'
new Vue({render:h=>h(App)}).$mount('#app')
  • vue3中依然是创建vue实例,将App根组件渲染至App盒子中

    vue3中会大量使用函数调用的方法来创建实例或完成功能

import { createApp } from 'vue'//类似于之前的new Vue()
import './style.css'
import App from './App.vue'
const app = createApp(App)//得到vue的应用实例
app.mount('#app')//渲染到app盒子中

入口页面,ESM 加载资源

  • ---- index.html

<div id="app"></div>
<script type="module" src="/src/main.js"></script>

组件中写法差别

只有script中的写法不同,template结构语法完全一致

vue3中基本是函数的调用

API差别

先定义数据,再使用数据

选项式api options API

  • vue2是典型的options API 选项式api

    • 优点:对新手友好,属性方法等放到对应的选项里面

    • 缺点:相关功能逻辑代码 被割裂了 不好维护

    export default{
        data(){ return{} },
        methods:{},
        watch:{},
        components:{},
        computed:{}
    }

组合式api composition API

  • vue3是典型的composition API 组合式api 需要什么功能,就直接调用某个封装好的函数即可。

    • 但是vue3兼容所有vue2的写法

    • 所有逻辑在setup函数中,使用 ref、watch 等函数组织代码是组合式API写法

    • 优点:将某个功能相关的代码 组织在一起 好维护

    reactive()  ref()
    computed()
    watch()

setup函数

  • 相当于钩子函数----触发时机比vue2中的beforeCreate还早,在组件创建之前的钩子。

  • 也是组合式api的入口,所有组合式api代码都写在这个函数中

  • setup函数this不是组件实例,是undefined -----vue3中也不需要this

  • 如果数据或函数在模板中使用,需要在setup返回

    (react标准的是class,因为this等不好用的问题,衍生了hooks,而vue3就学了创了组合式API )

vue2和vue3都是数据驱动视图!这个数据得是响应式的数据

  • vue2中是写在data函数中的 Object.defineProperty()

  • vue3中数据响应式 Proxy响应式 reactive() ref()

Proxy响应式

reactive()

  • reactive针对复杂数据(不能转换简单) 变响应式

  • 把数据放到reactive() 中,会被Proxy变为响应式

    复杂数据
    <script setup>
        const obj = reactive({
                age:18,
                name:'zs' })
        const ageAdd = () => {
                obj.age++}
    </script>

ref()

  • ref将任何数据 变响应式(不限类型)

  • 把数据放到ref() 中,会被Proxy变为响应式

  • 注意点:

    • ref可以将任何数据都变为响应式,但是在script中需要通过.vlaue来返回结果

    • 在模板中不需要.value ===>因为内部底层已经自动解套了一层

      简单数据
      <div>{{count}}</div>
      <button @click="addOne">+1</button>
      ​
      setup(){
              let count = ref(99)
              const addOne = () => {
                  count.value++}
              return{count,addOne}
          },
      复杂数据类型
      <button @click="ageAdd">过了一年{{obj.age}}</button>
      ​
      <script setup>
          const obj = ref({
                  age:18,
                  name:'zs'})
          const ageAdd = () => {
                  obj.value.age++}
      </script>

总结

1、只要明确是复杂类型也知道准确字段就用reactive(),其他用ref()

2、都用ref()

setup语法糖

setup语法糖:简化方式

将export default{}省略,setup(){}省略,return{}省略

<script setup>// setup语法糖:简化方式 
const count = 99 
const money = 90 
</script>

computed函数

计算属性语法:

computed(()=>{return 值}) return的就是结果

<script setup>
const list=ref([100,98,77,64,43,23,88,95])
//计算属性语法
const goodList = computed(()=>{
 return list.value.filter(item=>item>90)})
</script>

watch函数

5种情况:

使用 watch 监听一个响应式数据

使用 watch 监听多个响应式数据

使用 watch 监听响应式对象数据中的一个属性(简单)

使用 watch 监听 响应式对象数据中的一个属性(复杂),配置深度监听

使用 watch 监听 ,配置默认执行

1、监听一个数据   
watch(监视数据,回调函数)
    watch(count,(newV,oldV)=>{
        console.log('你变了',newV,oldV)})
   
2、监听多个数据
watch([数据1,数据2...],回调函数)  同时监视
    watch([count,fn],()=>{
        console.log('你变了',count,fn)})
    
3、监听对象中一个属性(简单)
watch(()=>数据, 改变后回调函数)
    watch(()=>user.name,()=>{
        console.log('改名字')})
 
4、监听响应式对象数据中的一个属性(复杂)
watch(()=>数据, 改变后回调函数, {deep: true})
    watch(()=>user.info,()=>{
        console.log('info变了')
    },{deep:true})
​
5、监听并立即执行
watch(..,..,{deep: true,immediate:true})
    watch(()=>user.info,()=>{
        console.log('info变了')
    },{deep:true,immediate:true})

vue3生命周期函数

选项式API下的生命周期函数使用组合式API下的生命周期函数使用
beforeCreate不需要(直接写到setup函数中)
created不需要(直接写到setup函数中)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyedonBeforeUnmount
destroyedonUnmounted
activatedonActivated
deactivatedonDeactivated
  • 常用的发请求,直接写在setup中

  • 常用的 onMounted 组件渲染完毕:发请求,操作dom,初始化图表... onMounted(()=>{})

  • 每个钩子都可以多次调用,目的为了拆分逻辑,让不同的代码用单独的钩子,避免相同逻辑的代码拆分。

其他方法

ref操作

ref 获取dom对象

  1. 创建ref对象

  2. 将inpRef对象与dom关联 inpRef.value=dom

  3. 在合适的时机获取dom

<script setup>
const inpRef = ref(null)//inpRef.value
onMounted(()=>{
    console.log(inpRef.value)
    inpRef.value.value=123
})</script>
​
<input type="text" ref="inpRef">

ref操作组件

  1. 导入组件(不用注册),使用组件, 创建ref对象 ,关联ref

  2. 组件向外暴露数据 defineExpose({xx,xxx})

  3. 获取组件上的属性/方法

    <script setup>
    import Jack from './components/jack.vue'
    // 引入组件,组件不需要注册
    import { ref } from 'vue';
    const jackRef = ref(null)
    ​
    ​
    const fn = ()=>{
        console.log(jackRef.value.car)
        jackRef.value.fn()}
    </script>
    ​
     <Jack ref="jackRef"></Jack>
     
     jack.vue中
    const money = ref(100)...
     defineExpose({
        money,car,fn
    })//向外暴露数据 函数的一个方法
    // 只有向外暴露了,这个数据才能被外界访问

父子通信

父传子

通过defineProps({...})接收

子组件 --- 通过defineProps({...})接收,正常使用
// 如果接收到的props只在模板中使用,不用通过变量接收返回值
defineProps({
    // 接收props
    money:{
        type:Number,
        default:100 },
    car:String
 })
 父组件 --- 导入child,正常写数据,传数据给子组件
 <child :money="money" :car="car"></child>

子传父

通过 defineEmits(['xx','xxx']) 传递

子组件

  • 如果props数据需要在script中使用,必须通过变量接收

  • 想要子传父 必须获取到emit方法

  • 注意:触发的自定义事件名 必须显示指定的defineEmits 数组参数中

子组件 --- defineEmits(['xx','xxx']) 传递
const obj = defineProps({money:Number})
const emit =defineEmits(['changeMoney','xx'])
const pay = ()=>{// 触发一个自定义事件
    emit('changeMoney',obj.money-10)}
    
父组件 --- 通过自定义事件名注册事件
<child @changeMoney="fn"></child>
 const fn = (num)=>{money.value=num}

依赖注入:解决跨组件通信

1.找父组件 通过provide 提供数据 / 函数

语法:provide('属性名',值)

通过provide提供的数据是属于app.vue组件的所有后代组件的!!!

2.后代组件如何使用数据 语法: inject('属性名') //注入

父组件:
const money = ref(100)
provide('money',money)
provide('car','奥迪')
//以下函数是组件通信,后代组件修改父组件变量的
provide('updateMoney',()=>{money.value+=10})
​
子组件
const money = inject('money')
const car = inject('car')
const updateMoney = inject('updateMoney')
​
<div>我是孙组件child2 {{money}} {{car}}</div>
<button @click="updateMoney">加钱+10</button>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值