计算属性与监视

(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>
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WeChat624

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值