1. ref 创建:基本类型的响应式数据
-
作用:定义响应式变量。
-
语法:
let xxx = ref(初始值)。 -
返回值:一个
RefImpl的实例对象,简称ref对象或ref,ref对象的value属性是响应式的。 -
注意点:
-
JS中操作数据需要:xxx.value,但模板中不需要.value,直接使用即可。 -
对于
let name = ref('张三')来说,name不是响应式的,name.value是响应式的。
-
【代码示例】
<template><div class="person"><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><button @click="changeName">修改名字</button><button @click="changeAge">年龄+1</button></div>
</template><script>
import {ref} from 'vue'
export default {name: 'App',setup() {// 数据(注意:此时的name、age都不是响应式数据)let name = ref('张三')let age = ref(18)// 方法function changeName(){console.log(name)name.value = '李四'}function changeAge(){console.log(age)age.value += 1 }// 返回一个对象,对象中的内容,模板中可以直接使用return {name,age,changeAge,changeName}}
}
</script>
2. ref 创建:对象类型的响应式数据
-
其实
ref接收的数据可以是:基本类型、对象类型。 -
若
ref接收的是对象类型,内部其实也是调用了reactive函数(下文讲述)。
【代码示例】
<template><div class="person"><h1>个人信息</h1><h2>{{ name }}</h2><h2>{{ sex }}</h2><h2>{{ job.position }}</h2><h2>{{ job.salary }}</h2><h2>{{ job.a.b.c.d }}</h2><br><button @click="change">改变信息</button></div>
</template><script>import { ref } from 'vue'export default {name: 'Code',setup() {let name= ref('张三')let sex = ref('男')let job = ref({position: '前端工程师',salary: '20K',a: {b: {c: {d: '123'}}}})function change() {name.value = '李四',sex.value = '女',job.value.position = '后端工程师'job.value.salary = '30K'job.value.a.b.c.d = '456'}return { name, sex,job, change } }}</script>
3. reactive 创建:对象类型的响应式数据
-
作用:定义一个响应式对象(基本类型不要用它,要用
ref,否则报错) -
语法:
let 响应式对象 = reactive(源对象)。 -
返回值:一个
Proxy的实例对象,简称:响应式对象。 -
注意点:
reactive定义的响应式数据是“深层次”的。
【代码示例】
<template><div class="person"><h1>个人信息</h1><h2>{{ person.name }}</h2><h2>{{ person.sex }}</h2><h2>{{ person.job.position }}</h2><h2>{{ person.job.salary }}</h2><h2>{{ person.job.a.b.c.d }}</h2><h3>{{ person.hobby }}</h3><br><button @click="change">改变信息</button></div>
</template><script>
import { reactive } from 'vue'export default {name: 'HelloWorld',setup() {let person = reactive({name: '张三',sex: '男',job: {position: '前端工程师',salary: ('20K'),a: {b: {c: {d: '123'}}}},hobby: ['篮球', '足球', '羽毛球'],})function change() {person.name = '李四',person.sex = '女',person.job.position = '后端工程师'person.job.salary = '30K'person.job.a.b.c.d = '456'person.hobby[0] = '乒乓球'}return { person, change } }}
</script>
4.Vue3中实现响应式的原理
4.1 Proxy
<script type="text/javascript">let person = {name: '张三',age: 18,sex: '男',}// 模拟Vue3中实现响应式const p = new Proxy(person, {// 有人读取p的某个属性时调用get(target, propName) {console.log(`有人读取了${propName}属性`)return target[propName]},// 有人修改p的某个属性或给p追加属性时调用set(target, propName, value) {console.log(`有人修改了${propName}属性`)target[propName] = value},// 有人删除p的某个属性时调用deleteProperty(target, propName) {console.log(`有人删除了${propName}属性`)return delete target[propName]}})</script>
4.2 Reflect

5. ref 对比 reactive
从定义数据角度对比:
(1)ref用来定义:基本类型数据
(2)reactive用来定义:对象(或数组)类型数据
(3)备注:ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象
从原理角度对比:
(1)ref通过Object.defineProperty()的get和set来实现响应式(数据劫持)
(2)reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据
从使用角度对比:
(1)ref定义的数据:操作数据需要 .value, 读取数据时模板中直接读取,不需要.value
(2)reactive定义的数据:操作数据与读取数据均不需要 .value
