Vue3-Composition API

89 阅读5分钟

一、认识Composition API

1. Options API弊端

  • 当我们实现某一个功能时,这个功能对应的代码逻辑会被拆分到各个属性中
  • 当我们组件变得更大、更复杂时,逻辑关注点的列表就会增长,那么同一个功能的逻辑就会被拆分的很分散

2. 认识Composition API

  • 可以将同一个逻辑关注点相同的代码收集在一起
  • setup可以代替之前编写的大部分其他选项
    vue单项数据流规范:父组件将数据传递给子组件后,子组件拿到数据之后,只能用,不能修改;子组件可以将事件传递给父组件,父组件对该事件进行监听,改变父组件中的数据。

二、setup的使用

1. setup函数的基本使用

  • setup函数的参数
    • props
      • 父组件传递过来的属性会被放到props对象中
    • context
      • attrs:所有的非prop的attribute
      • slots:父组件传递过来的插槽
      • emit:当组件内部需要发出事件时会用到emit
  • setup函数的返回值
    • setup的返回值可以在模板template中被使用

2. setup中数据的响应式

  • Ref API
    • ref的使用
      • ref会返回一个可变的响应式对象,该对象作为一个响应式的引用维护着它内部的值
      • 它内部的值是在ref的value属性中被维护的
      • 在模板中引入ref的值,Vue会自动帮助我们进行解包,所以在模板中不需要通过ref.value的方式来使用
      • 但是在setup函数内部,它依然是一个ref引用,所以对其进行操作时,我们依然需要使用ref.value的方式
    • ref的API
      • unref:获取ref引用中的value
      • isRef:判断值是否是一个ref
      • shallowRef:创建一个浅层的ref对象
      • triggerRef:手动触发和shallowRef相关联的副作用
  • Reactive API
    • 如果想为在setup中定义的数据提供响应式的特性,那么我们可以使用reactive函数
    const info = reactive({
        name: "Messi",
        age: 35
    })
    
    • 为什么会变成响应式
      • 因为当我们使用reactive函数处理我们的数据之后,数据再次被使用时就会进行依赖收集
      • 当数据发生改变时,所有收集到的依赖都是进行对应的响应式操作
      • 事实上,我们编写的data选项,也是内部交给了reactive函数将其编成响应式对象的
    • reactive判断的API
      • isProxy:检查对象是否由reactive或readonly创建的proxy
      • isReactive:检查对象是否由reactive创建的响应式代理;如果该代理是readonly建的,但是包裹了由reactive创建的另一个代理,它也会返回true
      • isReadonly:检查好对象是否由readonly创建的只读代理
      • toRaw:创建reactive或readonly代理的原始对象
      • shalloReactive:创建一个响应式代理,它跟踪其自身property的响应性,但不执行嵌套对象的深层响应式转换
      • shallowReadonly:创建一个proxy,使其自身的property为只读,但不执行嵌套对象的深度只读转换
    • toRefs
      • 对reactive返回的对象进行解构获取值,解构出来的变量不再是响应式的
      • toRefs可以将reactive返回的对象中的属性都转成ref
      const info = reactive({
          name: "Messi",
          age: 35
      })
      const { name, age } = toRefs(info)
      
    • toRef
      • 只希望转换一个reactive对象中的属性
      cons name = toRef(info, "name")
      
  • Reactive和Ref的区别
    • 传入的类型
      • reactive要求必须传入一个对象或者数组类型
      • ref可以传入基本数据类型,也可以传入复杂数据类型
    • 应用场景
      • reactive应用于本地的数据;多个数据之间是有关系的
      • 其他的场景基本都用ref
  • readonly
    • 认识readonly
      • readonly会返回原始对象的只读代理
    • readonly的入参
      • 普通对象
      • reactive返回的对象
      • ref的对象
    • readonly的使用
      • readonly返回的对象是不允许修改的
      • 经过readonly处理的原来的对象是允许被修改的
      • 其本质就是readonly的对象的setter方法被劫持了 setup中禁用this

三、computed函数的使用

1. 使用方式一

  • 接受一个getter函数,并为getter函数返回的值,返回一个不变的ref对象
const fullName = computed(() => {
    return firstName.value + " " + lastName.value
})

2. 使用方式二

  • 接收一个具有get和set的对象,返回一个可变的ref对象
const fullName = computed({
    get: () => {
        return firstName.value + " " + lastName.value
    },
    set: newValue => {
        const names = newValue.split(" ")
        firstName.value = names[0]
        lastName.value = names[1]
    }
})

四、组件的生命周期函数

59_生命周期函数.jpg 因为setup是围绕beforeCreate和created生命周期钩子运行的,所以不需要显示的定义他们

五、Provide/Inject使用

1. Provide函数

  • 可以通过Provide来定义每个Property
  • provide可以传入两个参数
    • name:提供属性名称
    • value:提供属性值
    let info = {
        name: "why",
        age: 18
    }
    provide("info", info)
    

2. Inject函数

  • 在后代组件中可以通过Inject来注入需要的属性和对应的值
  • inject可以传入两个参数
    • 要inject的property的name
    • 默认值
    const info = inject("info")
    

六、watch/watchEeffect

1. watch

  • 需要手动执行侦听的数据源
const info = reactive({
    name: "why",
    age: 18,
    friend: {
        name: "kobe"
    }
})
watch(info, (newValue, oldValue) => {
    console.log(newValue, oldValue)
}, {
    immediate: true,
    deep: true
})

2. watchEffect

  • 用于自动收集响应式数据的依赖
const age = ref(18)
const stopWatch = watchEffect(() => {
    console.log(age.value)
})
if (age.value > 20) {
    stopWatch()
}