computed 計(jì)算屬性
計(jì)算屬性是指 基于現(xiàn)有狀態(tài)派生 (演變) 出新的狀態(tài),現(xiàn)有狀態(tài)發(fā)生變化,派生狀態(tài)重新計(jì)算。
computed 接收回調(diào)函數(shù)作為參數(shù),基于回調(diào)函數(shù)中使用的響應(yīng)式數(shù)據(jù)進(jìn)行計(jì)算屬性的創(chuàng)建,回調(diào)函數(shù)的返回值就是基于現(xiàn)有狀態(tài)演變出的新狀態(tài)。
// 定義一個(gè)數(shù)據(jù)
const num = ref(0);
// result 通過計(jì)算num動(dòng)態(tài)獲得
const result = computed(() => num.value * 2);
- 完整寫法
import { ref, computed } from 'vue';
export default {
setup() {
// 響應(yīng)式數(shù)據(jù)
const firstName = ref('張');
const lastName = ref('三');
// 計(jì)算屬性(完整寫法,考慮讀和寫)
const fullName = computed({
get() {
return firstName.value + lastName.value;
},
set (value) {
const nameArr = value.split('-');
firstName.value = nameArr[0];
lastName.value = nameArr[1];
},
});
// 返回所有的數(shù)據(jù)和方法,才能使用
return { firstName, lastName, fullName }
}
}
案例:動(dòng)態(tài)顯示名字。
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
<div>姓名:{{ name }}</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const firstName = ref('');
const lastName = ref('');
// 姓名通過計(jì)算屬性獲得
const name = computed(() => firstName.value + lastName.value);
return { firstName, laseName, name }
}
}
</script>
watch 監(jiān)聽狀態(tài)
watch 方法用于監(jiān)聽響應(yīng)式數(shù)據(jù)的變化,數(shù)據(jù)發(fā)生變化時(shí)觸發(fā)。
Vue2 的 watch 是一個(gè)配置項(xiàng),Vue3 的 watch 是一個(gè)方法。
# 語法格式
watch([監(jiān)視對(duì)象], fn{監(jiān)視的回調(diào)}, {監(jiān)視的配置});
監(jiān)聽 ref 的響應(yīng)式數(shù)據(jù)
監(jiān)聽 ref 數(shù)據(jù)時(shí),不能使用
.value
,因?yàn)楸O(jiān)聽的是 value 的值,而不是 ref 數(shù)據(jù)。
- 監(jiān)聽多個(gè)值時(shí),newValue 和 oldValue 會(huì)接收一個(gè)數(shù)組,參數(shù)是監(jiān)聽的每一項(xiàng)。
使用 watch 方法監(jiān)聽基于 ref 創(chuàng)建的響應(yīng)式數(shù)據(jù) (基本數(shù)據(jù)類型)。
<template>
<input type="text" v-model="str">
</template>
<script>
import { ref, watch } from 'vue';
export default {
setup() {
const str ref('');
// 監(jiān)聽表單內(nèi)容 str
watch(str, (newValue, oldValue) => {
console.log(newValue, oldValue);
}, {
// 監(jiān)聽的配置
immediate: true,
deep: true
});
// 返回所有的數(shù)據(jù)和方法,才能使用
return { str }
}
}
</script>
使用 watch 監(jiān)聽基于 ref 創(chuàng)建的響應(yīng)式數(shù)據(jù) (引用數(shù)據(jù)類型)。
import { ref, watch } from "vue";
export default {
setup() {
const person = ref({ name: '張三' });
// 監(jiān)聽
watch(person.value, (newValue, oldValue) => {
console.log(newValue, oldValue);
}, {
// 監(jiān)聽的配置
immediate: true,
deep: true
});
// 返回所有的數(shù)據(jù)和方法,才能使用
return { person }
},
};
使用 watch 監(jiān)聽響應(yīng)式數(shù)據(jù)內(nèi)部的具體屬性 (基本數(shù)據(jù)類型)
import { ref, watch } from "vue";
export default {
setup() {
const person = ref({ name: '張三' });
// 監(jiān)聽
watch(
() => person.value.name,
(newValue, oldValue) => {
console.log(newValue, oldValue);
}
);
// 返回所有的數(shù)據(jù)和方法,才能使用
return { person }
},
};
監(jiān)聽 reactive 的響應(yīng)式數(shù)據(jù)
import { ref, watch } from "vue";
export default {
setup() {
const person = reactive({ name: '張三' });
// 監(jiān)聽
watch(person, (newValue, oldValue) => {
console.log(newValue, oldValue);
});
// 返回所有的數(shù)據(jù)和方法,才能使用
return { person }
},
};
監(jiān)聽 reactive 時(shí)存在的問題
坑:監(jiān)聽 reactive 時(shí),oldValue 無法正確獲取,都是最新值。(Vue3的遺留問題)
- 解決方案:
watch 的 參數(shù)1 使用
() => 對(duì)象名.屬性名
監(jiān)聽單個(gè)屬性,但是要使用 deep 深度監(jiān)聽。(雖然麻煩,但是有效)
const person = ref({ name: '張三', age: 18 });
watch(
// 參數(shù)一寫法解決 oldValue 值無法獲取
[() => person.name, () => person.age],
(newValue, oldValue) => {
console.log(newValue, oldValue);
}
);
坑:使用 reactive 時(shí),強(qiáng)制開啟 deep 深度監(jiān)視,且 deep 無法被關(guān)閉。(Vue3的遺留問題)
import { ref, watch } from "vue";
export default {
setup() {
const person = reactive({ name: '張三' });
// 監(jiān)聽
watch(person, (newValue, oldValue) => {
console.log(newValue, oldValue);
}, {
deep: false, // 無效,無法關(guān)閉
});
// 返回所有的數(shù)據(jù)和方法,才能使用
return { person }
},
};
watchEffect 監(jiān)聽狀態(tài)
watchEffect 函數(shù)在頁面加載完成后和數(shù)據(jù)更新時(shí)調(diào)用。
watch 和 watchEffect 的區(qū)別:
- watch:既要指明監(jiān)視的屬性,也要指明監(jiān)視的回調(diào)。
- watchEffect:不用指明監(jiān)視哪個(gè)屬性,監(jiān)視的回調(diào)中用到哪個(gè)屬性,就監(jiān)聽哪個(gè)屬性。
watchEffect 和 computed 的區(qū)別:
- computed 注重計(jì)算出來的值(回調(diào)函數(shù)的返回值),所以必須要寫返回值。
- watchEffect 更注重的是過程(回調(diào)函數(shù)的函數(shù)),所以不用寫返回值。
# 語法格式
watchEffect(() => {
console.log('watchEffect 函數(shù)執(zhí)行了');
})
<template>
<h1>{{ person.name }}</h1>
<button @click="updatePerson">點(diǎn)擊更新名字</button>
</template>
<script>
import { reactive, watchEffect } from "vue";
export default {
setup() {
// 響應(yīng)式數(shù)據(jù)
let person = reactive({
name: "張三",
age: 18,
job: {
j1: {
salary: 20,
},
},
});
// 監(jiān)視
watchEffect(() => {
console.log("watchEffect執(zhí)行了");
console.log(person.name);
});
// 更新名字
const updatePerson = () => {
person.name = "李四";
};
return { person, updatePerson };
},
};
</script>
toRef 函數(shù)
創(chuàng)建一個(gè) ref 對(duì)象,其 value 值指向另一個(gè)對(duì)象中的某個(gè)屬性。
大白話解釋:toRef 方法用于將響應(yīng)式數(shù)據(jù)內(nèi)部的普通數(shù)據(jù)轉(zhuǎn)化為響應(yīng)式數(shù)據(jù),并且轉(zhuǎn)換后的數(shù)據(jù)和原始數(shù)據(jù)存在引用關(guān)系,存在引用關(guān)系意味著當(dāng)原始數(shù)據(jù)發(fā)生變化后,toRefs 轉(zhuǎn)換后的數(shù)據(jù)也會(huì)跟著變化。
應(yīng)用:要將響應(yīng)式對(duì)象中的某個(gè)屬性單獨(dú)提供給外部使用時(shí)。文章來源:http://www.zghlxwxcb.cn/news/detail-485805.html
// 語法
const name = toRef(對(duì)象名, '屬性名')
<template>
<h1>{{ name }}</h1>
<h1>{{ age }}</h1>
<h1>{{ salary }}</h1>
</template>
<script>
import { reactive, toRef } from 'vue'
export default {
name: 'App',
setup() {
let person = reactive({
name: '張三',
age: 18,
job: {
j1: {
salary: 20
}
}
})
return {
pname: toRef(person, 'name'),
age: toRef(person, 'age'),
salary: toRef(person.job.j1, 'salary')
}
},
}
</script>
toRefs 函數(shù)
toRefs方法接收引用數(shù)據(jù)類型的響應(yīng)式數(shù)據(jù),它可以將數(shù)據(jù)中的第一層屬性全部轉(zhuǎn)換為響應(yīng)式數(shù)據(jù),返回值是一個(gè)對(duì)象,對(duì)象中存儲(chǔ)了所有轉(zhuǎn)換之后的響應(yīng)式數(shù)據(jù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-485805.html
export default {
setup() {
const person = reactive({
name: "張三",
brand: {
title: "寶馬",
year: 1
}
});
return {
...toRefs(person),
...toRefs(person.brand) // 轉(zhuǎn)換第二層數(shù)據(jù)為響應(yīng)式
}
}
}
到了這里,關(guān)于Vue3:計(jì)算屬性、監(jiān)聽器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!