vue响应式形成条件

48 阅读2分钟

vue响应式形成条件

  • 函数和数据的直接关联(比如computed里面也是要传函数的)

    1. 被监控的函数
      • 源码体现
        • vue2的watch
        • vue3的effect
      • 直接体现
        • render函数
        • computed回调
        • watchEffect
        • watch
    2. 函数运行期间用到了响应式函数
      • ref(computed本质)
      • reactive(props本质)
    3. 响应式数据变化会导致函数重新运行
    • 总结判断方法
      • 先看是否有被监控函数
      • 再看监控函数方法里面的响应式数据
      • 最后看响应式数据变化是否会导致函数重新执行
  • 实践分析代码

// 父组件
    <template>
    <children :count="count"></children>
    <button @click="changeParentCount"></button>
    </template>
    <script setup lang="ts">
    import children from "./children.vue";
    import { ref } from "vue";

    const count = ref(0);

    const changeParentCount = () => {
    count.value++;
    };
    </script>

    <style lang="scss"></style>

    // 子组件
    <template>
    <div>得到的传入的属性:{{ count }}</div>
    <div>测试的数据:{{ doubleCount }}</div>
    </template>
    <script lang="ts" setup>
    import { ref, defineProps, watchEffect, withDefaults, computed } from "vue";

    // 通识:响应式数据一定一个对象,不管是reactive还是ref,ref访问的是一个.value的对象
    // 前置条件:

    const props = withDefaults(
    defineProps<{
        count: number;
    }>(),
    {
        count: 0,
    },
    );

    // 1
    // const doubleCount = ref(props.count * 2);
    // 分析:这个结果不生效,因为没有和render函数直接关联

    // 2
    // const doubleCount = ref(0);
    // watchEffect(() => {
    //   doubleCount.value = props.count * 2;
    // });
    /*
    分析:这个结果生效
    watchEffect里面有被监控的函数(满足1);
    函数运行期间用到响应式数据Props.count(满足2)
    props.count的变化会导致被监控函数的箭头函数重新运行,
    与render函数关联的doubleCount改变会导致render函数重新运行
    */

    // 3.1
    /* function useDouble(count: any) {
    const doubleCount = ref(count * 2);
    watchEffect(() => {
        doubleCount.value = count * 2;
    });
    return doubleCount;
    }
    const doubleCount = useDouble(props.count); */
    /**
    * 分析:先从函数入手,watchEffect里面使用到了count,
    * 但count是一个非响应式对象(没有完成对响应式对象的读取)
    * 如果要让这个函数可以实现响应式,应该传入props(见3.1)
    */

    // 3.2
    /* function useDouble(data: any) {
    const doubleCount = ref(data.count * 2); //这边的读取只是一次初始化
    watchEffect(() => {
        doubleCount.value = props.count * 2;
    });
    return doubleCount;
    }
    const doubleCount = useDouble(props); //传入对象,vueUse里面也这么做 */

    // 四、
    // const doubleCount = computed(() => props.count * 2);
    /**
    * 分析
    * 有受监控的函数(computed里面受监控的函数)
    * 受监控的函数里面有用到响应式数据props(对象)
    * computed返回的是一个响应式数据,这个响应式数据的变化会导致render函数重新运行
    */

    // 五、
    function useDouble(count: any) {
    const doubleCount = computed(() => count * 2);
    return doubleCount;
    }
    const doubleCount = useDouble(props.count);
    /**
    * computed里面有受监控的函数
    * 受监控的函数里面没有响应式数据(对象形式)
    */
    </script>

    <style scoped></style>