「Vue学习记录五」计算属性和侦听器

314 阅读4分钟

1: 计算属性: (内置缓存机制)

当更改age的时候, fullName 函数不执行;

当更改fristName的时候, fullName 函数才执行

<div id = "app">
    <span>{{fullName}}</span> 
    <span>{{age}}</span>
</div>

<script>
    var vm = new Vue({
        el : "#app",
        data: {
            fristName : "Christine",
            lastName : "Gao",
            age : "26"
        },
        // “计算属性” 实现:  具有缓存机制, 即改变年龄的时候, 执行 fullName 函数
        computed : {
            fullName : function () {
                console.log("计算了一次");
                return this.fristName + " " + this.lastName;
            }
        }
    })

</script>

效果如下:

get和set用法

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

<div id="app">
    <span>{{fullName}}</span>
    <span>{{age}}</span>
</div>

<script>
    var vm = new Vue({
        el: "#app",
       data: {
            firstName: 'Foo',
            lastName: 'Bar',
            age:'26',
        },
        computed: {
            fullName:{
            get() {//回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值
            console.log(this.firstName + ' ' + this.lastName)
            return this.firstName + ' ' + this.lastName
        },
        set(val) {//监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据
            //val就是fullName的最新属性值
            console.log(val)
            const names = val.split(' ');
            console.log(names)
            this.firstName = names[0];
            this.lastName = names[1];
        }
    }
  }
    })

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。

效果如下

2、方法: (无内置缓存)

当更改age的时候, fullName 函数执行, 这样就增加了代码冗余,浏览器运行性能降低;

当更改fristName的时候, fullName 函数仍执行。

<div id = "app">
    <span>{{fullName()}}</span>
    <span>{{age}}</span>
</div>

<script>

    var vm = new Vue({
        el : "#app",
        data: {
            fristName : "Christine",
            lastName : "Gao",
            age : "26"
        },
    
        // “方法” 实现 : 改变年龄的时候, 也会执行 fullName 函数
        methods : {
            fullName : function () {
                console.log("用方法,计算了一次")
                return  this.fristName + " " + this.lastName;
            }
        }
    })

</script>

效果如下:

3、侦听器: (有内置缓存)

跟“计算属性”相似, 但是代码相较于“计算属性”而言, 比较繁琐且冗余。

  <div id = "app">
    <span>{{fullName}}</span>
    <span>{{age}}</span>
</div>
<script>

    var vm = new Vue({
        el : "#app",
        data: {
            fristName : "Christine",
            lastName : "Gao",
            fullName : "Christine Gao",
            age : "26"
        },
        // “侦听” 实现 :实现了缓存, 但是代码冗余。
        watch : {
            firstName : function () {
                console.log("侦听实现 , 计算了一次");
                this.fullName = this.fristName + " " + this.lastName;
            },
            lastName : function () {
                console.log("侦听实现 , 计算了一次");
                this.fullName = this.fristName + " " + this.lastName;
            }
        }
    })

</script>

效果如下:

监听 基础用法

放在 data 中的对象,一旦发生改变就会执行相应的操作,当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的

<div id="app">
    <p>FullName: {{fullName}}</p>
    <p>FirstName: <input type="text" v-model="firstName"></p>
</div>

<script>
    var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Joy',
                lastName: 'lqy',
                fullName: ''
            },
            watch: {
                firstName(newName, oldName) {
                    this.fullName = newName + ' ' + this.lastName;
                }
            }
        })
</script>

watch 中的对象在 data 中已经定义了,当我们输入firstName后, watch监听每次修改变化的新值,然后计算输出fullName。也就是上面的代码中,fullName 一开始被渲染出来的时候是空值,如下所示:

监听 高级用法

handler方法和immediate属性

如上所述,一开始被渲染出来的时候,fullName是空值,如果想要一开始就让最初绑定的值执行该怎么办尼?别急,我们只需要给firstName绑定一个handler方法,之前我们写的watch方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就只这个handler,设置immediate:true代表如果在 wacth 里声明了 firstName 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行

修改后的代码如下:

<div id="app">
    <p>FullName: {{fullName}}</p>
    <p>FirstName: <input type="text" v-model="firstName"></p>
</div>

<script>
    var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Joy',
                lastName: 'lqy',
                fullName: ''
            },
            watch: {
            firstName: {
                handler(newName, oldName) {
                    this.fullName = newName + ' ' + this.lastName;
                },
                // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
                immediate: true
            }
        }
        })
</script>

deep属性

deep,默认值为false,代表是否深度监听,

总的来说,计算属性倾向于格式化/处理当前的数据,而 watch 倾向于执行数据变化需要进行的操作

参考资料

[1] segmentfault.com/a/119000001…

[2] www.jianshu.com/p/6f433b39f…