美文网首页
Vue3的ref、reactive、toRef、toRefs

Vue3的ref、reactive、toRef、toRefs

作者: 科科Cole | 来源:发表于2021-11-20 04:46 被阅读0次

    在网上看了很多文章没有一个能把这些效果讲清楚的。我写一下自己试出来的结果。


    先说一下我根据结论得出的理解:

    1. 只有响应式数据能更新界面,ref()、reactive()可以生成响应式数据。
    2. ref一般用于基础数据类型,按值传递;reactive用于复杂数据类型,按引用传递;toRef/toRefs一般用于解构响应式数据,因为如果直接解构响应式数据会使其失去响应性。
    3. toRef返回的值是否具有响应性取决于被解构的对象本身是否具有响应性。响应式数据经过toRef返回的值仍具有响应性,非响应式数据经过toRef返回的值仍没有响应性。toRef返回的是Ref<T>类型,因此在setup()内需要使用.value赋值或调用。
    4. toRefs相当于对对象内每个属性调用toRef,toRefs返回的对象内的属性使用时需要加.value。

    <template>
      <div>
        a:{{a}} b:{{b}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = 1;
        let b = ref(1);
        const onChange = () => {
          a = 2;
          console.log(a);
          console.log(b.value);
        }
        return {
          a,
          b,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:1 b:1

    点击按钮后,输出:

    2
    1
    

    html显示:a:1 b:1

    a ref(a) view
    a \

    <template>
      <div>
        a:{{a}} b:{{b}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = 1;
        let b = ref(1);
        const onChange = () => {
          b.value = 2;
          console.log(a);
          console.log(b.value);
        }
        return {
          a,
          b,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:1 b:1

    点击按钮后,输出:

    1
    2
    

    html显示:a:1 b:2

    a ref(a) view
    a \
    ref(a) \

    <template>
      <div>
        a:{{a}} b:{{b}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2 };
        let b = reactive(a);
        const onChange = () => {
          a.b = 4;
          console.log(a);
          console.log(b);
        }
        return {
          a,
          b,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2} b:{"a":1,"b":2}

    点击按钮后,输出:

    {
        a: 1,
        b: 4
    }
    {
        a: 1,
        b: 4
    }
    

    html显示:a:{"a":1,"b":2} b:{"a":1,"b":2}

    a reactive(a) view
    a \

    <template>
      <div>
        a:{{a}} b:{{b}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2 };
        let b = reactive(a);
        const onChange = () => {
          b.b = 4;
          console.log(a);
          console.log(b);
        }
        return {
          a,
          b,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2} b:{"a":1,"b":2}

    点击按钮后,输出:

    {
        a: 1,
        b: 4
    }
    {
        a: 1,
        b: 4
    }
    

    html显示:a:{"a":1,"b":4} b:{"a":1,"b":4}

    a reactive(a) view
    a \
    reactive(a) \

    <template>
      <div>
        a:{{a}} b:{{b}} c:{{c}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2, c:3 };
        let b = reactive(a);
        let c = toRef(a,'c');
        const onChange = () => {
          a.c = 4;
          console.log(a);
          console.log(b);
          console.log(c.value);
        }
        return {
          a,
          b,
          c,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    点击按钮后,输出:

    {
        a: 1,
        b: 2,
        c: 4
    }
    {
        a: 1,
        b: 2,
        c: 4
    }
    4
    

    html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    a reactive(a) toRef(a,'c') view
    a \

    <template>
      <div>
        a:{{a}} b:{{b}} c:{{c}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2, c:3 };
        let b = reactive(a);
        let c = toRef(a,'c');
        const onChange = () => {
          b.c = 4;
          console.log(a);
          console.log(b);
          console.log(c.value);
        }
        return {
          a,
          b,
          c,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    点击按钮后,输出:

    {
        a: 1,
        b: 2,
        c: 4
    }
    {
        a: 1,
        b: 2,
        c: 4
    }
    4
    

    html显示:a:{"a":1,"b":2,"c":4} b:{"a":1,"b":2,"c":4} c:4

    a reactive(a) toRef(a,'c') view
    a \
    reactive(a) \

    <template>
      <div>
        a:{{a}} b:{{b}} c:{{c}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2, c:3 };
        let b = reactive(a);
        let c = toRef(a,'c');
        const onChange = () => {
          c.value = 4;
          console.log(a);
          console.log(b);
          console.log(c.value);
        }
        return {
          a,
          b,
          c,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    点击按钮后,输出:

    {
        a: 1,
        b: 2,
        c: 4
    }
    {
        a: 1,
        b: 2,
        c: 4
    }
    4
    

    html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    a reactive(a) toRef(a,'c') view
    a \
    reactive(a) \
    toRef(a,'c') \

    <template>
      <div>
        a:{{a}} b:{{b}} c:{{c}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2, c:3 };
        let b = reactive(a);
        let c = toRef(b,'c');
        const onChange = () => {
          a.c = 4;
          console.log(a);
          console.log(b);
          console.log(c.value);
        }
        return {
          a,
          b,
          c,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    点击按钮后,输出:

    {
        a: 1,
        b: 2,
        c: 4
    }
    {
        a: 1,
        b: 2,
        c: 4
    }
    4
    

    html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    a reactive(a) toRef(a,'c') toRef(reactive(a),'c') view
    a \
    reactive(a) \
    toRef(a,'c') \

    <template>
      <div>
        a:{{a}} b:{{b}} c:{{c}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2, c:3 };
        let b = reactive(a);
        let c = toRef(b,'c');
        const onChange = () => {
          b.c = 4;
          console.log(a);
          console.log(b);
          console.log(c.value);
        }
        return {
          a,
          b,
          c,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    点击按钮后,输出:

    {
        a: 1,
        b: 2,
        c: 4
    }
    {
        a: 1,
        b: 2,
        c: 4
    }
    4
    

    html显示:a:{"a":1,"b":2,"c":4} b:{"a":1,"b":2,"c":4} c:4

    a reactive(a) toRef(a,'c') toRef(reactive(a),'c') view
    a \
    reactive(a) \
    toRef(a,'c') \

    <template>
      <div>
        a:{{a}} b:{{b}} c:{{c}}
      </div>
      <button @click="onChange">
        change
      </button>
    </template>
    
    <script>
    export default {
      setup(){
        let a = { a:1, b:2, c:3 };
        let b = reactive(a);
        let c = toRef(b,'c');
        const onChange = () => {
          c.value = 4;
          console.log(a);
          console.log(b);
          console.log(c.value);
        }
        return {
          a,
          b,
          c,
          onChange
        }
      }
    }
    </script>
    

    运行后,html显示:a:{"a":1,"b":2,"c":3} b:{"a":1,"b":2,"c":3} c:3

    点击按钮后,输出:

    {
        a: 1,
        b: 2,
        c: 4
    }
    {
        a: 1,
        b: 2,
        c: 4
    }
    4
    

    html显示:a:{"a":1,"b":2,"c":4} b:{"a":1,"b":2,"c":4} c:4

    a reactive(a) toRef(a,'c') toRef(reactive(a),'c') view
    a \
    reactive(a) \
    toRef(a,'c') \
    toRef(reactive,'c') \

    综上,可以总结以下表格:

    a ref(a) view
    a \
    ref(a) \
    a reactive(a) toRef(a,'c') toRef(reactive(a),'c') view
    a \
    reactive(a) \
    toRef(a,'c') \
    toRef(reactive,'c') \

    相关文章

      网友评论

          本文标题:Vue3的ref、reactive、toRef、toRefs

          本文链接:https://www.haomeiwen.com/subject/pcrytrtx.html