计算property and 监听property

深入LearningVue.js 计算property and 监听property, understanding它们 using场景 and best practices

1. 计算property (Computed)

计算property is 基于它们 response式依赖forcache property. 只 has 当依赖 data发生变化时, 计算property才会重 new 计算.

var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!',
        firstName: 'John',
        lastName: 'Doe'
    },
    computed: {
        // 计算property getter
        reversedMessage: function() {
            return this.message.split('').reverse().join('');
        },
        // 完整 getter and setter
        fullName: {
            get: function() {
                return this.firstName + ' ' + this.lastName;
            },
            set: function(newValue) {
                var names = newValue.split(' ');
                this.firstName = names[0];
                this.lastName = names[names.length - 1];
            }
        }
    }
});

1.1 计算property 特点

  • cachemechanism: 只 has 当依赖 data发生变化时, 计算property才会重 new 计算, 否则直接返回cache 结果.
  • response式: 计算property会自动追踪它所依赖 response式data.
  • 简化模板: 将 complex 计算逻辑 from 模板in抽离出来, 使模板更简洁.
  • readable 写: 可以同时定义getter and setter, 使其成 for readable 写 property.

1.2 计算property vs method

计算property and method都可以implementation相同 functions, 但它们 has 以 under 区别:

var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!'
    },
    computed: {
        // 计算property: 会cache结果
        reversedMessage: function() {
            console.log('Computed property called');
            return this.message.split('').reverse().join('');
        }
    },
    methods: {
        // method: 每次调用都会重 new 执行
        reverseMessage: function() {
            console.log('Method called');
            return this.message.split('').reverse().join('');
        }
    }
});

提示

such as果需要一个不会cache 计算结果, 应该usingmethod而不 is 计算property.

2. 监听property (Watch)

监听property用于观察 and responseVueinstance on data变化. 当被监听 data发生变化时, 会触发 for 应 processingfunction.

var app = new Vue({
    el: '#app',
    data: {
        firstName: 'John',
        lastName: 'Doe',
        fullName: 'John Doe'
    },
    watch: {
        // 监听firstName变化
        firstName: function(newVal, oldVal) {
            this.fullName = newVal + ' ' + this.lastName;
        },
        // 监听lastName变化
        lastName: function(newVal, oldVal) {
            this.fullName = this.firstName + ' ' + newVal;
        },
        // 深度监听object变化
        user: {
            handler: function(newVal, oldVal) {
                console.log('User object changed');
            },
            deep: true
        },
        // 立即执行
        message: {
            handler: function(newVal, oldVal) {
                console.log('Message changed to: ' + newVal);
            },
            immediate: true
        }
    }
});

2.1 监听property 选项

  • handler: data变化时调用 callbackfunction, 可以接收 new 值 and old 值两个parameter.
  • deep: is 否深度监听object in 部property 变化, 默认 for false.
  • immediate: is 否 in 监听开始时立即执行handlerfunction, 默认 for false.

2.2 监听property using场景

  • 当需要 in data变化时执行asynchronous or 开销较 big operation.
  • 当需要监听object in 部 变化.
  • 当需要根据data变化执行一系列 complex 逻辑.
  • 当需要 in data变化时 and out 部systemfor交互.

3. 计算property and 监听property 区别

features 计算property (Computed) 监听property (Watch)
cachemechanism has , 依赖不变时直接返回cache结果 无, data变化时总 is 执行
using场景 模板渲染in complex 计算 asynchronousoperation or complex 逻辑
语法 更简洁, 声明式 commands式, 需要显式定义
return value 必须 has return value 可以没 has return value
深度监听 自动深度依赖追踪 需要显式设置deep: true

4. best practices

4.1 what时候using计算property?

  • 当需要 from 现 has datafork new data时.
  • 当模板in需要 complex 计算逻辑时.
  • 当计算结果需要被 many 次using时 (利用cache) .

4.2 what时候using监听property?

  • 当需要 in data变化时执行asynchronousoperation (such asAPIrequest) .
  • 当需要 in data变化时执行开销较 big operation.
  • 当需要监听object in 部 变化.
  • 当需要根据data变化执行一系列 complex 逻辑.

4.3 避免滥用监听property

虽然监听property很强 big , 但过度using会导致code难以maintenance. 以 under is 一些需要避免 circumstances:

  • 不要用监听property来synchronization many 个data, 应该using计算property.
  • 不要 in 监听propertyin执行过于 complex synchronization逻辑, 应该考虑refactor for 计算property.
  • 不要监听太 many property, 应该考虑 is 否 has 更 good design模式.

练习 1: 计算property using

  1. creation一个Vueinstance, package含以 under data:
    • 商品价格 (price)
    • 商品数量 (quantity)
    • 折扣率 (discountRate)
  2. using计算property计算:
    • 商品总价 (totalPrice = price * quantity)
    • 折扣金额 (discount = totalPrice * discountRate)
    • practical支付金额 (finalPrice = totalPrice - discount)
  3. in 页面 on 显示所 has data, including计算结果.
  4. modify商品价格, 数量 or 折扣率, 观察计算property 变化.

练习 2: 监听property using

  1. creation一个Vueinstance, package含一个搜索关键词 (keyword) and 搜索结果 (results) .
  2. usingwatch监听搜索关键词 变化, 当关键词变化时:
    • 显示"正 in 搜索..."提示
    • usingsetTimeoutmockasynchronousAPIrequest, latency1秒 after 返回搜索结果
    • update搜索结果并隐藏"正 in 搜索..."提示
  3. 添加防抖functions, 只 has 当user停止输入300毫秒 after 才执行搜索.
  4. in 页面 on 显示搜索输入框, 搜索status and 搜索结果.

练习 3: 计算property and 监听property 综合application

  1. creation一个Vueinstance, mock一个购物车:
    • 商品list (package含id, name, price, quantity字段)
    • 选in 商品 (selectedItems)
    • 购物车总价 (totalPrice)
  2. usingv-for渲染商品list, 每个商品package含:
    • 商品名称 and 价格
    • 数量输入框
    • 选in checkbox
  3. using计算property计算:
    • 选in商品 总价 (totalPrice)
    • 选in商品 数量 (selectedCount)
  4. usingwatch监听选in商品 变化, 当选in商品数量超过5个时, 显示提示information.
  5. implementation"select all" and "全不选"functions.