一 computd计算属性
computed 是 Vue 3 中用于创建计算属性的功能。它允许你定义基于响应式数据的动态值,这些值会在其依赖的数据发生变化时自动更新。
- 使用场景
- 依赖于其他响应式数据的计算结果:你可以创建一个计算属性,其值依赖于其他响应式数据,并在这些数据变化时自动更新。
- 性能优化:computed 属性会进行缓存,只有当其依赖的数据发生变化时,才会重新计算,从而提高性能。
只读计算属性
<template>
<div>
<p>名称: {{ name }}</p>
<p>全名: {{ fullName }}</p>
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
return {
firstName,
lastName,
fullName
};
}
}
</script>
关键点
定义:使用 computed 来创建计算属性。例如:
const fullName = computed(() => firstName.value{lastName.value});
访问:计算属性的值可以直接使用,如 {{ fullName }},不需要 .value。
缓存:计算属性会缓存计算结果,只有在依赖的响应式数据变化时才会重新计算。
在 Vue 3 中,computed 属性默认是只读的,但你可以使用一个带有 getter 和 setter 的 computed 属性来实现读写功能。这种方式允许你定义一个计算属性,并同时为它指定一个 setter 函数来处理值的设置。
使用读写计算属性
<template>
<div>
<p>Count: {{ count }}</p>
<p>Doubled: {{ doubled }}</p>
<input v-model="doubled" />
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const doubled = computed({
get: () => count.value * 2,
set: (value) => {
count.value = value / 2;
}
});
return {
count,
doubled
};
}
}
</script>
在这个模板中,doubled 计算属性可以通过输入框进行双向绑定,因为它同时有 getter 和 setter 函数。这样,当输入框的值改变时,count 也会相应地更新。
二 watch
watch 是 Vue 3 中用于观察响应式数据变化并执行相应逻辑的功能。它允许你监控一个或多个响应式数据的变化,并在这些数据发生变化时执行回调函数。
- 作用:监视数据的变化(和
Vue2
中的watch
作用一致) - 特点:
Vue3
中的watch
只能监视以下四种数据:
ref
定义的数据。reactive
定义的数据。- 函数返回一个值(
getter
函数)。- 一个包含上述内容的数组。
- 监视 ref 数据
- 监视
ref
定义的【基本类型】数据:直接写数据名即可,监视的是其value
值的改变。
import { ref, watch } from 'vue';
export default {
setup() {
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
});
return { count };
}
}
- 监视
ref
定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
```vue
<template>
<div class="person">
<h1>情况二:监视【ref】定义的【对象类型】数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改整个人</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
// 数据
let person = ref({
name:'张三',
age:18
})
// 方法
function changeName(){
person.value.name += '~'
}
function changeAge(){
person.value.age += 1
}
function changePerson(){
person.value = {name:'李四',age:90}
}
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:true})
</script>
- 监视
ref
定义的【对象类型】数据中的某个属性
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
let person = ref({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
watch(()=> person.name,(newValue,oldValue)=>{
console.log('person.name变化了',newValue,oldValue)
})
watch(()=>person.car,(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
2- 监视 reactive 数据
- 监视
reactive
定义的【对象类型】数据,且默认开启了深度监视。
let person = reactive({
name:'张三',
age:18
})
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
})
- 监视
reactive
定义的【对象类型】数据中的某个属性
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
let person = ref({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
watch(()=> person.name,(newValue,oldValue)=>{
console.log('person.name变化了',newValue,oldValue)
})
watch(()=>person.car,(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
- 监视函数返回值(getter 函数)
import { ref, computed, watch } from 'vue';
export default {
setup() {
const count = ref(0);
const doubled = computed(() => count.value * 2);
watch(doubled, (newValue, oldValue) => {
console.log(`Doubled value changed from ${oldValue} to ${newValue}`);
});
return { count, doubled };
}
}
- 监视多个数据源(数组)
import { ref, reactive, watch } from 'vue';
export default {
setup() {
const count = ref(0);
const state = reactive({ name: 'Vue' });
watch([count, () => state.name], ([newCount, newName], [oldCount, oldName]) => {
console.log(`Count changed from ${oldCount} to ${newCount}`);
console.log(`Name changed from ${oldName} to ${newName}`);
});
return { count, state };
}
}
三 watchEffect
watchEffect 是 Vue 3 中用于自动执行副作用的功能,它会根据内部使用的响应式数据自动追踪和重新运行。与 watch 不同,watchEffect 不需要指定数据源,它会在副作用函数中自动追踪所有使用的响应式数据。
watch
对比watchEffect
都能监听响应式数据的变化,不同的是监听数据变化的方式不同
watch
:要明确指出监视的数据
watchEffect
:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)。
使用场景
- 简单的副作用:当你只需要执行副作用而不需要控制特定的数据源时。
- 自动追踪:当你希望副作用函数自动追踪其内部引用的所有响应式数据时。
import { ref, watchEffect } from 'vue';
export default {
setup() {
const count = ref(0);
const name = ref('Vue');
watchEffect(() => {
console.log(`Count is ${count.value}, Name is ${name.value}`);
});
return { count, name };
}
}