在网上看了很多文章没有一个能把这些效果讲清楚的。我写一下自己试出来的结果。
先说一下我根据结论得出的理解:
- 只有响应式数据能更新界面,ref()、reactive()可以生成响应式数据。
- ref一般用于基础数据类型,按值传递;reactive用于复杂数据类型,按引用传递;toRef/toRefs一般用于解构响应式数据,因为如果直接解构响应式数据会使其失去响应性。
- toRef返回的值是否具有响应性取决于被解构的对象本身是否具有响应性。响应式数据经过toRef返回的值仍具有响应性,非响应式数据经过toRef返回的值仍没有响应性。toRef返回的是Ref<T>类型,因此在setup()内需要使用.value赋值或调用。
- 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') | ✅ | ✅ | ✅ | \ | ✅ |
网友评论