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] https://segmentfault.com/a/1190000016593017
[2] https://www.jianshu.com/p/6f433b39fb8a