上一文简单介绍了vue的结构和一些核心概念,本文接着介绍计算属性、侦听器、过滤器以及生命周期函数。
上一篇链接:
VUE简单入门(一)
计算属性
我们继续从简单的vue应用入手,如果我们需要在模板中放入很多逻辑,那么模板就会足够复杂且难以维护,如下图:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
为了解决这个问题,对于任何复杂的逻辑,都应当使用计算属性:computed
看下图这个栗子:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
在这里我们就声明了一个计算属性 reversedMessage,把复杂的计算逻放在 reversedMessage里了。这里有几点概念需要拓展说明一下:
- 每一个计算属性都包含一个getter 和一个setter ,我们上面的示例都是计算属性的默认用法,只是利用了getter 来读取(当然,getter也是最常用的)
- 计算属性是基于它们的依赖进行缓存的。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。(这里多学一个methods方法,方法methods类似computed,不同的是每当触发重新渲染时,调用methods方法总会再次执行函数)
- 注意computed里面的this,指向的是vm实例,我们在计算属性computed里不应该使用箭头函数来定义计算属性,因为箭头函数会绑定父级作用域的上下文,所以 this 将不会按照期望指向Vue
参考文献:
https://www.cnblogs.com/8023-CHD/p/11166151.html
https://cn.vuejs.org/v2/guide/computed.html
侦听器watch
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。首先说说什么应用场景适合watch:
- 使用watch来响应数据的变化,一般用于异步或者开销较大的操作
- watch 中的属性一定是data中已经存在的数据
- 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听(这部分可以看拓展阅读内容)
拓展阅读
https://blog.csdn.net/qq_36688143/article/details/81287535
watch举栗说明
<div id="app">
<div>
<span>名:</span>
<span>
<input type="text" v-model='firstName'>
</span>
</div>
<div>
<span>姓:</span>
<span>
<input type="text" v-model='lastName'>
</span>
</div>
<div>{{fullName}}</div>
</div>
<script type="text/javascript">
/*侦听器*/
var vm = new Vue({
el: '#app',
data: {
firstName: 'Jim',
lastName: 'Green',
// fullName: 'Jim Green'
},
//watch属性定义和data和methods平级
watch: {
// 注意:这里 firstName 对应着 data 中的 firstName
// 当 firstName 值改变的时候会自动触发 watch
firstName: function(val) {
this.fullName = val + ' ' + this.lastName;
},
// 注意:这里lastName 对应着 data 中的 lastName
lastName: function(val) {
this.fullName = this.firstName + ' ' + val;
}
}
});
</script>
过滤器filters
接着我们说过滤器,过滤器的本质是一个有参数,有返回值的方法。Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
栗子一:普通用法,用在{{}} 和 在v-bind
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
// 输入内容首字母大写
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
栗子二:支持级联操作
栗子三:过滤器中传递参数
<div id="box">
<!--
filterA 被定义为接收三个参数的过滤器函数。
其中 message 的值作为第一个参数,
普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。
-->
{{ message | filterA('arg1', 'arg2') }}
</div>
<script>
// 在过滤器中 第一个参数 对应的是 管道符前面的数据n此时对应 message
// 第2个参数 a 对应 实参 arg1 字符串
// 第3个参数 b 对应 实参 arg2 字符串
Vue.filter('filterA',function(n,a,b){
if(n<10){
return n+a;
}else{
return n+b;
}
});
new Vue({
el:"#box",
data:{
message: "哈哈哈"
}
})
</script>
注意两点:
- 过滤器不改变真正的data,而只是改变渲染的结果,并返回过滤后的版本
- 全局注册时是filter,没有s的。而局部过滤器是filters,是有s的(全局和局部后面我们会细说)
总结一下 computed、watch、filter
computed | watch | filter |
---|---|---|
有返回值 | 不需要返回值、通常是改变值 | 有返回值 |
不可以传参 | 有参数 | 有多个参数 |
有缓存 | 无缓存 | 无缓存 |
可以访问this | 可以访问this | 可以全局/局部定义 |
一般是需要针对多个数据进行操作 | 多用于异步 | 多用于数据格式化 |
生命周期(勾子函数)
之所以把生命周期归到一起说,一个原因是生命周期和computed、watch在一个层级,另外一方面是理解生命周期有助于理解这几个常用的API的执行顺序。
Vue实例从创建 、运行到销毁的过程 ,这些过程中会伴随着一些函数的自调用。我们称这些函数为钩子函数。
周期函数 | 对应场景 |
---|---|
beforeCreate | 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了 |
created | 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来 |
beforeMount | 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已 |
mounted | el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件 |
beforeUpdate | 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的 |
updated | 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的 |
beforeDestroy | 实例销毁之前调用 |
destroyed | 实例销毁后调用 |
这里有个非常详细的过程说明,文件来源:
https://blog.csdn.net/mqingo/article/details/86031260