一. toRefs/toRef

1. 背景

 我们都知道reactive处理的对象是响应式的,但是使用ES6的解构语法对reactive对象进行处理,那么之后无论是修改解构后的变量name、age,还是修改reactive返回的原始对象info1数据都不再是响应式的。
第十一节:Vue3的Composition Api(toRefs/toRef、customerRef、computed、watchEffect、watch)

2. 使用 

(1). toRefs

  toRefs的函数,可以将reactive返回的对象中的属性都转成ref;如下代码,再次进行结构出来的 name 和 age 本身都是 ref的

(2). toRef 

   只希望转换一个reactive对象中的属性为ref, 那么可以使用toRef的方法。

代码分享: 

<template>
    <div>
        <h3>{{info1.name}}--{{info1.age}}</h3>
        <h3>{{name}}--{{age}}</h3>

        <h3>{{name2}}--{{age2}}</h3>

        <h3>{{age3}}</h3>
        <h3><button @click="EditAge">修改age</button></h3>
    </div>
</template>

<script>
    import { reactive, toRefs, toRef } from 'vue';

    export default {
        setup(props, context) {
            // 1. reactive响应式对象
            const info1 = reactive({
                name: 'ypf',
                age: 18
            });
            const info2 = reactive({
                name2: 'ypf',
                age2: 18
            });
            const info3 = reactive({
                name3: 'ypf',
                age3: 18
            });

            // 2. 解构后则不再支持响应式
            let { name, age } = info1;

            //3. 借助toRefs和toRef建立响应关系 (ref相关对象要通过.value拿值)
            let { name2, age2 } = toRefs(info2);
            let age3 = toRef(info3, "age3");

            var EditAge = () => {
                info1.age++;
                age++;
                age2.value++;
                age3.value++;
            }

            return {
                info1,
                name,
                age,
                name2,
                age2,
                age3,
                EditAge
            }
        }
    }
</script>

 

二. customerRef

1. 说明

 创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制:

(1). 它需要一个工厂函数,该函数接受 track 和 trigger 函数作为参数;

(2). 并且应该返回一个带有 get 和 set 的对象;

2. 案例 

 实现:双向绑定的属性进行debounce(节流)的操作。

useDebounceRef.js

import { customRef } from 'vue';

// 自定义ref
export default function(value, delay = 300) {
  let timer = null;
  return customRef((track, trigger) => {
    return {
      get() {
        track();
        return value;
      },
      set(newValue) {
        clearTimeout(timer);
        timer = setTimeout(() => {
          value = newValue;
          trigger();
        }, delay);
      }
    }
  })
}

调用

<template>
    <div>
        <input v-model="msg" />
        <h2>{{msg}}</h2>
    </div>
</template>

<script>
    import debounceRef from './hooks/useDebounceRef.js';

    export default {
        setup() {
            const msg = debounceRef('hello msg');
            return {
                msg
            }
        }
    }
</script>
View Code

相关文章: