Bootstrap

【Vue3】vue3有哪些方法和工具可以将参数变为响应式或处理响应式数据

在 Vue 3 中,有多种方法和工具可以将参数变为响应式或处理响应式数据。

一、将参数变为响应式的方法

  1. reactive

    • 将一个普通对象转换为响应式对象。
    import { reactive } from 'vue';
    const state = reactive({ count: 0 });
    
  2. readonly

    • 创建一个只读的响应式对象。
    import { readonly } from 'vue';
    const state = readonly({ count: 0 });
    
  3. ref

    • 创建一个包含单个响应式值的对象。
    import { ref } from 'vue';
    const count = ref(0);
    
  4. shallowReactive

    • 创建一个浅层响应式对象,仅对对象的顶层属性进行响应式处理。
    import { shallowReactive } from 'vue';
    const state = shallowReactive({ count: 0 });
    
  5. shallowReadonly

    • 创建一个浅层只读的响应式对象,仅对对象的顶层属性进行只读处理。
    import { shallowReadonly } from 'vue';
    const state = shallowReadonly({ count: 0 });
    
  6. shallowRef

    • 创建一个浅层响应式引用,仅对引用的顶层属性进行响应式处理。
    import { shallowRef } from 'vue';
    const count = shallowRef(0);
    
  7. toReftoRefs

    • toRef:将对象的某个属性转换为一个响应式的 ref 对象。
    • toRefs:将对象的所有属性转换为响应式的 ref 对象。
    import { reactive, toRef, toRefs } from 'vue';
    const state = reactive({ count: 0 });
    const countRef = toRef(state, 'count');
    const stateRefs = toRefs(state);
    
  8. computed

    • 创建一个计算属性,它会根据其依赖项自动更新。
    import { reactive, computed } from 'vue';
    const state = reactive({ count: 0 });
    const doubleCount = computed(() => state.count * 2);
    
  9. watchwatchEffect

    • watch:监听响应式数据的变化,并在变化时执行回调函数。
    • watchEffect:立即执行传入的函数,并在其依赖的响应式数据变化时重新执行。
    import { reactive, watch, watchEffect } from 'vue';
    const state = reactive({ count: 0 });
    
    watch(() => state.count, (newValue, oldValue) => {
      console.log(`count changed from ${oldValue} to ${newValue}`);
    });
    
    watchEffect(() => {
      console.log(`count is now ${state.count}`);
    });
    
  10. customRef

    • 创建一个自定义的 ref,可以自定义其依赖跟踪和触发更新的方式。
    import { customRef } from 'vue';
    
    function useDebouncedRef(value, delay = 200) {
      let timeout;
      return customRef((track, trigger) => {
        return {
          get() {
            track();
            return value;
          },
          set(newValue) {
            clearTimeout(timeout);
            timeout = setTimeout(() => {
              value = newValue;
              trigger();
            }, delay);
          }
        };
      });
    }
    
    const debouncedRef = useDebouncedRef(0);
    
  11. markRaw

    • 将一个对象标记为不可响应的,这样 Vue 就不会将它转换为响应式对象。
    import { reactive, markRaw } from 'vue';
    const rawObject = markRaw({ foo: 'bar' });
    const state = reactive({ raw: rawObject });
    
  12. triggerRef

    • 手动触发由 ref 创建的响应式对象的更新。
    import { ref, triggerRef } from 'vue';
    const myRef = ref({ foo: 'bar' });
    
    // 更新 ref 的值
    myRef.value.foo = 'baz';
    
    // 手动触发更新
    triggerRef(myRef);
    

这些工具和方法提供了灵活多样的方式来管理和处理响应式数据,帮助开发者根据不同的需求实现响应式状态管理。

二、使用 toRef 和 toRefs 的场景

toReftoRefs 在某些特定情况下仍然有其独特的用途和优势。让我解释一下为什么以及何时使用 toReftoRefs

使用 toReftoRefs 的场景

  1. 解构对象时保持响应式
    当你需要解构一个响应式对象时,直接解构会丢失响应性。toRefs 可以帮助你在解构时保持响应性。

    import { reactive, toRefs } from 'vue';
    
    const state = reactive({ count: 0, name: 'Vue' });
    
    // 直接解构会丢失响应性
    // const { count, name } = state;
    
    // 使用 toRefs 保持响应性
    const { count, name } = toRefs(state);
    
  2. 单独引用对象属性
    如果你需要单独引用对象的某个属性并传递给其他组件或函数,可以使用 toRef

    import { reactive, toRef } from 'vue';
    
    const state = reactive({ count: 0 });
    
    // 使用 toRef 创建单独的响应式引用
    const countRef = toRef(state, 'count');
    
    // 现在 countRef 是一个 ref,可以单独传递
    

示例解释

import { reactive, toRef, toRefs } from 'vue';

const state = reactive({ count: 0 });

// 使用 toRef 将 state 对象的 count 属性转换为一个 ref
const countRef = toRef(state, 'count');

// 使用 toRefs 将 state 对象的所有属性转换为 refs
const stateRefs = toRefs(state);

在这个示例中:

  • state 是一个响应式对象,它的所有属性都是响应式的。
  • toRef(state, 'count')state 对象的 count 属性转换为一个 ref,这样你可以单独使用 countRef,并且它仍然是响应式的。
  • toRefs(state)state 对象的所有属性转换为 ref,这样你可以解构 stateRefs,并且每个属性仍然是响应式的。
;