Vue.js学习过程记录——计算属性和监听器(第二天)####
前言:今天主要学习的是Vue.js中计算属性和监听器相关的内容,通过对它们基础的语法和实现过程以及使用中需要注意的地方进行记录,还会通过实现一些小需求来进一步了解,其实在后面的项目当中计算属性和监听器的使用会有很大的区别,话不多说,上代码!
1.计算属性和监听器
1.1计算属性:computed
(1)computed选项定义计算属性;
(2)计算属性类似于methods选项中定义的函数;
(3)计算属性会进行缓存,只在相关响应式以来发生改变时他们才会重新求值;
(4)函数每次都会执行函数体进行计算
下面通过一个需求来进一步了解methods和computed的区别:
需求:输入语文、数学和英语分数,,采用methods和computed分别计算出总得分;
html代码:
<div id="app">
语文:<input type="text" v-model="chineseScore">
数学:<input type="text" v-model="mathScore">
英语:<input type="text" v-model="englishScore"><br>
<!-- 通过methods实现总分计算,注意千万不能忘了sumScore后面的小括号 -->
总分(函数-单向):<input type="text" v-model="sumScore()"><br>
<!-- 绑定计算属性,sumScore后面不需要加小括号 -->
总分(计算属性-单向):<input type="text" v-model="sumScore1">
</div>
js代码:
var vm = new Vue({
el: '#app',
data: {
chineseScore:70,
mathScore:80,
englishScore:90,
},
methods:{
sumScore:function(){
// 在控制台输入vm.sumScore()每次都会被调用,因为不会进行缓存
console.info("函数sumScore被调用了!");
// this指向的是当前vm实例,减0是为了字符串转为数字运算
return (this.chineseScore-0)+(this.mathScore-0)+(this.englishScore-0);
}
},
computed: { //计算属性
sumScore1:function(){
// 在控制台输入vm.sumScore1不会被重新调用,说明计算机有缓存
console.info("sumScore1被调用了!");
return (this.chineseScore-0)+(this.mathScore-0)+(this.englishScore-0);
}
},
})
结果显示效果图:
注意:computed选项内的计算属性默认是getter函数,所以上面只支持单向绑定,也就是说改变总分,竖纹数学英语的分数并不会改变,而修改语文数学英语任一个分数,总分都会更新!!!
1.2计算属性(双向绑定)
(1)上面说到计算属性默认只有getter函数,如果要实现双向绑定,就必须要 自己设置setter函数;
具体实现代码如下:
html代码:
总分(计算属性-双向):<input type="text" v-model="sumScore2">
js代码:
// 指定getter/setter实现双向绑定
sumScore2:{
// 获取数据
get:function(){
console.info("sumScore2的getter函数被调用了!");
return (this.chineseScore-0)+(this.mathScore-0)+(this.englishScore-0);
},
// 设置数据
set:function(newValue){
console.info("sumScore2的setter函数被调用了!");
var avgScore = newValue / 3;
this.chineseScore = avgScore;
this.mathScore = avgScore;
this.englishScore = avgScore;
}
}
结果显示效果图:
1.3监听器:watch
(1)当属性数据发生变化时,对应属性的回调函数会自动调用,在函数内部进行计算;
(2)通过watch选项或者watch()来监听指定的属性;需求:1.通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3;2.通过vm.watch()来监听指定的属性;
需求:
1.通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3;
2.通过vm.watch()来监听指定的属性;需求:1.通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3;2.通过vm.watch()选项监听英语分数,当英语分数更新后回调函数中重新计算总分sumScore3;
注意:使用监听器需要在data选择中添加一个sumScore3属性
主要代码如下:
html代码:
<!-- 通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3; -->
总分(监听器):<input type="text" v-model="sumScore3">
js代码:
data: {
chineseScore:70,
mathScore:80,
englishScore:90,
sumScore3:240,
},
computed: {
// 监听方式1:通过watch选项实现监听
// 通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3;
watch: {
chineseScore:function(newValue,oldValue){
// newValue是更新后的语文分数,oldValue是更新前的语文分数
console.info("watch监听到语文分数被改变了!");
this.sumScore3 = (newValue-0)+(this.mathScore-0)+(this.englishScore);
},
mathScore:function(newValue,oldValue){
console.info("watch监听到数学分数被改变了!");
this.sumScore3 = (this.chineseScore-0)+(newValue-0)+(this.englishScore-0);
}
},
// 监听方式2:通过vm实例进行调用——vm.$watch()
// 通过vm.$watch()选项监听英语分数,当英语分数更新后回调函数中重新计算总分sumScore3;
// 第一个参数是监听的属性名,第二个参数是回调函数
vm.$watch("englishScore",function(newValue){
// newValue是更新后的英语分数
console.info("watch监听到英语分数被改变!");
this.sumScore3 = (this.chineseScore-0)+(this.mathScore-0)+(newValue);
});
vm.$watch("sumScore3",function(newValue){
// newValue是更新之后的sumScore3总分
console.info("watch监听到sumScore3总分发生了变化!");
var avgScore = newValue / 3;
this.chineseScore = avgScore;
this.mathScore = avgScore;
this.englishScore = avgScore;
})
结果显示效果图:
在最后,附上完整的源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">
语文:<input type="text" v-model="chineseScore">
数学:<input type="text" v-model="mathScore">
英语:<input type="text" v-model="englishScore"><br>
<!-- 通过methods实现总分计算,注意千万不能忘了sumScore后面的小括号 -->
总分(函数-单向):<input type="text" v-model="sumScore()"><br>
<!-- 绑定计算属性,sumScore后面不需要加小括号 -->
总分(计算属性-单向):<input type="text" v-model="sumScore1"><br>
总分(计算属性-双向):<input type="text" v-model="sumScore2"><br>
<!-- 通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3; -->
总分(监听器):<input type="text" v-model="sumScore3">
</div>
</body>
<script>
/*
1.函数没有缓存,每次都会被调用
2.计算属性有缓存,只有当计算属性体内的属性值被改变时,才会重新调用
3.函数只支持单向
4.计算属性默认情况下是getter函数,没有setter函数,所以是单向的
(如果要实现双向,则需要自己设置setter函数)
*/
var vm = new Vue({
el: '#app',
data: {
chineseScore:70,
mathScore:80,
englishScore:90,
sumScore3:240,
},
methods:{
sumScore:function(){
// 在控制台输入vm.sumScore()每次都会被调用,因为不会进行缓存
console.info("函数sumScore被调用了!");
// this指向的是当前vm实例,减0是为了字符串转为数字运算
return (this.chineseScore-0)+(this.mathScore-0)+(this.englishScore-0);
}
},
computed: { //计算属性
sumScore1:function(){
// 在控制台输入vm.sumScore1不会被重新调用,说明计算机有缓存
console.info("sumScore1被调用了!");
return (this.chineseScore-0)+(this.mathScore-0)+(this.englishScore-0);
},
// 指定getter/setter实现双向绑定
sumScore2:{
// 获取数据
get:function(){
console.info("sumScore2的getter函数被调用了!");
return (this.chineseScore-0)+(this.mathScore-0)+(this.englishScore-0);
},
// 设置数据
set:function(newValue){
console.info("sumScore2的setter函数被调用了!");
var avgScore = newValue / 3;
this.chineseScore = avgScore;
this.mathScore = avgScore;
this.englishScore = avgScore;
}
}
},
// 监听方式1:通过watch选项实现监听
// 通过watch选项监听语文和数学分数,当语文和数学分数更新后回调函数中重新计算总分sumScore3;
watch: {
chineseScore:function(newValue,oldValue){
// newValue是更新后的语文分数,oldValue是更新前的语文分数
console.info("watch监听到语文分数被改变了!");
this.sumScore3 = (newValue-0)+(this.mathScore-0)+(this.englishScore);
},
mathScore:function(newValue,oldValue){
console.info("watch监听到数学分数被改变了!");
this.sumScore3 = (this.chineseScore-0)+(newValue-0)+(this.englishScore-0);
}
},
})
// 监听方式2:通过vm实例进行调用——vm.$watch()
// 通过vm.$watch()选项监听英语分数,当英语分数更新后回调函数中重新计算总分sumScore3;
// 第一个参数是监听的属性名,第二个参数是回调函数
vm.$watch("englishScore",function(newValue){
// newValue是更新后的英语分数
console.info("watch监听到英语分数被改变!");
this.sumScore3 = (this.chineseScore-0)+(this.mathScore-0)+(newValue);
});
vm.$watch("sumScore3",function(newValue){
// newValue是更新之后的sumScore3总分
console.info("watch监听到sumScore3总分发生了变化!");
var avgScore = newValue / 3;
this.chineseScore = avgScore;
this.mathScore = avgScore;
this.englishScore = avgScore;
})
</script>
</html>
今天的学习到此为止,对于计算属性和监听器有了深一步的了解,最后感谢一下今天给我提意见的朋友们,晚安!