(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,(隐式强制deep) //情况三:监视reactive定义的所有响应式数据, //1.此处无法获取正确的oldValue(newValue与oldValue是一致值),且目前无法解决 //2.强制开启了深度监视(deep配置无效) /** * 受到码友热心评论解释: 此处附上码友的解释供大家参考: * 1. 当你监听一个响应式对象的时候,这里的newVal和oldVal是一样的,因为他们是同一个对象【引用地址一样】, * 即使里面的属性值会发生变化,但主体对象引用地址不变。这不是一个bug。要想不一样除非这里把对象都换了 * * 2. 当你监听一个响应式对象的时候,vue3会隐式的创建一个深层监听,即对象里只要有变化就会被调用。 * 这也解释了你说的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>
- 有两个小坑:1.监视reactive定义的响应式数据的时候:oldValue无法获取到正确的值,强制开启了深度监视(deep配置无效)
- 和computed一样,需要引入api