VUE 3.X——递归监听与非递归监听

  1. 递归监听

    Vue3.X是通过ES6的 Proxy 实现数据的双向绑定(即只有包装成 Proxy 的数据才会主动更新视图),即它会把 refreactive 的所有子节点包装成 Proxy 并进行视图更新,因此,如果数据量过大,递归监听会非常消耗性能,例:

    0BO0nf.png

    <template>
       <ul>
        <li>{{ test.a }}</li>
        <li>{{ test.gf.b }}</li>
        <li>{{ test.gf.f.c }}</li>
        <li>{{ test.gf.f.s.d }}</li>
      </ul>
      <button @click="changeToNum">测试递归监听</button>
    </template>
    
    setup() {
      // let test = reactive({
      let test = ref({
          a: 'a',
          gf: {
              b: 'b',
              f: {
                  c: 'c',
                  s: {
                      d: 'd'
                  }
              }
          }
      });
      function changeToNum() {
        // test.a = '1';
        // test.gf.b = '2';
        // test.gf.f.c = '3';
        // test.gf.f.s.d = '4';
    
        // console.log(test);
        // console.log(test.gf);
        // console.log(test.gf.f); 
        // console.log(test.gf.f.s);
    
        test.value.a = '1';
        test.value.gf.b = '2';
        test.value.gf.f.c = '3';
        test.value.gf.f.s.d = '4';
    
        console.log(test); 
        console.log(test.value); 
        console.log(test.value.gf);
        console.log(test.value.gf.f);
        console.log(test.value.gf.f.s);
      }
      return {test, changeToNum};
    }
    
  2. 非递归监听

    非递归监听只能监听第一层的数据变化,主要用到的方法有 shallowReactive shallowReftriggerRef

    • shallowReactive 会把 reactive 类型的数据的第一层包装成 Proxy ,因此如果更新了数据的第一层,视图会主动更新,例:

      0Dkpan.png

      import {shallowReactive} from 'vue'; 
      export default {
          name: 'App2',
          setup() {
              let state = shallowReactive({
                  a: 'a',
                  gf: {
                    b: 'b',
                    f: {
                      c: 'c',
                      s: {
                        d: 'd'
                      }
                    }
                  }
              });
             	function changeToNum() {
                  state.a = '1'; //如果注释这一句,视图将不会主动更新
                  state.gf.b = '2';
                  ...
                  console.log(state);
                  console.log(state.gf);
                  ...
              }
              return {state, changeToNum};
          }
      }
      
    • shallowRef 会把 .value 包装成 Proxy (类比 ref(10) 的实质是 reactive({ value: 10}) ),所以如果想更新视图,则要更新 value ,例:

      0DEu36.png

      import {shallowRef} from 'vue'; 
      export default {
          name: 'App2',
          setup() {
              let state = shallowRef({
                  a: 'a',
                  gf: {
                    b: 'b',
                    f: {
                      c: 'c',
                      s: {
                        d: 'd'
                      }
                    }
                  }
              });
              function changeToNum() {
                  state.value = {
                      a: '1',
                      gf: {
                        b: 'b',
                        f: {
                          c: 'c',
                          s: {
                            d: 'd'
                          }
                        }
                      }
                  };
                  // state.value.a = '1' // 这样写视图不会更新
                  state.value.gf.b = '2';
                  ...
                  console.log(state);
                  console.log(state.value);
                  ...
              }
              return {state, changeToNum};
          }
      }
      
    • triggerRef 是Vue 3.X提供的单独更新数据类型为 ref 的某一项数据的方法,要注意的是,Vue3.X只提供了 triggerRef ,没有提供 triggerReactive ,所以 reactive类型数据无法主动更新页面,例:

      0DVNdJ.png

      import {ref,triggerRef} from 'vue'; 
      export default {
          name: 'App2',
          setup() {
              let state = ref({
                  a: 'a',
                  gf: {
                    b: 'b',
                    f: {
                      c: 'c',
                      s: {
                        d: 'd'
                      }
                    }
                  }
              });
              function changeToNum() {
                  state.value.gf.f.s.d = '4';
                  triggerRef(state);
              }
              return {state, changeToNum};
          }
      }
      
  3. 应用场景

    • 一般情况下用 refreactive 进行递归监听即可
    • 只有当数据量特别大的时候才采用非递归监听

目录:VUE3.X笔记——目录
上一篇:VUE3.X——Composition API
下一篇:VUE3.X——响应数据原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值