Vue.js-05:第五章 - 计算属性与监听器
一、前言
在 Vue 中,我们可以很方便的将数据使用插值表达式( Mustache 语法)的方式渲染到页面元素中,但是插值表达式的设计初衷是用于简单运算,即我们不应该对差值做过多的操作。当我们需要对差值做进一步的处理时,这时,我们就应该使用到 Vue 中的计算属性来完成这一操作。同时,当差值数据变化时执行异步或开销较大的操作时,我们可以通过采用监听器的方式来达到我们的目的。
学习系列目录地址:https://www.cnblogs.com/danvic712/p/9549100.html
仓储地址:https://github.com/Lanesra712/VueTrial/blob/master/Chapter01-Rookie/watcher.html
二、干货合集
1、计算属性
计算属性,一般是用来描述一个属性值依赖于另一个的属性值,当我们使用插值表达式将计算属性绑定到页面元素上时,计算属性会在依赖的属性值的变化时自动的更新 DOM 元素。例如在下面的代码中,我们在 computed 中,定义了一个 reversedMessage 属性,它可以根据我们的 data 中的 message 属性的变化自动的获取到反转后的 message 的属性值。
<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 中定义一个方法来实现这个需求。原来,计算属性的本质就是一个方法,只不过,我们在使用计算属性的时候,是把计算属性的名称直接当做属性来使用,而并不会把计算属性当做一个方法去调用。
那么,为什么我们还要去使用计算属性而不是去定义一个方法呢?原来,计算属性是基于它们的依赖进行缓存的。即只有在相关依赖发生改变时它们才会重新求值。例如在上面的例子中,只要 message 的属性值没有发生改变,无论任何使用我们使用到 reversedMessage 属性,都会立即返回之前的计算结果,而不必再次执行函数。
反之,如果你使用方法的形式实现,当你使用到 reversedMessage 方法时,无论 message 属性是否发生了改变,方法都会重新执行一次,这无形中增加了系统的开销。当然,你也可以自己在方法中实现根据依赖进行缓存,嗯,如果你不嫌烦的话。。。
在上面的案例中,对于 reversedMessage 这个计算属性来说,我们主要的目的是为了获取属性的值,即使用的是计算属性的 getter 方法。不过,如果你需要使用到计算属性的 setter 方法时,我们也是可以为计算属性提供一个 setter 方法的。
<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。

2、监听属性
在 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>

三、总结
1、计算属性的结果会被缓存起来,只有依赖的属性发生变化时才会重新计算,必须返回一个数据,主要用来进行纯数据的操作。
2、监听器主要用来监听某个数据的变化,从而去执行某些具体的回调业务逻辑,不仅仅局限于返回数据。
四、参考
2、Vue 2.0学习笔记: Vue中的computed属性
Vue.js-05:第五章 - 计算属性与监听器的更多相关文章
- vue.js基础知识篇(3):计算属性、表单控件绑定
第四章:计算属性 为了避免过多的逻辑造成模板的臃肿不堪,可使用计算属性来简化逻辑. 1.什么是计算属性 <!DOCTYPE html><html lang="en" ...
- Vue.js基本规则提炼总结及计算属性学习
Vue.js基本须知: 1)以“{{}}”格式 “Mustache” 语法(双大括号)来绑定表达式输出文本值; 2)以“{{{}}}”格式绑定原始的html,绑定的表达式内为字符串格式的html内容, ...
- VUE -- Vue.js每天必学之计算属性computed与$watch
在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作.模板是为了描述视图的结构.在模板中放入太多的逻辑会让模板过重且难以维护.这就是为什么 Vue.js 将绑定表达式限制为一个表达式.如果需 ...
- Vue.js-----轻量高效的MVVM框架(五、计算属性)
#基础例子 <div id="dr01"> <h4>#基础例子</h4> <div> num01={{num01}}, num02= ...
- 读JS高级——第五章-引用类型 _记录
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- vue 计算属性和监听器
一.计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div> {{ message.split('').rev ...
- Vue.js 学习笔记 第3章 计算属性
本篇目录: 3.1 什么是计算属性 3.2 计算属性用法 3.3 计算属性缓存 模板内容的表达式常用语简单的运算,当其过长或逻辑复杂时,会难以维护,本章的计算属性就是用于解决该问题的. 3.1 什么是 ...
- Vue基础第三章 - 计算属性
1.计算属性介绍 在第二章中我们介绍了在Vue的{{}}中可以使用一些简单的表达式进行计算,但是当表达式过长或者逻辑过于复杂就会变得不易理解和维护,比如第二章的示例{{ text.split(',') ...
- 非node环境下的vue.js 实现简单的购物车计算功能 样式请无视
都说vue的双向数据绑定好用,自己用了下,感觉做购物车没想象中好用.自己的实现如下: <!DOCTYPE html> <html lang="en"> &l ...
随机推荐
- WIN10怎么安装SQL server2000数据库
怎样在win10下安装sql2000数据库 1.安装之前先确认自己的Windows10是64位的还是32位的 2.替换对应的系统文件SQLUNIRL.dll 此时你可能会遇到,没有权限替换文件或重命名 ...
- Selenium 三种等待
问题 : 强制等待和隐式等待的区别怎么理解? 和pause有什么区别?什么时候适用pause? 第二篇文章更清楚一点. 以下内容引自: https://www.cnblogs.com/xu-jia-l ...
- 电脑开机出现“致命错误C0000034。。。”--该怎么办?
win7或win8系统的电脑在开机时出现了 "致命错误C0000034 正在更新操作236,共156764个0000000000000000.cdf-ms "的提示并不能正常启动系 ...
- 连续查询(Continuous Queries)
当数据超过保存策略里指定的时间之后,就会被删除.如果我们不想完全删除掉,比如做一个数据统计采样:把原先每秒的数据,存为每小时的数据,让数据占用的空间大大减少(以降低精度为代价). 这就需要Influx ...
- MFC学习笔记_关于CSpinButtonCtrl
CSpinButtonCtrl使用起来比较特殊,使用起来,需要注意一些地方.实际的教程也比较少.为了让后人少走弯路,这里写这篇文章以说明.1.添加EDIT控件2.添加Spin控件如果不是这样的顺序的话 ...
- 【构造】UVa 11387 The 3-Regular Graph
Description 输入n,构造一个n个点的无向图,使得每个点的度数都为3.不能有重边和自环,输出图或确定无解. Solution 如果n为奇数,奇数*3=奇数,度数为奇,必无解. 考虑我们怎么构 ...
- laravel5.4 后台RBAC功能完成中遇到的问题及解决方法
1.在后台模块中有些公共的地方 比如头部 尾部 左侧菜单栏; 在laravel中通过继承模板来实现,但是在做RBAC的时候 需求是:不同的登陆用户显示不同的菜单;去数据库获取这些数据 但是每个界面都要 ...
- python+appium 查找某个元素find_element()并click()点击,正向判断与反判断的方法封装
使用场景: 在自动化测试过程中,难免会用到反判断,包括异常情况的处理,比如:find_element_by_name('测试') 判断"测试"是否存在,存在则点击,不存在则执行其他 ...
- UWP中实现大爆炸效果(一)
自从老罗搞出大爆炸之后,各家安卓都内置了类似功能.UWP怎么能落下呢,在这里我们就一起撸一个简单的大爆炸实现. 闲话不说,先上效果: 因为代码太多,所以我打算写成一个系列,下面是第一篇的正文: 首先, ...
- Spring事务的一些特性
事务的四大特征 1.原子性:一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做要么全不做 2.一致性:数据不会因为事务的执行而遭到破坏 3.隔离性:一个事物的执行,不受其他事务的干扰,即并 ...