vue3.0 的改变(3) - 07

105 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

image.png

前面讲过,vue3与vue2最大的改进就是 Composition API , 除了前面介绍的一些Composition API之外,还有很多其他的 Composition API,这一节我们就来看一看

  • provide 与 inject
  • shallowReactive 与 shallowRef
  • readonly 与 shallowReadonly
  • toRaw 与 markRaw
  • customRef

1. provide 与 inject

image.png

vue2时祖与后代组件间,只能使用 bus和vuex来实现通信了,如果一层一层往下,那这就太麻烦了。vue3新增了 provide inject 来实现祖与后代组件间的通信,非常的方便操作

  • 父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据

  • 示例

    • 祖先
    setup(){
        let car = reactive({name:'奔驰',price:'40万'})
        provide('car',car)
    }
    
    • 子孙
     setup(props,context){
       const car = inject('car')
       return {car}
     }
    

这样是不是太方便了,简化了我们的操作

2. shallowReactive 与 shallowRef

在上一节学习reactive和ref的时候讲过他们是为递归监听,本质是Proxy只能监听到当前对象下属性的变化,当属性为引用数据类型时,属性的属性他是监听不到的,所以需要递归监听

那当在项目中数据过于复杂并且我们没有这种递归监听的需求时,这样的操作是很消耗性能的,所以vue3提供了非递归监听的API:shallowReactive和shallowRef,只监听第一层数据的变化

  • 作用场景

    • 如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive
    • 如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===> shallowRef
  • shallowReactive:只处理对象最外层属性的响应式(浅响应式)

  • shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理

3. readonly 与 shallowReadonly

  • 作用场景: 当你希望数据被不能被修改时,可以使用他们
  • readonly: 让一个响应式数据变为只读的(深只读)。
  • shallowReadonly:让一个响应式数据变为只读的(浅只读)。

const定义的变量也是不能改的,那readonly和const有什么区别?

  • const是赋值保护,使⽤const定义的变量,该变量不能重新赋值。如果const赋值的是对象,那么对象⾥⾯的东西是可以改的。原因是const定义的变量不能改说的是,对象对应的那个地址不能改变,而不是里面的值不能修改
  • readonly是属性保护,不能给属性重新赋值,值是不能变的

4. toRaw 与 markRaw

  • toRaw:
    • 作用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
    • 作用:将一个由reactive生成的响应式对象转为普通对象,与代理数据指向相同的引用地址,与源数据无关
import { reactive, toRaw} from 'vue'

setup() {
    let obj = {name:'lsh',age:18};
    let state = reactive(obj)
    let obj2 = toRaw(state)
    console.log(obj === obj2) //true
}
  • markRaw:
    • 作用场景:
      • 有些值不应被设置为响应式的,例如复杂的第三方类库等。
      • 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
    • 作用:标记一个对象,使其永远不会再成为响应式对象,即源对象本身就不需要响应式
import { reactive,markRaw } from 'vue'

let obj = {name:'lsh',age:18};
obj = markRaw(obj)
let state = reactive(obj)

5. customRef

  • 作用:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制
  • 可以使用他来实现一个防抖的效果,下面看下一代码
<template>
    <input type="text" v-model="keyword">
    <h3>{{keyword}}</h3>
</template>

<script>
    import {ref,customRef} from 'vue'
    export default {
            name:'Demo',
            setup(){
                    // let keyword = ref('hello') //使用Vue准备好的内置ref
                    //自定义一个myRef
                    function myRef(value,delay){
                            let timer
                            //通过customRef去实现自定义
                            return customRef((track,trigger)=>{
                                    return{
                                            get(){
                                                    track() //告诉Vue这个value值是需要被“追踪”的
                                                    return value
                                            },
                                            set(newValue){
                                                    clearTimeout(timer)
                                                    timer = setTimeout(()=>{
                                                            value = newValue
                                                            trigger() //告诉Vue去更新界面
                                                    },delay)
                                            }
                                    }
                            })
                    }
                    let keyword = myRef('hello',500) //使用程序员自定义的ref
                    return {
                            keyword
                    }
            }
    }
</script>