**计算属性与监视**
##### (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>
```