前端基础之《Vue(28)—Vue3 ref相关API》

ref相关API介绍

1、ref()

(1)ref介绍

ref用于定义基本数据类型,比如:string / boolean / number等(因为这几个没办法代理)。

ref的背后是使用reactive来实现的响应式。

使用.value来访问变量的值。

(2)打印一个ref对象

RefImpl引用实现,就是个响应式变量

因为Vue3给基本数据类型外面包了一层(做了Proxy()代理,加get、set钩子),你传了1000进来,得到的是对象

num = {

value: 1000

}

(3)ref的变量在视图模板中都不要加.value,因为指令会自动加

2、isRef()

(1)作用:判断一个变量是否为一个ref对象

(2)语法:const bol = isRef(x)

3、unref()

(1)作用:用于返回一个值,如果访问的是ref变量,就返回其.value值。如果不是ref变量就直接返回

这是 val = isRef(val) ? val.value : val 计算的一个语法糖

(2)语法:const x = unref(y)

4、customRef()

(1)作用:自定义ref对象,把ref对象改写成get/set,进一步可以为它们添加track/trigger

(2)、customRef()关联的生命周期钩子

onRenderTracked()

onRenderTriggered()

这两个是用于调试的,只能在开发环境使用,生产环境不起作用。用来对变量进行劫持。

javascript 复制代码
    const name = customRef((track, trigger)=>{ // track和trigger是两个函数
        let value = ''
        return {
            get () {
                track() // 如果有人访问name,就执行track()
                return value
            },
            set (val) {
                value = val
                trigger() // 如果有人修改name,就执行trigger()
            }
        }
    })
    // 仅供在开发环境下,用于ref变量的调试
    onRenderTracked((ev)=>{console.log('name被跟踪了', ev)})
    onRenderTriggered((ev)=>{console.log('name被修改了', ev)})

5、toRef()

(1)作用:把一个reactive对象中的某个属性变成ref变量

(2)语法:const x = toRef(reactive(obj), 'key')

javascript 复制代码
<script setup>
    import { reactive, toRef } from 'vue'
    const user = reactive({name: '张三', age: 10})
    console.log('---user', user)

    const name = toRef(user, 'name')
    console.log('---name', name.value) // name是ref变量

</script>

6、toRefs()

(1)作用:把一个reactive响应式对象变成ref变量

(2)语法:const obj1 = toRefs(reactive(obj))

(3)应用:在子组件中接收父组件传递过来的props时,使用toRefs把它变成响应式的

例如:const {a, b} = toRefs(props)

javascript 复制代码
<script setup>
    import { isRef, reactive, toRef, toRefs } from 'vue'
    const user = reactive({name: '张三', age: 10})
    console.log('---user', user)

    // const name = toRef(user, 'name')
    // console.log('---name', name.value) // name是ref变量

    const {name, age} = toRefs(user)
    console.log('---1', isRef(name))
    console.log('---2', isRef(age))

</script>

7、shallowRef()

(1)作用:对复杂层级的对象,只将其第一层变成ref响应(性能优化)

用shallowRef包裹的对象,只有第一层变化才更新,更改后面的层不更新,第一层是.value

(2)语法:const x = shallowRef({a:{b:{c:1}}, d:2}),如此a、b、c、d变化都不会自动更新,需要借助triggerRef来强制更新

(3)shallowRef只劫持第一层

javascript 复制代码
<script setup>
    import { isRef, reactive, toRef, toRefs, shallowRef, ref } from 'vue'

    // ref包裹对象
    const info1 = ref({a: {b: {c: 3}}})
    console.log('---3', info1.value.a.b.c) // 要访问c,需要写的很长

    const info2 = shallowRef({a: {b: {c: 3}}})
    console.log('---4', info2) // 只有info2.value = xxx 才会更新

</script>

8、triggerRef()

(1)作用:强制更新一个shallowRef对象的渲染

(2)语法:triggerRef(shallowRef对象),只能接收一个shallowRef的变量,强制更新这个变量

9、reactive()

(1)作用:定义响应式变量,一般用于定义引用数据类型,如果是基本数据类型,建议使用ref来定义

(2)语法:const info = reactive([])

(3)如果定义对象类型、数组类型声明式变量,用reactive定义