vue.js.2.0 icon indicating copy to clipboard operation
vue.js.2.0 copied to clipboard

【vue】计算属性与观察者(watch/computed)

Open Kelichao opened this issue 8 years ago • 9 comments

计算属性computed

作用一:解决模板上逻辑过多的问题

不推荐在模板上写太多逻辑,会显得模板过于繁琐

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>
  • 例子
<div id="example">
  <p>我是原信息: "{{ message }}"</p>
  <p>我是处理后的信息: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    // 源数据
    message: 'Hello'
  },
// 处理后的数据存放点
  computed: {
    reversedMessage: function () {
      return this.message.split('').reverse().join('')
    }
  }
});

作用二:属性缓存

计算属性与普通方法的区别是:如果该计算属性所包含的data没有发生变化,是不会去改变它的输出值,因此如果该计算属性与new Date()关联,则并不会实时变化,而普通方法则会根据时间实时变化的。

<p>Reversed message: "{{ reverseMessage() }}"</p>
// in component
methods: {
  reverseMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

计算属性 vs 被观察的属性

  • 对比

$watch方法用于监听data值改变,以下代码是监听方式实现全名的赋值。

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar',
    obj: {
        aaa:123
    }
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    },
    // watch还可以以字符串形式,监听对象内部属性的变化,非常实用
    "obj.aaa":function (val) {
     
    }
  }
});

属性计算能够更加高效地解决问题。

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

计算属性的setter方法

// ...
computed: {
  fullName: {
    // getter 这个是默认方法,不写get或者set的时候触发这个方法
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
     console.log(123);
    }
  }
}
// ...
vm.fullName = 'John Doe'// 控制台输出123

观察watchers

(与计算属性相比,watchers作用不仅仅是属性的计算过滤,应理解为事件的触发载体,用于事件的监听)

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的 watcher 。这是为什么 Vue 提供一个更通用的方法通过 watch 选项,来响应数据的变化。当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。

使用 watch 选项允许我们执行异步操作(访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这是计算属性无法做到的。

总结

  • 个人感觉component与watch在一定条件下可以互相代替。
  1. watch处理比较复杂的事件或者大逻辑比较合适。
  2. 而component适合处理一些数据格式,比如时间格式的转换,字符串的截取等等。_

Kelichao avatar Feb 01 '17 14:02 Kelichao

情况一: 当 input 输入值发生变化时 question 跟着变化,触发 computed 重新计算,console.log 日志打出

<input v-model="question">
<p>{{ fullName }}</p> 
data: {
    question: ''
  },
computed: {
    fullName: function () {
       console.log(this.question)
    }
  },

情况二: 注释掉 fullName 计算属性的调用, input 输入值发生变化时 question 跟着变化,但 computed 下的 fullName 不再 console.log ,这改如何解释呢? 而 watch 下的 question 可以console.log打出

<input v-model="question">
<!-- <p>{{ fullName }}</p> -->
data: {
    question: ''
  },
computed: {
    fullName: function () {
       console.log(this.question)
    }
  },
watch: {
    question: function (val) {
       console.log(val)
    }
  }

ZengTianShengZ avatar Nov 23 '17 07:11 ZengTianShengZ

@ZengTianShengZ 计算属性 默认只是属性的getter,只有在你调用的时候他才会执行,而watch相当于回调,只要观察的属性一变动,就会执行这个方法

jsm1003 avatar Dec 31 '17 09:12 jsm1003

我是来学习的

mhxy13867806343 avatar Feb 08 '18 09:02 mhxy13867806343

我是来学习的

Shangyunliang avatar Feb 23 '18 02:02 Shangyunliang

我是来学习的

sealzrt avatar Feb 28 '18 11:02 sealzrt

@ZengTianShengZ 我是觉得vue计算属性里面是会有一个属性维护关系的(写在其内部的数据源才生效),在你说的情况二中, 注释掉 fullName 计算属性的调用等于切断了该计算属性(fullName)与question之间的关联,自然改变question的值不会引起fullName的变化

Kelichao avatar Mar 12 '18 02:03 Kelichao

照着官网抄有意吗

marksa avatar May 03 '18 03:05 marksa

我是来学习的

mhxy13867806343 avatar Jun 08 '18 04:06 mhxy13867806343

照着官网抄有意吗

我这是做总结,做过筛选了,只是一部分示例懒的改代码,不利于自己理解的东西就不会抄过来。

@marksa

Kelichao avatar Oct 11 '18 03:10 Kelichao