vue 计算属性
模板内的表达式实际上只用于简单的运算, 对于复杂逻辑, 使用计算机属性
基础例子:
- <div id="example">
- <p>
- Original message:"{{message}}"
- </p>
- <p>
- Computed reversed message:"{{reversedMessage}}"
- </p>
- </div>
- var vm = new Vue({
- el: "#example",
- data: {
- message: "Hello"
- },
- computed: { //a computed getter reversedMessage:function(){ //'this' points to the vm instance return this.message.split('').reverse().join('') } }})
这里我们声明了一个计算机属性 reversedMessage, 我们提供的函数将用作属性 vm.reversedMessage 的 getter 计算机缓存 vs Methods
可以通过调用表达式中的 method 来达到同样的效果:
- <p>
- Reversed message:"{{reversedMessage}}"
- </p>
- //in componentmethods:{ reversedMessage:function(){ return this.message.split('').reverse()/join('') }}
可以将同一个函数定义为一个 method 而不是一个计算机属性对于最终的结果, 两种方式确实是相同的然而不同的计算机属性是基于它们的依赖进行缓存的计算属性只有在它的相关依赖发生改变时才会重新求值, 这就意味着只要 message 还没有改变, 多次访问 reversedMessage 计算属性会立即返回之前的计算结果, 而不必再次执行函数下面的计算属性将不再更新, 因为 Date.now() 不是响应式依赖:
- computed: {
- now: function() {
- return Date.now()
- }
- }
只要发生重新渲染, method 调用总会执行该函数 computed 属性 vs watch 属性
- <div id="demo">
- {{fullName}}
- </div>
watch:
- var vm = new Vue({
- el: "#demo",
- data: {
- firstName: "Foo",
- lastName: "Bar",
- fullName: "Foo Bar"
- },
- watch: {
- firstName: function(val) {
- this.fullName = val + '' + this.lastName
- },
- lastName: function(val) {
- this.fullName = this.firstName + '' + val
- }
- }
- })
- computed:
- var vm = new Vue({
- el: '#demo',
- data: {
- firstName: 'Foo',
- lastName: 'Bar'
- },
- computed: {
- fullName: function() {
- return this.firstName + ' ' + this.lastName
- }
- }
- })
计算 setter:
计算属性默认只有 getter, 不过在需要是可以提供一个 setter:
// ...computed: { fullName: { // getter get: function () { return this.firstName + ''+ this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } }}// ...
在运行 vm.fullName = 'John Doe'时, setter 会被调用, vm.firstName 和 vm.lastName 也相应的会被更新观察 watchers
当想要在数据变化相应时, 执行异步操作或开销较大的操作, 这是很有用的
- <div id="watch-example">
- <p>
- Ask a yes/no question:
- <input v-model="question">
- </p>
- <p>
- {{ answer }}
- </p>
- </div>
- <script src="https://unpkg.com/axios@0.12.0/dist/axios.min.js">
- </script>
- <script src="https://unpkg.com/lodash@4.13.1/lodash.min.js">
- </script>
- <script>
- var watchExampleVM = new Vue({
- el: '#watch-example',
- data: {
- question: '',
- answer: 'I cannot give you an answer until you ask a question!'
- },
- watch: {
- // 如果 question 发生改变, 这个函数就会运行
- question: function (newQuestion) {
- this.answer = 'Waiting for you to stop typing...' this.getAnswer() } },
- methods: {
- // _.debounce 是一个通过 lodash 限制操作频率的函数
- // 在这个例子中, 我们希望限制访问 yesno.wtf/api 的频率
- // ajax 请求直到用户输入完毕才会发出
- // 学习更多关于
- _.debounce function (and its cousin
- // _.throttle), 参考: https://lodash.com/docs#debounce
- getAnswer: _.debounce(
- function () {
- var vm = this
- if (this.question.indexOf('?') === -1) {
- vm.answer = 'Questions usually contain a question mark. ;-)' return }
- vm.answer = 'Thinking...'
- axios.get('https://yesno.wtf/api')
- .then(function (response) {
- vm.answer = _.capitalize(response.data.answer)
- })
- .catch(function (error) {
- vm.answer = 'Error! Could not reach the API.' + error }) },
- // 这是我们为用户停止输入等待的毫秒数
- 500 ) }})
- </script>
在这个示例中, 使用 watch 选项允许我们执行异步操作, 限制我们执行该操作的频率, 并在得到最终结果前, 设置中间状态, 这是计算属性无法做到的
来源: http://www.92to.com/bangong/2017/03-30/19688306.html