1.计算属性

虽然插值表达式中可以插入复杂逻辑,但过于臃肿且难以复用,对于复杂逻辑,应使用计算属性。

基础例子:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>

<script>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

计算属性相当于一层缓存,每次都从缓存中取值,只有设计的数据更改后才会重新执行此函数。直接引用,不比写成”reversedMessage()”形式。

1.1 计算属性与方法比较

上面的例子在插值表达式中调用方法同样可以实现,如:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

两者的不同:

  1. 计算属性是响应式的,只要message的值没有改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,相当于缓存,不必再次执行函数;
  2. 相比之下,每次重新渲染调用方法总会重新执行函数,费时费力。但是在不需要缓存的情况下可以使用方法。

1.2 计算属性对象形式

涉及双向绑定时可以用计算属性的对象形式,不常用。
例:

<div id="app">
  
    计算相加: 
    <input type="text" v-model.number="firstCount" /> +
    <input type="text" v-model.number="lastCount" /> 

    <p>
      计算结果: <input type="text" v-model="sum" />
    </p>
    
</div>

<script>
var vm = new Vue({
  el: '#app',
  data: {
    firstCount: null,
    lastCount: null,
  },
  computed: {
   sum: {
          get () {
            if(!this.firstCount && !this.lastCount) {
              return null;
            }
            return this.firstCount + this.lastCount;
          },
          set (val) {
            const avg = val / 2;
            this.firstCount = avg;
            this.lastCount = avg;
          }
        }
    }
})
</script>

2.侦听器watch

<div id="app">
    {{ person }}
    
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      name: 'lushuo',
      age: 18,
      person:''
    
    },
    // created(){
    //   this.age = 23;
    // },
    watch: {
        // 被观察的属性变化,就会执行相应的函数
        // name改变触发name函数,age改变触发age函数
        // 首次刷新页面时不执行,可以配合methods和生命周期函数来实现
        // name (newVal) {
        //   // newVal 是更改后的值
        //   this.person = `姓名:${newVal} 年龄:${this.age}`;
        // },
        // age (newVal) {
        //   this.person = `姓名:${this.name} 年龄:${newVal}`;
        // }
        // watch不仅可以写成函数的形式,还可以写成对象的形式
        // 可以填写其他参数,如immediate:true, 无论有没有数据改变,立即执行
        // 填写immediate后,就不需要配合methods和生命周期函数了
        name: {
          handler (newVal) {
            setTimeout (() => {
              this.person = `姓名:${newVal} 年龄:${this.age}`;
            }, 2000) 
          },
          immediate: true
        },
        age: {
          handler (newVal) {
            setTimeout (() => {
              this.person = `姓名:${this.name} 年龄:${newVal}`;            
            }, 2000)
          },
          immediate: true
        }
      }
  })
</script>

3.总结

3.1 computed和watch的区别

  1. computed不可执行异步,watch可执行异步;
  2. computed可以观察多个数据,watch只观察一个;
  3. computed可以新生成一个数据,直接在视图中渲染;watch不可,他用的是本身存在的数据,data中存在。

3.2 computed和methods的区别

computed有缓存机制,methods无缓存机制。

3.3 数据查找顺序

data > methods > computed


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

vue插值表达式 上一篇
vue生命周期及钩子函数 下一篇