2022-09-02 更新:这篇文章写了比较久了,不推荐大家再往下看。推荐大家去看Vue.js设计与实现这本书,讲得很好,看完绝对能彻底理解响应式。
在网上看了很多文章没有一个能把这些效果讲清楚的。我写一下自己试出来的结果。
先说一下我根据结论得出的理解:
- 只有响应式数据能更新界面,ref()、reactive()可以生成响应式数据。
- ref即可以用于基础数据类型,也可以用于复杂数据类型;reactive用于复杂数据类型;toRef/toRefs用于解构响应式数据,因为如果直接解构响应式数据会使其失去响应性。
- toRef返回的值是否具有响应性取决于被解构的对象本身是否具有响应性。响应式数据经过toRef返回的值仍具有响应性,非响应式数据经过toRef返回的值仍没有响应性。
- toRefs相当于对对象内每个属性调用toRef,toRefs返回的对象内的属性使用时需要加.value。
a:{{a}} b:{{b}}
运行后,html显示:a:1 b:1
。
点击按钮后,输出:
2
1
html显示:a:1 b:1
。
a | ref(a) | view | |
---|---|---|---|
a | \ | ❌ | ❌ |
a:{{a}} b:{{b}}
运行后,html显示:a:1 b:1
。
点击按钮后,输出:
1
2
html显示:a:1 b:2
。
a | ref(a) | view | |
---|---|---|---|
a | \ | ❌ | ❌ |
ref(a) | ❌ | \ | ✅ |
a:{{a}} b:{{b}}
运行后,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 | \ | ✅ | ❌ |
a:{{a}} b:{{b}}
运行后,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) | ✅ | \ | ✅ |
a:{{a}} b:{{b}} c:{{c}}
运行后,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 | \ | ✅ | ✅ | ❌ |
a:{{a}} b:{{b}} c:{{c}}
运行后,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) | ✅ | \ | ✅ | ✅ |
a:{{a}} b:{{b}} c:{{c}}
运行后,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') | ✅ | ✅ | \ | ❌ |
a:{{a}} b:{{b}} c:{{c}}
运行后,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') | ✅ | ✅ | \ | ❌ |
a:{{a}} b:{{b}} c:{{c}}
运行后,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') | ✅ | ✅ | \ | ✅ | ❌ |
a:{{a}} b:{{b}} c:{{c}}
运行后,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') | ✅ | ✅ | ✅ | \ | ✅ |