reactive API的使用
reactive方法用来创建响应式对象,它接收一个对象/数组参数,返回对象的响应式副本,当该对象的属性值发生变化,会自动更新使用该对象的方法。
接下来我们用对象和数组来作为参数演示:
import {reactive, toRefs} from 'vue'
export default {
setup() {
const dataMap = reactive({
reactiveName : 'Chris1993',
reactiveArr : ['a','b','c','d']
})
const methodsMap = reactive({
setReactiveObj : () => {
dataMap.reactiveName = 'Hello Chris1993'
},
setReactiveArr: () => {
dataMap.reactiveArr[1] = 'Hello Chris1993'
}
})
return {
...toRefs(dataMap),
...toRefs(methodsMap)
}
}
}
模板如下:
<h2>Vue3 reactive API Base</h2>
<div>
Object:{{reactiveName}}
<span @click="setReactiveObj" class="button1">Update</span>
</div>
<div>
Array:{{reactiveArr}}
<span @click="setReactiveArr" class="button1">Update</span>
</div>
此时页面如下:
当点击Update按钮后,数据会发生变化,同时视图上的内容会跟着一起更新:
ref API的使用
ref的作用就是将一个原始数据类型转换成一个带有响应式特性的数据类型,原始数据类型共有7个值,分别是String,BigInt,Number,Boolean,Symbol,Null,Undefined。
ref的值在JS/TS中读取或修改时,需要使用 .value 来获取,而在模板中读取是不需要使用 .value
下面分别以字符串和对象作为参数演示:
import {ref} from 'vue'
export default {
setup() {
let refValue = ref('Chris1993')
let refObj = ref ({ name: 'Chris1993'})
let setRefValue = () => {
refValue.value = 'Hello Chris1993'
}
let setRefObj = () => {
refObj.value.name = 'Hello Chris1993'
}
return {
refValue,
refObj,
setRefValue,
setRefObj
}
}
}
模板内容如下:
<h2>Vue3 ref API Base</h2>
<div>
String: {{refValue}}
<span @click="setRefValue" class="button">Update</span>
</div>
<div>
Object: {{refObj.name}}
<span @click="setRefObj" class="button">Update</span>
<span></span>
</div>
此时页面展示如下:
当我们分别点击Update按钮后,数据发生变化后,视图内容也一起更新了:
reactive可以用在深层对象或数组
reactive是基于ES2015 Proxy API实现的,它的响应式是整个对象的所有嵌套层级。
接下来用对象和数组作为参数进行展示
import {reactive} from 'vue'
export default {
setup() {
let reactiveDeepObj = reactive({
user:{name: 'Chris1993'}
})
let setReactiveDeepObj = () => {
reactiveDeepObj.user.name = 'Hello Chris1993'
}
let reactiveDeepArr = reactive(['a',['a1','a2','a3'],'c','d'])
let setReactiveDeepArr = () => {
reactiveDeepArr[1][1] = 'Hello Chris1993'
}
return {
reactiveDeepObj,
reactiveDeepArr,
setReactiveDeepObj,
setReactiveDeepArr
}
}
}
模板内容如下:
<h2>Vue3 reactive deep API Base</h2>
<div>
Object: {{reactiveDeepObj.user.name}}
<span @click="setReactiveDeepObj" class="button">Update</span>
</div>
<div>
Array: {{reactiveDeepArr}}
<span @click="setReactiveDeepArr" class="button">Update</span>
</div>
此时的页面如下:
当点击Update按钮后,数据产生变化后,视图内容也跟着一起更新:
reactive返回值和源对象不一样
reactive是基于ES2015 Proxy API实现的,返回结果是个proxy对象。
测试代码:
import {reactive} from 'vue'
import { onMounted } from '@vue/runtime-core'
export default {
setup() {
let reactiveSource = {name: 'Chris1993'}
let reactiveData = reactive(reactiveSource)
onMounted(() => {
console.log(reactiveSource === reactiveData);
console.log(reactiveSource);
console.log(reactiveData);
})
}
}
输出如下:
把ref值作为reactive参数
当我们已有一个ref对象,需要使用在reactive对象中,会发生什么?
let name = ref('Chris1993')
let nameReactive = reactive({name})
console.log(name.value === nameReactive.name); //true
name.value = 'Hi Chris1993'
console.log(name.value); //Hi Chris1993
console.log(nameReactive.name); //Hi Chris1993
nameReactive.name = 'Hi Chris1993'
console.log(name.value); //Hi Chris1993
console.log(nameReactive.name); //Hi Chris1993
reactive会将深层的refs进行解包,并且保持ref的响应式。
当通过赋值方式将ref分配给reactive属性时,ref也会自动被解包
let name = ref('Chirs1993')
let nameReactive = reactive({})
nameReactive.name = name
console.log(name.value); // Chris1993
console.log(nameReactive.name); // Chris1993
console.log(name.value === nameReactive.name); //true
总结
- reactive一般用于对象/数组类型的数据,都不需要使用 .value
- ref一般用于基础数据类型的数据,在JS中读取和修改时,需要使用 .value,在模板中使用时则不需要
- reactive可以修改深层属性值,并保持响应
- reactive返回值和源对象不同
- reactive的属性值可以是ref值
- ref本质也是reactive,ref(obj) 等价于 reactive({value: obj})