【Vue3】06-to 全家桶

39 阅读1分钟

1. toRef

1.1 作用

作用于响应式对象的属性,对非响应式的视图不起作用

1.2 用法

当作用于非响应式对象时,即使值修改了,但视图并不会更新
<template>
    <div>{{ obj }}</div>
    <div>{{ age }}</div>
    <hr>
    <button @click="change">修改</button>
</template>
    
<script setup lang="ts">
import { toRef } from 'vue'

let obj = {name: "lzy", age: 18}

let age = toRef(obj, "age")  // 接收两个参数,一个是对象,一个是这个对象中的某个 key
console.log(age)  // Ref<18>

const change = () => {
    age.value = 20
    console.log(age)  // Ref<20>
}
  
</script>
当作用于响应式对象时,值修改后,内部触发依赖更新,视图更新
import { reactive } from 'vue'
// 将上面代码中定义 obj 的那句改为下面这句
let obj = reactive({name: "lzy", age: 18})

1.3 原理

ref 对比,toRef 函数内部并没收集依赖和触发依赖更新的语句,因此当 toRef 作用于非响应式对象时,并不会起作用;
而作用于响应式对象后,能起作用的原因是,响应式对象本身的依赖更新触发了,而不是 toRef 起作用

2. toRefs

2.1 作用及用法

传入一个响应式对象,返回一个普通对象,但这个普通对象的每个属性都是响应式的
<template>
    <div>{{ obj }}</div>
    <hr>
    <button @click="change">修改</button>
</template>
    
<script setup lang="ts">
import { reactive, toRef, toRefs } from 'vue'

let obj = reactive({name: 'lzy', age: 18})

let map = toRefs(obj)

const change = () => {
    console.log(obj)  // Reactive<Object>
    
    console.log(map)  // {name: ObjectRefImpl, age: ObjectRefImpl}
    map.name.value = "LZY"  // 视图可以变化,说明是响应式的
}
  
</script>

2.2 源码

const toRefs = <T extends object>(object: T) => {
    let map: any = {}  // 定义一个普通对象
    
    for( let key in object ) {
        map[key] = toRef(object, key)  // 把响应式对象的每个属性都变成响应式的,然后包装在普通对象里
    }

    return map  // 返回这个普通对象
}

2.3 应用

将 reactive 对象属性解构出来使用
<template>
    <div>{{ obj }}</div>
    <hr>
    <button @click="change">修改</button>
</template>
    
<script setup lang="ts">
import { reactive, toRef, toRefs } from 'vue'

let obj = reactive({name: 'lzy', age: 18})
let {name, age} = toRefs(obj)

const change = () => {
    // 值更新,视图变化
    name.value = "LZY"
    age.value = 28
}
  
</script>

3. toRaw

3.1 作用

解除响应式对象的响应式,变成普通对象

3.2 用法

import { reactive, toRaw } from 'vue'

let obj = reactive({name: 'lzy', age: 18})
let rawObj = toRaw(obj)
  
console.log(obj)  //  Reactive<Object>
console.log(rawObj) //  {name: 'lzy', age: 18}