**計算屬性與監視**
##### (1)computed函數
* 與vue2.x中的寫法一致
* 需要引入computed
```
<template>
<h1>個人的信息</h1>
<div>
姓: <input type="text" v-model="person.firstName">
名:<input type="text" v-model="person.lastName">
<div>
<span>簡名:{{person.smallName}}</span> <br>
<span>全名:{{person.fullName}}</span>
</div>
</div>
</template>
<script>
import { computed,reactive } from 'vue'
export default {
name: 'test4',
props: ['msg'],
emits:['hello'],
setup(){
let person = reactive({
firstName: '張',
lastName: '三'
})
//簡寫形式
person.smallName = computed(()=>{
return person.firstName + '-' + person.lastName
})
//完全形態
person.fullName = computed({
get(){
console.log('調用get');
return person.firstName + '*' + person.lastName
},
set(value){
console.log('調用set');
const nameArr = value.split('*')
person.firstName = nameArr[0]
person.firstName = nameArr[1]
},
})
return {
person,
}
},
}
</script>
```
##### (2)watch函數
* 和computed一樣,需要引入api
* 有兩個小坑:
1.監視reactive定義的響應式數據的時候:oldValue無法獲取到正確的值,強制開啟了深度監視(deep配置無效)
2.監視reactive定義的響應式數據中某個屬性的時候:deep配置有效
具體請看下面代碼以及注釋
```
<template>
<h1>當前求和為: {{sum}}</h1>
<button @click="sum++">點我+1</button>
<hr>
<h1>當前信息為: {{msg}}</h1>
<button @click="msg+='!' ">修改信息</button>
<hr>
<h2>姓名: {{person.name}}</h2>
<h2>年齡: {{person.age}}</h2>
<button @click="person.name += '~' ">修改姓名</button> <button @click="person.age++">增長年齡</button>
</template>
<script>
//使用setup的注意事項
import { watch,ref,reactive } from 'vue'
export default {
name: 'test5',
props: ['msg'],
emits:['hello'],
setup(){
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
name: '張三',
age: 18,
job:{
salary: '15k'
},
})
//由于這里的this是指的是undefined,所以使用箭頭函數
//情況一:監視ref所定義的一個響應式數據
// watch(sum, (newValue,oldValue)=>{
// console.log('新的值',newValue);
// console.log('舊的值',oldValue);
// })
//情況二:監視ref所定義的多個響應式數據
watch([sum,msg], (newValue,oldValue)=>{
console.log('新的值',newValue); //['sum的newValue', 'msg的newValue']
console.log('舊的值',oldValue); //['sum的oldValue', 'msg的oldValue']
},{immediate: true,deep:true}) //這里vue3的deep是有點小問題的,可以不用deep
//情況三:監視reactive定義的所有響應式數據,
//1.此處無法獲取正確的oldValue(newValue與oldValue是一致值),且目前無法解決
//2.強制開啟了深度監視(deep配置無效)
watch(person, (newValue,oldValue)=>{
console.log('新的值',newValue);
console.log('舊的值',oldValue);
})
//情況四:監視reactive對象中某一個屬性的值,
//注意: 這里監視某一個屬性的時候可以監聽到oldValue
watch(()=>person.name, (newValue,oldValue)=>{
console.log('新的值',newValue);
console.log('舊的值',oldValue);
})
//情況五:監視reactive對象中某一些屬性的值
watch([()=>person.name,()=>person.age], (newValue,oldValue)=>{
console.log('新的值',newValue);
console.log('舊的值',oldValue);
})
//特殊情況: 監視reactive響應式數據中深層次的對象,此時deep的配置奏效了
watch(()=>person.job, (newValue,oldValue)=>{
console.log('新的值',newValue);
console.log('舊的值',oldValue);
},{deep:true}) //此時deep有用
return {
sum,
msg,
person,
}
},
}
</script>
```
(3)watchEffect函數
watch的套路是:既要指明監視的屬性,也要指明監視的回調
watchEffect的套路是:不用指明監視哪個屬性,監視的回調中用到哪個屬性,那就監視哪個屬性
watchEffect有點像computed:
但computed注重的計算出來的值(回調函數的返回值),所以必須要寫返回值
而watchEffect更注重的是過程(回調函數的函數體),所以不用寫返回值
```
<script>
//使用setup的注意事項
import { ref,reactive,watchEffect } from 'vue'
export default {
name: 'test5',
props: ['msg'],
emits:['hello'],
setup(){
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
name: '張三',
age: 18,
job:{
salary: '15k'
},
})
//用處: 如果是比較復雜的業務,發票報銷等,那就不許需要去監聽其他依賴,只要發生變化,立馬重新回調
//注重邏輯過程,你發生改變了我就重新執行回調,不用就不執行,只執行一次
watchEffect(()=>{
//這里面你用到了誰就監視誰,里面就發生回調
const x1 = sum.value
console.log('我調用了');
})
return {
sum,
msg,
person,
}
},
}
</script>
```