[Vue 牛刀小试]:第五章 - 计算属性与监听器

 1、前言

  在 Vue 中,咱们能够很方便的将数据使用插值表达式( Mustache 语法)的方式渲染到页面元素中,可是插值表达式的设计初衷是用于简单运算,即咱们不该该对差值作过多的操做。当咱们须要对差值作进一步的处理时,这时,咱们就应该使用到 Vue 中的计算属性来完成这一操做。同时,当差值数据变化时执行异步或开销较大的操做时,咱们能够经过采用监听器的方式来达到咱们的目的。html

  学习系列目录地址:http://www.javashuo.com/article/p-bzzucmub-ba.htmlvue

  仓储地址:https://github.com/Lanesra712/VueTrial/blob/master/Chapter01-Rookie/watcher.htmlgit

 2、干货合集

  一、计算属性

  计算属性,通常是用来描述一个属性值依赖于另外一个的属性值,当咱们使用插值表达式将计算属性绑定到页面元素上时,计算属性会在依赖的属性值的变化时自动的更新 DOM 元素。例如在下面的代码中,咱们在 computed 中,定义了一个 reversedMessage 属性,它能够根据咱们的 data 中的 message 属性的变化自动的获取到反转后的 message 的属性值。github

<div id="app">
    输入的值:<input type="text" v-model="message"><br />
    反转的值:{{reversedMessage}}
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: ''
        },
        computed: {
            reversedMessage: function () {
                //这里的 this 指向 当前的 vm 实例
                return this.message.split('').reverse().join('')
            }
        },
        methods: {}
    })
</script>

  

  可能你会发觉,这里的写法和咱们定义方法时很类似,咱们彻底也能够在 methods 中定义一个方法来实现这个需求。原来,计算属性的本质就是一个方法,只不过,咱们在使用计算属性的时候,是把计算属性的名称直接当作属性来使用,而并不会把计算属性当作一个方法去调用。segmentfault

  那么,为何咱们还要去使用计算属性而不是去定义一个方法呢?原来,计算属性是基于它们的依赖进行缓存的。即只有在相关依赖发生改变时它们才会从新求值。例如在上面的例子中,只要 message 的属性值没有发生改变,不管任何使用咱们使用到 reversedMessage 属性,都会当即返回以前的计算结果,而没必要再次执行函数。数组

  反之,若是你使用方法的形式实现,当你使用到 reversedMessage 方法时,不管 message 属性是否发生了改变,方法都会从新执行一次,这无形中增长了系统的开销。固然,你也能够本身在方法中实现根据依赖进行缓存,嗯,若是你不嫌烦的话。。。缓存

  在上面的案例中,对于 reversedMessage 这个计算属性来讲,咱们主要的目的是为了获取属性的值,即便用的是计算属性的 getter 方法。不过,若是你须要使用到计算属性的 setter 方法时,咱们也是能够为计算属性提供一个 setter 方法的。app

<div id="app">
    输入的值:<input type="text" v-model="message"><br />
    反转的值:{{reversedMessage}}
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: ''
        },
        computed: {
            reversedMessage: {
                get: function () {
                    return this.message.split('').reverse().join('')
                },
                set: function (value) {
                    this.message = value.split('').reverse().join('')
                }
            }
        },
        methods: {}
    })
</script>

  在上面的代码中,咱们为计算属性 reversedMessage 增长了一个 setter 方法:经过设置 reversedMessage 的值,一样进行反转操做,并最终将结果赋值给属性 message。异步

  二、监听属性

  在 vue 中,咱们不光可使用计算属性的方式来监听数据的变化,还可使用 watch 监听器的方法来监测某个数据发生的变化。不一样的是,计算属性仅仅是对于依赖数据的变化后进行的数据操做,而 watch 更加侧重于对于监测中的某个数据发生变化后所执行的一系列的业务逻辑操做。函数

  监听器以 key-value 的形式定义,key 是一个字符串,它是须要被监测的对象,而 value 则能够是字符串(方法的名称)、函数(能够获取到监听对象改变前的值以及更新后的值)或是一个对象(对象内能够包含回调函数的其它选项,例如是否初始化时执行监听 immediate,或是是否执行深度遍历 deep,便是否对对象内部的属性进行监听)。

  1)回调值为函数方法

  在下面的例子中,咱们监听了 message 属性的变化,根据属性的变化后执行了回调方法,打印出了属性变化先后的值。

<div id="app">
    输入的值:<input type="text" v-model="message">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: ''
        },
        computed: {},
        watch: {
            //回调为未建立的方法
            'message': function (newValue, oldValue) {
                console.log(`新值:${newValue} --------- 旧值:${oldValue}`)
            }
        },
        methods: {}
    })
</script>

  一样的,咱们能够经过方法名称指明回调为已经定义好的方法。

<div id="app">
    输入的值:<input type="text" v-model="message">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: ''
        },
        computed: {},
        watch: {
            //回调为已建立好的方法
            'message': 'recording'
        },
        methods: {
            recording: function (newValue, oldValue) {
                console.log(`method记录:新值:${newValue} --------- 旧值:${oldValue}`)
            }
        }
    })
</script>

  2)回调值为对象

  当咱们监听的回调值为一个对象时,咱们不只能够设置回调函数,还能够设置一些回调的属性。例如,在下面的例子中,咱们监听了 User 这个对象,同时执行了执行深度遍历,这时,当咱们监听到 User.name 这个属性发生改变的时候,咱们就能够执行咱们的回调函数。注意,深度遍历默认为 false,当不启用深度遍历时,咱们是没法监听到对象的内部属性的变化的。

<div id="app">
    用户姓名:<input type="text" v-model="User.name">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: '',
            User: {
                name: 'zhangsan',
                gender: 'male'
            }
        },
        computed: {},
        watch: {
            //回调为对象
            'User': {
                handler: function (newValue, oldValue) {
                    console.log(`对象记录:新值:${newValue.name} --------- 旧值:${oldValue.name}`)
                },
                deep: true
            }
        },
        methods: {}
    })
</script>

  可能你发现了,为何 newValue 与 oldValue 都是同样的啊?原来,当咱们监听的数据为对象或数组时,newValue 和 oldValue 是相等的,由于对象和数组都为引用类型,这两个的形参指向的也是同一个数据对象。同时,若是咱们不启用深度遍历,咱们将没法监听到对于 User 对象中 name 属性的变化。

<div id="app">
    用户姓名:<input type="text" v-model="User.name">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: '',
            User: {
                name: 'zhangsan',
                gender: 'male'
            }
        },
        computed: {},
        watch: {
            //回调为对象
            'User': {
                handler: function (newValue, oldValue) {
                    console.log(`对象记录:新值:${newValue.name} --------- 旧值:${oldValue.name}`)
                },
                deep: false
            }
        },
        methods: {}
    })
</script>

 3、总结

  一、计算属性的结果会被缓存起来,只有依赖的属性发生变化时才会从新计算,必须返回一个数据,主要用来进行纯数据的操做。

  二、监听器主要用来监听某个数据的变化,从而去执行某些具体的回调业务逻辑,不只仅局限于返回数据。

 4、参考

  一、深刻理解 Vue Computed 计算属性

  二、Vue 2.0学习笔记: Vue中的computed属性

  三、Vue系列之computed使用详解

相关文章
相关标签/搜索