响应式系统工具集的使用

Vue3 提供了一组响应式工具,其中经常使用的有 unref()、toRef()、isRef()、isProxy()、isReactive() 和 isReadonly()。

unref()

作用:如果 unref() 函数的参数是 ref 数据,则返回 value 值,如果不是 ref 数据,则返回参数本身。

(1)定义ref变量并赋值。 (2)直接打印ref变量,输出的是对象。 (3)使用unref()函数直接获取对象的value值。

<script>
import { ref, unref } from "vue";

export default {
  setup() {
    // 1.定义 ref 变量
    var num = ref(10);

    // 2.如果直接打印 num,打印出来的是一个 RefImpl 对象
    console.log(num); // 输出:RefImpl {_rawValue: 10, _value: 10, __v_isRef: true, …}

    // 3.使用 unref 打印出来的是 num 对象的 value 值
    console.log(unref(num)); // 输出:10

    // 补充说明:
    // 在模板中使用 ref 变量时,Vue 会自动解包,
    // 所以可以直接使用 {{ num }} 而不需要 {{ num.value }}。
    // 但是在 setup 函数中,如果需要访问 ref 变量的值,
    // 就需要使用 .value 属性,或者使用 unref() 函数。

    return {}; // setup 函数必须返回一个对象
  },
};
</script>

toRef()

作用:把reactive对象中的一个属性创建成ref数据。

(1)创建reactive代理对象。 (2)使用toRef()函数把reactive中的某一个属性转成ref数据。 (3)打印ref数据。

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

export default {
  setup() {
    var data = reactive({ num: 10 });

    // toRef 有两个参数,第一个参数是 reactive 创建的对象名
    // 第二个参数是 reactive 对象中的某一个参数
    // numRef 具有响应式和可传递性
    var numRef = toRef(data, "num");

    console.log(numRef.value); // 输出 10

    // 修改 numRef.value 会同时修改 data.num
    numRef.value = 20;
    console.log(data.num); // 输出 20

    // 修改 data.num 会同时更新 numRef.value
    data.num = 30;
    console.log(numRef.value); // 输出 30

    return {
      numRef, // 将 numRef 返回,以便在模板中使用
    };
  },
};
</script>

isRef()

作用:检查一个值是否为ref对象,代码如下。

<script>
import { ref, isRef } from "vue";

export default {
  setup() {
    var num = ref(10);

    // 判断 num 是否为 ref 对象
    console.log(isRef(num)); // true

    console.log(isRef(100)); // false

    // 补充说明:
    // isRef() 函数用于检查一个值是否为 ref 对象。
    // 如果是 ref 对象,则返回 true;否则返回 false。
    // 这在需要根据值的类型来执行不同操作时非常有用。
    // 例如,在处理 props 或 data 时,
    // 可能需要判断某个属性是否为 ref 对象,
    // 然后根据情况来访问它的 .value 属性或直接使用它。

    return {}; // setup 函数必须返回一个对象
  },
};
</script>

isProxy()

作用:检查对象是否为代理对象。当前学习的代理对象有两种,一种是由 reactive() 函数创建的,另一种是由 readonly() 函数创建的。

<script>
import { reactive, isReactive, readonly, isReadonly } from "vue";

export default {
  setup() {
    var data = reactive({ num: 10 });
    var newdata = readonly(data);

    // 判断 newdata 是否为 readonly 创建的只读代理对象
    console.log(isReadonly(newdata)); // true

    console.log(isReadonly(data)); // false

    // 判断 data 是否为 reactive 创建的响应式对象
    console.log(isReactive(data)); // true

    console.log(isReactive(newdata)); // true  readonly 也会被认为是 reactive

     // 补充说明:
    // isReadonly() 函数用于检查一个对象是否为 readonly 创建的只读代理对象。
    // 如果是只读代理对象,则返回 true;否则返回 false。
    // isReactive() 函数用于检查一个对象是否为 reactive 创建的响应式对象。
    // 如果是响应式对象,则返回 true;否则返回 false。
    // 需要注意的是,readonly 对象也会被认为是 reactive 对象。

    return {}; // setup 函数必须返回一个对象
  },
};
</script>

isReactive()

作用:检查对象是否为 reactive 代理对象,代码如下。

<script>
import { reactive, isReactive, readonly, isReadonly, isProxy } from "vue";

export default {
  setup() {
    var data = reactive({ num: 10 });
    var newdata = readonly(data);

    // 判断是否为代理对象
    console.log(isProxy(data)); // true

    console.log(isProxy(newdata)); // true

    // 补充说明:
    // isProxy() 函数用于检查一个对象是否为 reactive 或 readonly 创建的代理对象。
    // 如果是代理对象,则返回 true;否则返回 false。
    // 因为 reactive 和 readonly 都会返回代理对象,
    // 所以 isProxy() 函数对于 reactive 和 readonly 创建的对象都会返回 true。

    return {}; // setup 函数必须返回一个对象
  },
};
</script>

isReadonly()

作用:检查对象是否是 isReadonly 代理对象,代码如下。

<script>
import { reactive, isReactive } from "vue";

export default {
  setup() {
    var data = reactive({ num: 10 });

    // 判断 data 是否为 reactive 创建的代理对象
    console.log(isReactive(data)); // true

    console.log(isReactive(100)); // false

    // 补充说明:
    // isReactive() 函数用于检查一个对象是否为 reactive() 或 shallowReactive() 创建的代理。
    // 如果是 reactive() 或 shallowReactive() 创建的代理,则返回 true;否则返回 false。

    return {}; // setup 函数必须返回一个对象
  },
};
</script>