宏观角度看:
区别:
使用原则:
基本用法
import { reactive, toRef } from 'vue';
const person = reactive({ name: 'John Doe' });
const nameRef = toRef(person, 'name');
console.log(nameRef.value); // John Doe
基本用法
import { reactive, toRefs } from 'vue';
const person = reactive({ name: 'John Doe', age: 30 });
const { name, age } = toRefs(person);
console.log(name.value); // John Doe
console.log(age.value); // 30
结论
计算属性是 Vue 3 中一种特殊的响应式变量,它根据其他响应式数据自动计算值。
基本用法
import { computed, ref } from 'vue';
const count = ref(0);
const doubledCount = computed(() => count.value * 2);
特点
作用:监视数据的变化(和 Vue2 中的 watch 作用一致)
特点:Vue3 中的 watch 只能监视以下四种数据:
1.ref 定义的数据。
2.reactive 定义的数据。
3.函数返回一个值(getter 函数)。
4.一个包含上述内容的数组。
监视【ref】 直接写数据名即可,监视的是其 value 值的改变。
示例:
import { watch, ref } from 'vue';
const count = ref(0);
// 监视 ref 'count' 的变化
watch(count, (newValue, oldValue) => {
console.log(`变化前:${oldValue} 变化后: ${newValue}`);
},{
deep: true, // 深度监听 state 对象内部的变化
immediate: true, // 当设置为 true 时,watch 会在开始监视后立即执行一次回调函数。
flush: 'pre', // 控制副作用(如 DOM 更新)的刷新时机。可以是 'pre' 或 'post',或者一个包含这些值的数组。
onTrack: () => {}, // 依赖项被追踪时调用
onTrigger:() =>{}, // 依赖项变化时调用
computed: true // 计算属性模式
});
监视【ref】深层要手动开启深度监视
注意:
若修改的是ref定义的对象中的属性,newValue 和 oldValue 都是新值,因为它们是同一个对象。
若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。
示例:
import { watch, ref } from 'vue';
const person = ref({ name: 'John', age: 30 });
// 监视 ref 'person' 的深层属性变化
watch(
() => person.value, // 使用函数返回 ref 的 value,以确保每次都是最新的值
(newValue, oldValue) => {
// 回调函数会在 person 对象的属性变化时触发
console.log(`变化前:${oldValue.name} 变化后:${newValue.name}`);
},
{ deep: true } // 开启深度监视
);
在这个例子中:
注意事项
监视【reactive】定义的【对象类型】数据,默认开启深度监视(无法关闭)
示例:
import { reactive, watch } from 'vue';
// 使用 reactive 创建一个响应式对象
const person = reactive({
name: 'John',
details: {
age: 30
}
});
// 监视 reactive 对象的 'details.age' 属性
watch(
() => person.details.age,
(newValue, oldValue) => {
console.log(`Age changed from ${oldValue} to ${newValue}`);
}
);
在这个例子中:
注意事项
通过这种方式,Vue 3 的 reactive API 提供了一种直观且强大的方式来创建和管理响应式状态,同时 watch API 允许你监视这些状态的变化,无需担心监视的深度问题。
监视响应式对象中的某个属性,且该属性是基本类型,要写成函数式
监视响应式对象中的某个属性,且该属性是对象类型,可以直接写,也能写函数,更推荐写函数
⭐结论:监视的要是对象里的属性,那么最好写函数式
⭐注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
当监视响应式对象中的基本类型属性时,推荐使用函数式的方式来访问该属性的值。这是因为基本类型的属性不会触发对象的重新分配,所以每次获取的都是最新的值。
示例:
import { watch, reactive } from 'vue';
const person = reactive({ name: 'John' });
// 使用函数式监视响应式对象中的 'name' 属性
watch(
() => person.name,
(newValue, oldValue) => {
console.log(`变化前:${oldValue} 变化后:${newValue}`);
}
);
在这个例子中,我们通过函数 () => person.name 来获取 person 对象的 name 属性的值。每次 watch 触发时,都会调用这个函数以确保获取到最新的 name 值。
当监视响应式对象中的对象类型属性时,可以直接写属性名,也可以使用函数式。推荐使用函数式,尤其是当你需要监视对象内部属性的变化时。
示例:
const person = reactive({ detail: { address: '123 Main St' } });
// 使用函数式监视 'detail' 对象内部的 'address' 属性
watch(
() => person.detail.address,
(newValue, oldValue) => {
console.log(`变化前: ${oldValue} 变化后:${newValue}`);
},deep: true } // 开启深度监视,以追踪对象内部属性的变化
);
在这个例子中,我们监视的是 person.detail.address。由于 address 是 detail 对象的属性,我们需要开启深度监视 { deep: true } 来确保当 address 发生变化时,watch 能够触发。
我们通过函数 () => person.name 来获取 person 对象的 name 属性的值。每次 watch 触发时,都会调用这个函数以确保获取到最新的 name 值。
示例
import { watch, reactive, ref } from 'vue';
// 使用 reactive 创建一个响应式对象
const person = reactive({
name: 'John',
car: 'Toyota'
});
// 使用 ref 创建一个响应式引用
const age = ref(30);
// 监视 person 对象的 'name' 属性和 age 引用
watch([() => person.name, age], (newValues, oldValues) => {
// newValues 和 oldValues 都是数组,分别包含新旧值
console.log(`Name changed to ${newValues[0]}, Age changed to ${newValues[1]}`);
// 如果只想监视 person.car 的变化,可以这样写:
// watch([() => person.car, age], callback, options)
}, { deep: true });
在这个例子中:
注意事项
watchEffect 是 Vue 3 的一个工具,它用来观察你的数据。当你的数据变化时,它会做一些事情。
// 假设我们有一个数字,我们想观察它的变化
const count = 0;
// 使用 `watchEffect` 观察 `count` 的变化
watchEffect(() => {
// 当 `count` 变化时,打印 `count` 的新值
console.log(`New value of count is: ${count}`);
});
// 如果你改变了 `count` 的值,上面的打印就会执行
如果你后面不想观察了,可以告诉 watchEffect 停止。
const stop = watchEffect(() => {
// 逻辑
});
// 想要停止观察时,调用这个函数
stop();