vue的watch和computed详解

导读:本篇文章讲解 vue的watch和computed详解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、watch

1、函数写法

<template>
  <div>
    <input v-model="num" />
    <div>oldVal:{{ oldVal }}</div>
    <div>newVal:{{ newVal }}</div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      num: '',
      oldVal: '',
      newVal: ''
    }
  },
  watch: {
    num (newVal, oldVal) {
      // 监听 num 属性的数据变化
      // 作用 : 只要 num 的值发生变化,这个方法就会被调用
      // 第一个参数 : 新值
      // 第二个参数 : 旧值,之前的值
      this.oldVal = oldVal
      this.newVal = newVal
      console.log('oldVal:', oldVal)
      console.log('newVal:', newVal)
    }
  }
}
</script>

2、对象写法

<template>
  <div>
    <input v-model="obj.num" />
    <button @click="() => (obj.num += 1)">+1</button>
    <div>oldVal:{{ oldVal }}</div>
    <div>newVal:{{ newVal }}</div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      obj: {
        num: 1,
        name: 'jack'
      },
      oldVal: '',
      newVal: ''
    }
  },
  watch: {
    obj: {
      // 第一种方式:监听整个对象,每个属性值的变化都会执行handler
      // 注意:属性值发生变化后,handler执行后获取的 newVal 值和 oldVal 值是一样的
      handler: function (newVal, oldVal) { // 写箭头函数获取不到this
        // oldVal和newVal对应的是watch监听的内容,监听的是对象,那它俩就是对象,监听的是对象中的属性,那它俩就是对象中的属性
        this.oldVal = oldVal
        this.newVal = newVal
        console.log('oldVal:', oldVal) // oldVal是obj,
        console.log('newVal:', newVal) // newVal是obj
      },
      // 立即处理 进入页面就触发
      immediate: true,
      // 深度监听 属性的变化
      deep: true
    },
    // 第二种方式:监听对象的某个属性,被监听的属性值发生变化就会执行函数
    // 函数执行后,获取的 newVal 值和 oldVal 值不一样
    'obj.num' (newVal, oldVal) {
      this.oldVal = oldVal
      this.newVal = newVal
      console.log('oldVal:', oldVal)   // oldVal只是obj.num,非obj对象
      console.log('newVal:', newVal)   // newVal只是obj.num,非obj对象
    }
  }
}
</script>

3、监听对象时,newVal和oldVal值相同的解决方案

原因

Vue官方的解释是:在变更(不是替换)对象或数组时,新值与旧值相同,因为他们指向同一数组或对象,Vue不会保留变更前值的副本。

解决

利用计算属性,通过深拷贝来使其保留

<template>
  <div>
    <input v-model="obj.num" />
    <button @click="() => (obj.num += 1)">+1</button>
    <div>oldVal:{{ oldVal }}</div>
    <div>newVal:{{ newVal }}</div>
    <div>computedVal:{{ objNew }}</div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      obj: {
        num: 1,
        name: 'jack'
      },
      oldVal: '',
      newVal: ''
    }
  },
  watch: {
    // 这里监听的是 computed 的属性
    objNew: {
      handler: function (newVal, oldVal) {
        this.oldVal = oldVal
        this.newVal = newVal
        console.log('oldVal:', oldVal)
        console.log('newVal:', newVal)
      },
      immediate: true,
      deep: true
    }
  },
  computed: {
    // 这里深拷贝 data 的对象
    objNew () {
      return JSON.parse(JSON.stringify(this.obj));
    },
  },
}
</script>


<style scoped>
</style>

二、computed

1、基本使用

<template>
  <div>
    <div>姓:<input v-model="firstName" /></div>
    <div>名:<input v-model="lastName" /></div>
    <div>姓名:{{ fullName }}</div>  // console.log只会执行一次,除非依赖发生变化
    <div>姓名:{{ fullName }}</div> 
  </div>
</template>

<script>
export default {
  data () {
    return {
      firstName: '张',
      lastName: '三'
    }
  },
  computed: {
    fullName: function () {
      console.log('computed开始执行');  
      return this.firstName + this.lastName
    }
  },
}
</script>

2、应用场景

当一个数据受多个数据影响时,可以使用computed

  1. 本组件计算
  2. 计算props的值
  3. 计算vuex的state或者getters值的变化
  4. 父组件给子组件传引用类型的值,且子组件要展示newVal和oldVal(computed+watch)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84947.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!