1.reactive函数
- 作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用
ref
函数) - 语法:
const 代理对象= reactive(源对象)
接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象) - reactive定义的响应式数据是“深层次的”。若要避免深层响应式转换,只想保留对这个对象顶层次访问的响应性,请使用 shallowReactive()open in new window 作替代。
- 只能传入引用类型,否则抛出警告。 ***reactive 将解包所有深层的 refs,同时维持 ref 的响应性。***正确的讲应该是:当它通过代理访问时,会被自动解包:
- 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。
<script lang='ts' setup>
import { ref,reactive } from 'vue';
let rea1 = reactive({ count: 0 }) // Proxy
let refData = ref('1') // RedfImpl 构造函数的对象
//! ***reactive 将解包所有深层的 refs,同时维持 ref 的响应性。***
//! ***正确的讲应该是:当它通过代理访问时,会被自动解包:***
let rea2 = reactive<any>({refData})
//! 当将 ref 分配给 reactive property 时,效果同上
rea2.re2_1 = refData // console.log(rea2.re2_1) > 打印 '1'
// 因为访问 reactive 内的 ref 会自动解包,所以不需要 .value
rea2.re2_1 = '测试'
// 任何类型的新属性都是 proxy 类型
rea2.newObj = {data1:'同样是响应式的'}
</script>
let person = reactive({
name: 'dselegent',
age: 21,
});
console.log(person);
2.ref函数
2.1 基本使用
reactive()
的种种限制归根结底是因为 JavaScript 没有可以作用于所有值类型的 “引用” 机制。为此,Vue 提供了一个ref()方法来允许我们创建可以使用任何值类型的响应式 ref
-
作用: 定义一个响应式的数据
-
语法:
const xxx = ref(initValue)
- 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
- JS中操作数据:
xxx.value
- 模板中作为顶层属性被访问: 它们会被自动“解包”,所以不需要使用
.value
,直接:<div>{{xxx}}</div>
-
备注:
- 接收的数据可以是:基本类型、也可以是对象类型。
- 基本类型的数据:响应式依然是靠
Object.defineProperty()
的get
与set
完成的。 - 对象类型的数据:内部 “ 求助 ” 了Vue1.0中的一个新函数——
reactive
函数。
import { ref } from 'vue'
const count = ref(0)
ref()
将传入参数的值包装为一个带 .value
属性的 ref 对象:
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
和响应式对象的属性类似,ref 的 .value
属性也是响应式的。
如果将一个对象赋值给 ref,那么这个对象将通过 reactive()open in new window 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包。
初体验
<template>
<h2>name:{{ name }}</h2>
<h3>{{ person.name }}</h3>
<button @click="updateName">修改name值为ds2</button>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'App',
setup() {
let name = ref('ds');
console.log(name);
let person = ref({
name: 'dselegent',
age: 21,
});
console.log(person);
function updateName() {
name.value = 'ds2';
person.value.name = 'ds3';
}
return {
name,
updateName,
person,
};
},
};
</script>
let name = ref('ds');
console.log(name);
2.2 ref的响应式
一个包含对象类型值的 ref 可以响应式地替换整个对象:
const objectRef = ref({ count: 0 })
// 这是响应式的替换
objectRef.value = { count: 1 }
ref 被传递给函数或是从一般对象上被解构时,不会丢失响应性:
const obj = {
foo: ref(1),
bar: ref(2)
}
// 该函数接收一个 ref
// 需要通过 .value 取值
// 但它会保持响应性
callSomeFunction(obj.foo)
// 仍然是响应式的
const { foo, bar } = obj
简言之,ref()
让我们能创造一种对任意值的 “引用”,并能够在不丢失响应性的前提下传递这些引用。这个功能很重要,因为它经常用于将逻辑提取到 组合函数open in new window 中。