Vue3的ref、reactive、toRef、toRefs

2021-11-20  本文已影响0人  科科Cole

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


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

  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') \
上一篇 下一篇

猜你喜欢

热点阅读