vue3.0

vue3.0新特性介绍

  1. 数据响应式数据重新实现(ES6的proxy代替ES5的Object.defineProperty)
  2. 源码使用typescript进行重新编写(更好的类型推导)
  3. 虚拟DOM新算法(更快、更小)
  4. 提供了composition api,为了更好的逻辑复用与代码组织
  5. 自定义渲染器(可以根据需求自定义各种各样的渲染器)
    1.App端:https://vue-native.io/docs/
    2.小程序端:http://mpvue.ccom/
    3.游戏开发:http://vugel.planning.nl/#applicatian
  6. Fragment,模板可以有多个根元素

vue2.0和vue3.0响应式原理对比

vue2.0响应式原理

1.vue2.0中使用ES5中的Object.defineProperty方法实现响应式数据

2.缺点

  • 无法监测到对象属性的动态添加和删除
  • 无法监测到数组的下标和length属性的变更

3.解决方案

  • Vue2.0提供Vue.set方法用于动态给对象添加属性
  • Vue2.0提供Vue.delete方法用于动态删除对象的属性
  • 重写vue中数组的方法,用于监测数组的变更

vue3.0响应式原理

1.Vue3.0中使用ES6中的proxy语法实现响应式数据

2.优点

  • 可以监测到代理对象属性的动态添加和删除
  • 可以监测到数组的下标和length属性的变更

3.缺点

  • ES6的proxy语法对于低版本浏览器不支持,IE11
  • Vue3.0会针对于IE11出一个特殊的版本用于支持ie11

创建vue3.0项目

使用vue-cli创建vue3.0项目

  1. 安装vue-cli到最新版本(必须高于4.5.0)
yarn global add @vue/cli

//如果已经安装了vue-cli

yarn global upgrade @vue/cli
  1. 如果创建的是vue2项目,可以直接升级(不推荐)
vue add vue-next
  1. 可以直接创建vue3项目(推荐)
vue create demo
//手动选中3.0版本

使用vite创建vue3.0项目

  1. Vite是一个有原生ESM驱动的Web开发构建工具,在开发环境下基于浏览器原生ES imports开发,在生产环境下基于Rollup打包
  2. Vite目前仅支持vue3.x,不兼容vue2.x项目
  3. Vite基本使用
npm init vite-app <project-name>
cd <project-name>
npm install
npm run dev

Composition API VS Options API

Options API 选项api

  1. Options API的优点是容易学习和使用,代码有明确的书写位置
  2. Options API的缺点就是相似逻辑不容易复用,在大项目中尤为明显
  3. Options API可以通过mixins提取相同的逻辑,但是容易发生命名冲突且来源不清晰

Composition API 组合api

  1. Composition API是根据逻辑功能来组织代码的,一个功能所有的api放到一起
  2. 即便项目很大,功能很多,都能快速的定位到该功能所有的API
  3. Composition API提高了代码的可读性和可维护性

Vue3.0中推荐使用Composition API,也保留了Options API

Composition API的使用

setup

  1. setup函数是一个新的组件选项,作为组件中omposition API的起点
  2. 从生命周期函数的角度来看,setup在beforeCreate钩子函数之前执行
  3. setup中不能使用this,this指向undefined
export default {
  setup(){
    //1.setup需要返回值,setup中的返回值才能在模板中使用
    const car={brand:'宝马',price:100}
    //2.此时car为普通对象
    return {car}
  }
}

reactive

reactive函数接受一个普通对象,返回该对象的响应式代理

import {reactive} from 'vue'
export default {
  setup(){
    //2.reactive函数接受一个普通对象,返回该对象的响应式代理
    const car=reactive({brand:'宝马',price:100})
    //模板中访问的数据需要在setup中返回
    return {car}
  }
}

ref

  1. ref函数接受一个简单类型的值,返回一个可改变的ref对象。返回的对象有唯一的属性value
  2. 在setup函数中,通过ref对象的value属性可以访问到值
  3. 在模板中,ref属性会自动解套,不需要额外的.value
  4. 如果ref接受的是一个对象,会自动调用reactive
import {ref} from 'vue'
export default {
  setup(){
     //1.ref函数接受一个简单类型,返回一个响应式对象
     //2.这个响应式对象只有一个属性value
     //3.在模板中使用ref,会自动调用value
     //eg:<div>我的金钱{{money}}</div>
     let money=ref(100)
     money.value++
     return {money}
 }
}

toRefs

  1. 把一个响应式对象转换成普通对象,该普通对象的每个property都是一个ref
  2. Reactive的响应式功能是赋予给对象的,但是如果给对象解构或者展开的时候,会让数据丢失响应式的功能
  3. 使用toRefs可以保证该对象展开的每一个属性都是响应式的
import {reactive,ref,toRefs} from 'vue'
export default {
  setup(){
     const state=reactive({
     money:100,
     car:{
       brand:'宝马',
       price:10000
     },
     name:'zs'
     })
     return {
     ...toRefs(state)
     }
 }
}

readonly

  1. 传入一个对象(响应式或普通)或ref,返回一个原始对象的只读代理
  2. 一个只读的代理是“深层的”,对象内部任何嵌套的属性也都是只读的
  3. 可以防止对象被修改

computed

  1. computed函数用于创建一个计算属性
  2. 如果传入的是一个getter函数,会返回一个不允许修改的计算属性
  3. 如果传入的是一个带有getter和setter函数的对象,会返回一个允许修改的计算属性
<div>今年的年龄:<input type='text' v-model='age'/></div>
<div>明年的年龄:<input type='text' v-model='nextage'/>
<div>后年的年龄:<input type='text' v-model='nextage2'/></div>
import {ref,computed} from 'vue'
export default {
   setup(){
     const age=ref(18)
     //computed是一个函数
     //1.传入一个函数的getter返回一个不允许修改的计算属性
     const nextage=computed(()=>{
        return parseInt(age.value)+1
     })
     //2.传入一个对象,包括get和set,可以创建一个可以修改的计算属性
     const nextage2=computed({
       get(){
         return parseInt(age.value)+2
       },
       set(value){
         age.value=value-2
       }
     })
     return {
     age,nextage,nextage2
     }
   }
}

watch

  1. watch函数接受3个参数
    1.参数1:监视的数据源,可以是ref或getter函数
    2.参数2:回调函数 (value,oldValue)=>{}
    3.参数3:额外选项,immediate和deep

  2. watch可以监听一个ref或者一个带返回值得getter函数

  3. watch可以监听单个数据源,也可以监听多个数据源

  4. watch函数会有返回值,用于停止监听

import {ref,toRefs,watch,reactive} from 'vue'
export default {
  setup(){
    const state=reactive({
      money:100,
      car:{
        brand:'宝马',
        price:1000
      }
    })
   
    //1.监听外面的money
    //const money=ref(100)
    //watch(money,(value,oldValue)=>{console.log(value,oldValue)})
    
    //2.监听state里面的money
    //watch(()=>state.money,(value,oldValue)=>{console.log(value,oldValue)})
    
    //3.监听state里面的car对象,deep
    watch(()=>state.car,(value,oldValue)=>{console.log(value,oldValue)},{deep:true})
    
    //4.监听多个属性
    watch([()=>state.money,()=>state.car],([money,car])=>{console.log(money,car)})
    return {
    ...toRefs(state),
    //1.money
    }
  }
}

生命周期钩子函数

  1. vue3提供的生命周期钩子函数注册函数只能在setup()期间同步使用
  2. vue3生命周期钩子函数与vue2对比

beforeCreate =>使用setup()
created =>使用setup()
beforeMount =>onBeforeMount
mounted => onMounted
beforeUpdate => onBeforeUpdate
updated =>onUpdated
beforeDestroy =>onBeforeUnmount
destroyed => onUnmounted
errorCaptured =>onErrorCapured

依赖注入

  1. vue3中提供了provide和inject提供依赖注入,用于实现组件之间的通讯。类似于vue2中的provide和inject
  2. vue3提供的provide和inject可以用于跨多级组件进行通讯
<!--父组件-->
<div>
  <h1>{{fatherMoney}}</h1>
  <!--还是可以用props-->
  <Child :money='money'></Child>
</div>
//父组件
import {ref,provide} from 'vue'
import Child from './child.vue'
export default {
  components:{
    Child 
  },
  setup(){
    const money=ref(100)
    const changeMoney=(val)=>{money.value=val}
    // 组件提供了money属性
    provide('money',money)
    provide('changeMoney',changeMoney)
    return {
      money
    }
  }
}
<!--子组件-->
<div>我是child:{{money}}</div>
<button @click='fn'>修改</button>
//子组件 用inject接收
import {inject} from 'vue'
export default {
  //子组件接收props,setup有props参数
  setup(props){
    const money=inject('money')
    const changeMoney=inject('changeMoney')
    const fn=()=>{
      changeMoney(20000)
    }
    return {
      money,
      fn
    }
  },
  //props必须写
  props:{
    money:Number
  }
}
//子组件 用props接收
export default {
  //子组件接收props,setup有props参数
  setup(props){
    console.log(props)
    return {
    }
  },
  //props必须写
  props:{
    money:Number
  }
}

模板refs

为了获得对模板内元素或组件实例的引用,我们可以向往常一样在setup()中声明一个ref并返回它

<template>
   <div ref='root'></div>
</template>
import {ref,onMounted} from 'vue'
export default {
  setup(){
     //创建一个空的ref
     const root=ref(null)
     onMounted(()=>{
     //在渲染完成后,这个div DOM会被赋值给root ref对象
     console.log(root.value)
     })
     return {
       root
     }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值