这里写目录标题
- 一级目录
- 二级目录
- 三级目录
- ref和reactive的区别
- 用途
- 用法
- 响应性
- 组合式使用
- vue3中setup语法糖的使用
- 优势
- 举例
- Vue 2 中通过 Object.defineProperty 来拦截对象的属性访问和修改以实现数据的响应化
- 1. 数据初始化
- 2. 使用 Object.defineProperty
- 3. 依赖收集
- 4. 通知更新
- 5. 嵌套对象的处理
- 6. 限制
一级目录
二级目录
三级目录
ref和reactive的区别
用途
- ref:
主要用于创建单一的响应式数据(基本类型或对象)。
当你需要对一个简单的数据类型(如字符串、数字、布尔值等)进行响应式处理时,使用 ref 更为合适。 - reactive:
用于创建一个响应式对象,适用于复杂的对象或嵌套对象。
当你需要将整个对象或数组变为响应式时,使用 reactive 更为合适。
用法
- 使用 ref 创建的响应式数据需要通过 .value 来访问和修改
- 使用 reactive 创建的对象可以直接访问和修改其属性,无需使用 .value
响应性
- ref:
对于基本类型(如数字、字符串等),ref 提供了更简单的响应式处理。
对于对象类型,使用 ref 时仍然需要通过 .value 来访问。 - reactive:
直接将对象的所有属性变为响应式。
支持深层嵌套的对象属性,所有嵌套属性都会被自动转换为响应式。
组合式使用
vue3中setup语法糖的使用
优势
使用 setup 语法糖,可以减少样板代码,使得组件更加简洁易读。通过这种方式,你可以直接在模板中使用导入的组件,而无需在 export default 中定义 components 选项
举例
<template>
<div>
<MyComponent v-slot="{ info }">
<p>{{ info.message }} - Count: {{ info.count }}</p>
</MyComponent>
</div>
</template>
<script setup>
import MyComponent from './MyComponent.vue';
</script>
Vue 2 中通过 Object.defineProperty 来拦截对象的属性访问和修改以实现数据的响应化
1. 数据初始化
2. 使用 Object.defineProperty
内部实现过程中,Vue 会遍历 data 对象的属性,使用 Object.defineProperty 为每个属性定义 getter 和 setter:
function defineReactive(obj, key, val) {
// 递归处理嵌套对象
observe(val); // 使得嵌套对象也响应式
Object.defineProperty(obj, key, {
get() {
// 依赖收集
return val;
},
set(newVal) {
if (newVal !== val) {
val = newVal;
// 通知视图更新
// 这里可以触发更新逻辑
}
}
});
}
3. 依赖收集
在 getter 中,Vue 会收集依赖(例如组件的渲染函数或计算属性)。当属性被访问时,Vue 会将当前的观察者(watcher)添加到依赖列表中。
4. 通知更新
在 setter 中,当属性值被修改时,Vue 会检查新值与旧值是否不同。如果不同,则更新值并通知依赖的观察者(即更新视图)。
5. 嵌套对象的处理
对于对象中的嵌套属性,Vue 会递归调用 defineReactive 以确保所有层级的属性都是响应式的。这是通过 observe 函数实现的:
function observe(value) {
if (typeof value !== 'object' || value === null) {
return;
}
// 处理对象的每个属性
for (let key in value) {
defineReactive(value, key, value[key]);
}
}
6. 限制
新增属性: 如果对一个对象添加新属性,Vue 不能自动侦测到这个变化。可以使用 Vue.set(obj, ‘newProp’, value) 来添加新属性,并确保它是响应式的。
数组处理: Vue 通过重写数组的一些方法(如 push、pop、splice 等)来确保数组的变化是响应式的。