Vue核心知识-computed和watch的使用场景和方法

computed

不使用 computed

通过简单的字符串拼接

import Vue from 'vue'

new Vue({
  el: '#root',
  template: `
    <div>
      <span>Name: {{firstName + ' ' + lastName}}</span>
    </div>
  `,
  data: {
    firstName: 'Jokcy',
    lastName: 'Lou'
  }
})

使用 computed

new Vue({
  el: '#root',
  template: `
    <div>
      <span>Name: {{name}}</span>
    </div>
  `,
  data: {
    firstName: 'Jokcy',
    lastName: 'Lou'
  },
  computed: {
    name () {
      return `${this.firstName} ${this.lastName}`
    }
  }
})

使用 methods

显示结果和使用 computed 相同

new Vue({
  el: '#root',
  template: `
    <div>
      <span>Name: {{name}}</span>
      <span>Name: {{getName()}}</span>
    </div>
  `,
  data: {
    firstName: 'Jokcy',
    lastName: 'Lou'
  },
  computed: {
    name () {
      return `${this.firstName} ${this.lastName}`
    }
  },
  methods: {
    getName () {
      return `${this.firstName} ${this.lastName}`
    }
  }
})

使用 computed 的好处

当我们改变 number 时,整个应用会重新渲染,vue 会被数据重新渲染到 dom 中。这时,如果我们使用 getName 方法,随着渲染,方法也会被调用,而 computed 不会重新进行计算,从而性能开销比较小。当新的值需要大量计算才能得到,缓存的意义就非常大。

如果 computed 所依赖的数据发生改变时,计算属性才会重新计算,并进行缓存;当改变其他数据时,computed 属性 并不会重新计算,从而提升性能。

当我们拿到的值需要进行一定处理使用时,就可以使用 computed。

import Vue from 'vue'

new Vue({
  el: '#root',
  template: `
    <div>
      <p>Name: {{name}}</p>
      <p>Name: {{getName()}}</p>
      <p>Number: {{number}}</p>
      <p><input type="text" v-model="number"/></p>
      <p>FirsName: <input type="text" v-model="firstName"/></p>
      <p>LaseName: <input type="text" v-model="lastName"/></p>
    </div>
  `,
  data: {
    firstName: 'Jokcy',
    lastName: 'Lou',
    number: 0
  },
  computed: {
    name () {
      console.log('new name')
      return `${this.firstName} ${this.lastName}`
    }
  },
  methods: {
    getName () {
      console.log('getName invoked')
      return `${this.firstName} ${this.lastName}`
    }
  }
})

computed 设置的操作

通过 computed 的 set 方法,可以进行设置的操作。

如下例,通过改变 name 的值,也可以改变 computed 属性 name 所以来的 firstName 和 lastName 的值。

不推荐这样做,一般 computed 属性数据是根据多重数据组合成的新的数据,组合容易,但拆开重新设置并不容易

template: `
    <div>
      <p>Name: <input type="text" v-model="name"/></p>
    </div>
  `,
  data: {
    firstName: 'Jokcy',
    lastName: 'Lou',
  },
  computed: {
    name: {
      get () {
        console.log('new name')
        return `${this.firstName} ${this.lastName}`
      },
      set (name) {
        const names = name.split(' ')
        this.firstName = names[0]
        this.lastName = names[1]
      }
    }
  },

watch

例如,监听 firstName 数据,并根据改变得到的新值,进行某些操作。

new Vue({
  template: `
    <div>
      <p>FullName: {{fullName}}</p>
      <p>FirsName: <input type="text" v-model="firstName"/></p>
    </div>
  `,
  data: {
    firstName: 'Jokcy',
    lastName: 'Lou',
    fullName: ' '
  },
  watch: {
    firstName (newName, oldName) {
      this.fullName = newName + ' ' + this.lastName
    }
  }
})

注意:上例中,初始 fullName 是没有值的,只有当数据改变时,才会显示。因为 watch 的方法默认是不会执行的,只有当监听数据变化,才会执行。

immerdiate 属性

通过声明 immediate 选项为 true,可以立即执行一次 handler。

watch: {
    firstName: {
      handler (newName, oldName) {
        this.fullName = newName + ' ' + this.lastName
      },
      immediate: true
    }
  },

watch 并不适用于显示某一个数据以及数据的拼装等。watch 用在监听数据变化,做某些指令操作(给后台发数据请求)

deep属性

不使用 deep 时,当我们改变 obj.a 的值时,watch不能监听到数据变化,默认情况下,handler 只监听属性引用的变化,也就是只监听了一层,但改对象内部的属性是监听不到的

new Vue({
  template: `
    <div>
      <p>Obj.a: <input type="text" v-model="obj.a"/></p>
    </div>
  `,
  data: {
    obj: {
      a: '123'
    }
  },
  watch: {
    obj: {
      handler () {
        console.log('obj.a changed')
      },
      immediate: true
      // deep: true
    }
  }
})

通过使用 deep: true 进行深入观察,这时,我们监听 obj,会把 obj 下面的属性层层遍历,都加上监听事件,这样做,性能开销也会变大,只要修改 obj 中任意属性值,都会触发 handler。

如何优化?

在字符串中,写 obj 深入的属性调用,vue 会层层解析,找到 a,并进行监听。

watch: {
    'obj.a': {
      handler () {
        console.log('obj.a changed')
      },
      immediate: true
      // deep: true
    }
  }

注意

不要在 computed 或 watch 中,去修改所依赖的数据的值,尤其是 computed;如果这样做,可能导致一个无线循环的触发。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值