Vue 计算属性和侦听器

计算属性 computed

特性:当他依赖的值发生变化的时候会重新计算其属性,所以对于任何复杂逻辑,你都应当使用计算属性

  • 对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
  • 计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例

示例

  • 比如我们有 firstName 和 lastName 两个变量,我们需要显示完整的名称。
    • 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
    • 所以我们需要把这两个变量合并显示 {{fullName}}
<div id="app">
  <h2>{{firstName}} {{lastName}}</h2>
  <h2>{{fullName}}</h2>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      firstName: 'Kobe',
      lastName: 'Bryant'
    },
    computed: {
      fullName() {
        return this.firstName + ' ' + this.lastName
      }
    }

计算属性的 setter 和 getter

  • 计算属性默认只有 getter,不过在需要时你也可以提供一个 setter
  • get 属性用来获取计算属性(只读)
  • set 属性用来设置计算属性(可写)
<div id="app">
    <h2>{{fullName}}</h2>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        firstName: 'Kobe',
        lastName: 'Bryant'
      },
      computed: {
        fullName: {
          set(newValue) {
            const names = newValue.split(' ')
            this.firstName = names[0]
            this.lastName = names[1]
          },
          get() {
            return this.firstName + ' ' + this.lastName
          }
        }
      },
      mounted() {
        // my boy 会当作参数传给 fullName 的 set 方法
        this.fullName = 'my boy'
      },
    })
  </script>

侦听器

  • 监听 data 的一个值的变化,然后执行相应的函数
    • 函数接收两个参数
      • 第一个是变化后的值
      • 第二个是变化之前的值

示例

<div id="app">
    <input v-model="value" />
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        value: ''
      },
      watch: {
        value(val, oldVal) {
          // do something
        },
      }
    })
  </script>  

立即触发回调

  • watch 最初绑定时是不会执行的
  • 在组件挂载实例的时候触发一次
watch: {
  watch: {
      value: {
        handler(val, oldVal) {
          // do something
        },
        immediate: true // 立即触发回调
      }
    }
}

深度监听

  • 受 JavaScript 的限制,Vue 无法检测到对象属性的变化
<div id="app">
    <input v-model="obj.value" />
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        obj: {
          value: ''
        }
      },
      watch: {
        obj: {
          handler(val, oldVal) {
            // 无法监听对象
          },
          immediate: true
        }
      }
    })
  </script>

deep 属性

watch: {
  obj: {
    handler(val, oldVal) {
      console.log(val.value)
    },
    immediate: true,
    deep: true
  }
}
  • 但我们其实只是需要监听一个对象的一个值,但是在这个对象其它值改变的情况下也会触发
    • 这样性能消耗会非常大
    • 我们可以使用字符串形式监听来进行优化
watch: {
  'obj.value': {
    handler(val, oldVal) {
      console.log(val)
    },
    immediate: true,
    deep: true
  }
}

计算属性VS方法

  • 计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。
  • 所得到的值没有任何的区别
  • 计算属性是基于它们的响应式依赖进行缓存的只在相关响应式依赖发生改变时它们才会重新求值
    • 多次访问 get 计算属性会立即返回之前的计算结果,而不必再次执行函数
  • methods 方法,每当触发重新渲染时,调用方法将总会再次执行函数
  • 对于任何复杂逻辑,你都应当使用计算属性(增强性能)
  computed: {
      fullName() {
        console.log('调用了computed中的fullName');
        return this.firstName + ' ' + this.lastName
      }
    },
    methods: {
      getFullName() {
        console.log('调用了methods中的getFullName');
        return this.firstName + ' ' + this.lastName
      }
    }

计算属性VS侦听属性

  • 计算属性computed代码重复性小,代码更简便
  • 计算属性多对一,侦听属性一对一
  • 侦听属性 可以操作异步
posted @ 2020-03-04 14:10  懒惰ing  阅读(336)  评论(0编辑  收藏  举报