相对于Vue2来说,Vue3最大的突破就是 Composition API 。与现有的 Option API 截然不同。他的好处可以总结为两点
更集中的逻辑关注点
更方便的函数逻辑复用机制
不整废话,直接上货。
作用
首先需要明确这四个函数都是用于在 setup 中创造 响应式变量 的。明确了这一前提,再分类讨论。
区分
这四个函数分为两类,可触发页面改变与不可触发页面改变。在我没有完全搞懂每个函数具体的作用时,对这四个各面临的场景及各自的特性是不大能有一个明确的理解的。很容易被混淆。
ref、reactive 可触发页面改变
区别
ref可用于任何类型的数据创建响应式,reactive只用于创建引用类型数据的响应式。
注意
ref对引用类型变量创建响应式其根本是当你给ref传入引用类型则调用reactive方法为其创建响应式。
我为input进行双向绑定 ref 创建的数据,并且注册一个input事件来查看对原始数据的影响。
ref
// template
<div>
<input type="text" v-model="refVal" @input="inputRefHander" />
{{ refVal }}
</div>
// js
let otherName = 'chris';
const refVal = ref(otherName);
const inputRefHander = () => {
console.log(`ref:::refVal: ${refVal.value}, 原始数据: ${otherName}`);
}
通过打印出来的信息可以查看,ref 并不会影响原始数据。
注意: ref返回一个对象,所以在非模板中,使用 ref 创建的变量应通过 .value 的形式访问变量值。在模板中则不用,它会自动展开为内部值。
reactive
我同样对input做相同操作监测 reactive 返回的数据变化。
// template
<div>
<input type="text" v-model="reactiveVal.target" @input="inputreactiveHander" />
{{ reactiveVal.target }}
</div>
// js
const obj = { type: 'obj', target: '5' }
const reactiveVal = reactive(obj);
const inputreactiveHander = () => {
console.log('reactive:::', reactiveVal, "原始数据:::", obj);
}
通过打印可以很明显的看出,原始数据也被改变。
注意:
不可使用解构的方式定义响应式变量,会破坏响应性。所以老老实实的去访问属性就完事儿了,不要图那一两个单词的便利。
toRef、toRefs 不可触发页面改变
上面两个介绍了,ref 和 reactive 可以改变页面。接下来这两个则不能去改变页面,但是数据还是会遵循响应式。
区别、特点:
toRef 用于创建对象指定的属性响应式,换句话说就是只能控制一个对象中的一个属性。
toRefs 用于创建对象响应式。
他们对响应式的处理你可以理解为: toRef 类似 ref, toRefs 类似 reactive
toRef
还是同样的配方,还是同样的代码
// template
<div class="item">
<input type="text" v-model="toRefVal" @input="inputToRefHander" />
{{ toRefVal }}
</div>
// js
const obj = { type: 'obj', target: '5' }
const toRefVal = toRef(obj, 'target');
const inputToRefHander = () => {
console.log("toRef:::", toRefVal, "原始数据:::", obj);
}
toRef 接受两个参数:
- 需要给属性创建响应式的对象
- 需要创建响应式的属性
通过打印的结果很容易看出,toRef是能改变原始数据的。从页面上也能看出,并不能触发页面改变。
toRefs
// template
<div>
<input type="text" v-model="target" @input="inputToRefsHander" />
{{ target }}
</div>
// js
const obj = { type: 'obj', target: '5' }
const { target } = toRefs(obj);
const inputToRefsHander = () => {
console.log("toRefs:::", target, "原始数据:::", obj);
}
依旧从打印结果中可以看出,原始数据被改变,页面没有被触发。但从我的写法上应该可以注意到,toRefs 返回的对象,随便解、随便构。丝毫不会影响值的响应性。
到这里也就写完了,不过还是要提一句setup基础知识。
ref、reactive、toRef、toRefs 这些方法 均需从 vue 中导入到组件。
ref、reactive、toRef、toRefs 创建的变量在 setup 中都需要 return { ... } 抛出才可在页面使用,除非你是为props创建响应式。
最后总结成表格方便大家忘记特性的时候查阅,不过这么简单应该不会忘记( 没错,我就是单纯的想整个表格 )。
类型 是否触发页面改变 是否可以解构
ref 是 否
reactive 是 否
toRef 否 否
toRefs 否 是