vue3的知识整理

1. vue3的生命周期

vue3的生命周期一般有2种形式写法,一种是基于vue2options API的写法,一种是vue3特有的Composition API

options API的生命周期
基本同vue2的生命周期基础,只是为了与生命周期beforeCreatecreated对应,将beforeDestroydestroyed更名为beforeUnmountunmounted,使用方法同vue2



初次渲染时

点击修改值的生命周期

点击跳转,组件销毁的生命周期

composition API的生命周期
composition API的生命周期钩子函数是写在setup函数中的,它所有生命周期是在vue2生命周期名字前加on,且必须先导入才可使用

在这种写法中,是没有onBeforeCreateonCreated周期的,setup等同于(或者说是介于)这两个生命周期



初次渲染

点击修改data中的值

页面跳转,组件销毁

2. 如何理解 Composition API 和 options API ?

Composition API带来了什么:

  • 更好的代码组织
  • 更好的逻辑复用,避免mixins混入时带来的命名冲突和维护困难问题
  • 更好的类型推导

options API
使用options API,当代码很多时,即当data, watch, methods等有很多内容时,业务逻辑比较复杂,我们需要修改一部分时,可能要分别到data/methods/模板中对应修改,可能需要我们在页面反复横跳来修改,逻辑块会比较散乱。

Composition API
Composition API则会将业务相关的部分整合到一起,作为一个模块,当要修改,统一到一处修改,代码看起来会更有条理

image.png

它包含的内容包括:

  • reactive
  • ref相关(ref, toRef, toRefs,后面会具体介绍)
  • readonly
  • watch和watchEffect
  • setup
  • 生命周期钩子函数

两者的选择:

  • 不建议共用,否则容易引起混乱(思路、组织方式、写法都不太一样)
  • 小型项目,业务逻辑简单的,建议用options API,对新手也比较友好
  • 中大型项目、逻辑复杂,建议使用Composition API

Composition API它属于高阶技巧,不是基础必会的,有一定的学习成本,是为了解决复杂业务逻辑而设计,就像hooksReact中的地位一样

3. 如何理解ref,toRef,toRefs

ref

  • 通过ref方式创建响应式的值类型,并赋予初始值,并通过.value的方式获取值或修改值
  • 通过reactive方式创建响应式的引用类型,并赋予初始值,修改和获取方式同普通对象一样
  • 除了以上两种用法,还可以使用ref来声明dom元素,也就是类似vue2中的用法



image.png

PS: 小建议,ref定义的数据可以加个Ref后缀,这样就能区分refreactive定义的变量了

toRef

看定义有点绕

  • 针对一个响应式对象(reactive封装)的属性prop
  • 通过toRef创建一个ref对象,这个ref对象和reactive对象的某属性两者保持引用关系

注意,如果toRef是通过普通对象来生成ref对象,那么普通对象和ref对象都将不是响应式的




初始时

1s后,state.age改了,ageRef也跟着改了

2s后,ageRef改了,state.age也跟着改了

toRefs

  • 将响应式对象(reactive)的所有属性prop,转换为对应prop名字的ref对象
  • 两者保持引用关系



应用:
当使用composition API时,抽象出一个模块,使用toRefs返回响应式对象,这样,在接收的时候,我们就可以使用解构的方式获取到对象里面的内容,这也是比较符合我们常用的方式

// 封装一个模块,使用toRefs导出对象
export function useFeature() {
  const state = reactive({
    x: 1,
    y: 2
  })
  // ...
  return toRefs(state)
}
// 导入时,可以使用解构方式
import { useFeature } from './features'
  
export default {
  setup() {
    // 可以在不丢失响应式的情况下解构
    const  { x, y } = useFeature()
    return { x, y }
  }
}

ref, toRef, toRefs 使用小结:

  • reactive做对象的响应式,用ref做值类型的响应式
  • setup中返回toRefs(state),或toRef(state, prop)
  • ref变量命名建议用xxxRef
  • 合成函数返回响应式对象时,使用toRefs

为什么需要 ref ?

  • 如果没有ref,普通的值类型定义,没法做响应式
  • computed,setup,合成函数,都有可能返回值类型,要保证其返回是响应式的
  • 如果vue不定义ref,用户可能会自己造ref,反而更加混乱

为什么需要.value ?

  • ref是一个对象(保证响应式),value用来存储值
  • 通过.value属性的getset实现响应式
  • 用于模板、reactive时,不需要.value,这是因为vue编译会自动识别,其他情况则需要使用

为什么需要 toRef 和 toRefs ?

  • 目的:为了不丢失响应式的情况下,把对象数据分散、扩散(或者说是解构)
  • 前提:针对的是响应式对象(reactive封装的对象)
  • 本质:不创建响应式(创建是ref和reactive的事),而是延续响应式

4. watch和watchEffect的区别

  1. watchwatchEffect都可以监听data的变化
  2. watch需要指定监听的属性,默认初始时不会触发,如果初始要触发,需要配置immediate: true
  3. watchEffect是不需要指定监听的属性,而是自动监听其用到的属性,它初始化时,一定会执行一次,这是为了收集要监听的属性



watch
  // watchEffect监听
    watchEffect(() => {
      console.log('watchEffect');
      console.log(numberRef.value);
      console.log(state.age);
    })
watchEffect

5. 在setup中怎么获取组件实例

  • setup和其它compostion API中没有this
  • 如果一定要获取,要使用getCurrentInstance获取,并且在挂载后才可获取数据
  • 如果是options API,则可以像vue2一样正常使用this



6. vue3升级了哪些重要的功能

参考官网升迁指南

createApp

// vue2
const app = new Vue({/*options*/})
Vue.use(/*...*/)
Vue.mixin(/*...*/)
Vue.component(/*...*/)
Vue.directive(/*...*/)

// vue3
const app = Vue.createApp({/*options*/})
app.use(/*...*/)
app.mixin(/*...*/)
app.component(/*...*/)
app.directive(/*...*/)

emits属性

  1. setup中可以使用emit向父组件发出事件
  2. 在子组件中,需要emits声明向父组件发出的事件集合




多事件处理


fragment

vue2只允许template中只有一个元素,如果多个元素,必须用一个元素包裹
vue3则允许template中可以直接有多个元素,这样就可以减少dom层级

移除.sync

vue2中的.sync

vue2中使用.sync是对以下语句的语法糖,父组件通过v-bind:xxx.sync='xxx'来向子组件说明这个属性是双向绑定的,子组件中通过$emit('update:xxx', newVal)来更新这个值





vue3中,废除了.sync的写法,换成一种更具有语义的写法v-model:xxx,在父组件中使用v-model:xxx方式说明这个属性是双向绑定的,子组件中通过$emit('update:xxx', newVal)来更新这个值






 

异步组件的导入方式不一样

vue2child: () => import('child.vue')
vue3:需要defineAsyncComponent导入,child: defineAsyncComponent(() => import('child.vue'))

teleport

teleport将我们的模板移动到DOMVue app之外的其他位置,比如可以使用teleport标签将组件在body


image.png

你可能感兴趣的:(vue3的知识整理)