Vue2
在Vue2内,写在data内的数据都为响应式的数据
是做了数据代理和数据劫持实现的
Vue3
是用 ref 和 reactive 实现响应式数据的
ref
基本类型的响应式数据
可以定义 基本类型数据、对象类型数据
作用:定义响应式变量
语法:let xxx = ref(初始值)
返回值:一个 RefImpl 的实例对象,简称 ref对象 或 ref,ref对象的value属性是响应式的
注意:1. JS中(方法中)操作数据需要,xxx.value,但是模版中使用数据不需要.value,可以直接使用
2. 对于 let name = ref(‘张三’)来说,name不是响应式的,name.value是响应式的
// 定义基本类型的响应式数据
let name = ref('张杰')
let age = ref(22)
// 模版中直接使用
<div>{{ name }}</div>
// JS方法中需要 .value
function changeName() {
name.value = 'Jason Zhang'
}
reactive
对象类型的响应式数据
只能定义对象类型的响应式数据
作用:定义一个响应式变量(不要用来定义基本类型,会报错)
语法:let 响应式对象 = reactive(源对象)
返回值:一个 Proxy 的实例对象,简称 响应式对象
注意:reactive 定义的响应式数据是深层次的
// 定义的数据
let ticket = reactive({name: '张杰演唱会门票', price: 1680})
let songs = reactive([
{ id: '001', name: '爱不解释' },
{ id: '002', name: '这就是爱' },
{ id: '003', name: '穿越人海' },
])
// 方法 不用.value
function hChangePrice(){
ticket.price -= 100
}
ref 和 reactive 对比
宏观角度:
1. ref 用来定义 基本类型数据、对象类型数据
2. reactive 用来定义 对象类型数据
区别:
1. ref 创建的变量必须使用 .value (可以使用 volar 插件自动添加 .value)
2. reactive 重新分配一个新对象,会失去响应式(可以使用 Object.assign 去整体替换)
Object.assign(原来的对象, 新对象值)
// 示例
let car = reactive({ name: '保时捷', price: 299 })
Object.assign(car, { name: '小米SU7', price: 29.9 })
使用原则:
1. 基本类型响应式数据,必须使用 ref
2. 响应式对象,层级不深,ref 和 reactive 都可以
3. 响应式对象,层级深,推荐使用 reactive
toRefs 与 toRef
作用:将一个响应式对象中的每一个属性,转换为 ref 对象
备注: toRefs 与 toRef 功能一致,但是 toRefs 可以批量转换
代码示例:
// 数据
let ticket = reactive({name: '张杰演唱会门票', price: 1680})
let {name, price} = toRefs(ticket)
// 方法
function hChangePrice(){
price.value -= 100
}
这里的目的就是把ticket的值,类似于结构赋值一样,把里面的属性单独的提取出来,并也让提取后的属性为响应式的,这样在方法内去操作时,可以直接修改提取后的属性,需要注意的是,操作时要加上.value,操作后,原来的 ticket的值也会同步改变
在模版内使用的时候,可以 {{ ticket.name }},也可以直接 {{ name }}
toRef的使用和toRefs一样,只是toRef只能操作一个值.,代码示例如下:
let xxx = toRef(要传递的对象,需要变成响应式的属性)
let nl = toRef(person,'age')