本文已参与【新人创作礼】活动,一起开启掘金创作之旅。
前言:Vue3中实现数据响应式,用到的是组合式API中的
ref
和reactive
函数,不同的是ref
函数一般定义基本类型数据,而reactive
函数用于定义一个对象类型的响应式数据。
一、ref函数
-
作用: 定义一个响应式的数据
-
语法:
const xxx = ref(initValue)
-
创建一个包含响应式数据的引用对象(reference对象,简称ref对象) ;
-
JS中操作数据:
xxx.value
,因为ref
接收参数并将其包裹在一个带有value
property 的对象中返回; -
模板中读取数据: 不需要.value,直接:
<div>{{xxx}}</div>
;
-
<template>
<h2>名称:{{name}}</h2>
<button @click="changeName">修改名称</button>
</template>
<script>
import { ref } from 'vue' // 按需引入ref函数
export default {
name: 'App',
setup () {
let name = ref('赵丽颖') // 定义基本类型响应式变量
function changeName () {
console.log('name',name)
name.value = '刘亦菲' // 对ref定义的响应式数据进行操作,需要使用.value
}
// 将变量和函数返回,以便在模版中使用
return {
name,
changeName
}
}
}
</script>
-
备注:
- 接收的数据可以是:基本类型、也可以是对象类型。
- 基本类型的数据:响应式依然是靠
Object.defineProperty()
的get
与set
完成的。 - 对象类型的数据:内部 “ 求助 ” 了Vue3.0中的一个新函数——
reactive
函数(ES6 的 Proxy)。
<template>
<h2>名称:{{name}}</h2>
<h2>工作类型:{{job.type}}</h2>
<button @click="changeName">修改人信息</button>
</template>
<script>
import { ref } from 'vue' // 按需引入ref函数
export default {
name: 'App',
setup () {
let name = ref('赵丽颖') // 定义基本类型响应式变量
let job = ref({ // ref也可以定义对象类型响应式变量
type:'演员',
hobby:'演戏'
})
function changeName () {
console.log('name',name)
name.value = '刘亦菲' // 对ref定义的响应式数据进行操作,需要使用.value
console.log('job',job)
job.value.hobby = '看书'
}
// 将变量和函数返回,以便在模版中使用
return {
name,
job,
changeName
}
}
}
</script>
二、reactive函数
-
作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用
ref
函数); -
语法:
const 代理对象= reactive(源对象)
- 接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象);
- js中操作不需要.value(与ref区别);
- 模板中读取数据: 不需要.value,直接:
<div>{{xxx}}</div>
;
-
备注:
-
reactive定义的响应式数据是“深层次的”。
-
内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。
-
Proxy 响应式原理请参考下篇文档:juejin.cn/post/708046…
-
<template>
<h2>名称:{{name.title}}</h2>
<h2>主要爱好:{{job.hobby[0].type}}</h2>
<button @click="changeName">修改姓名和爱好</button>
</template>
<script>
import { ref,reactive } from 'vue' // 按需引入ref函数
export default {
name: 'App',
setup () {
let name = ref({ // ref定义对象类型响应式变量
title:'赵丽颖'
})
let job = reactive({ // reactive定义对象类型响应式变量
type:'演员',
hobby:[
{
type:'演戏',
degree:'✨✨✨✨✨'
},
{
type:'看书',
degree:'✨✨✨'
}
],
})
function changeName () {
console.log('name',name)
name.value.title = '刘亦菲' // 对ref定义的响应式数据进行操作,需要使用.value
console.log('job',job)
job.hobby[0].type = '运动' // 对reactive定义的响应式数据进行操作,无需使用.value,且是深层次响应
}
// 将变量和函数返回,以便在模版中使用
return {
name,
job,
changeName
}
}
}
</script>
使用ref定义基本类型数据,reactive定义对象类型数据原因:
- ref定义对象,在js中使用时都应该.value,如果定义的对象嵌套太深,再多一层.value太冗余,而reactive则无需.value;
- ref定义对象类型数据,里边使用的也是reactive中的Proxy代理,不如直接使用reactive;
- reactive不能直接定义基本类型数据,不起作用,可以将基本类型数据整体放入一个对象中,将reactive当作Vue2中的data去使用。
let person = reactive({ // 将人信息整体放入一个对象中
name:'赵丽颖',
type:'演员',
hobby:[
{
type:'演戏',
degree:'✨✨✨✨✨'
},
{
type:'看书',
degree:'✨✨✨'
}
],
})