这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
计算属性
介绍
-
在Vue开发中,经常需要对项目中的属性进行一些js运算,如果将js运算代码直接插入到Vue的模板中会显得模板代码十分臃肿,并且插值语法内部不能使用if语句的。
-
Vue为需要处理数据提供了一个新的配置选项,computed计算属性。写在当前计算属性函数内部的所有其他属性都会作为当前计算属性的依赖(计算属性会监听这些数据的变化)。
-
如果依赖不发生改变计算属性就不会重复执行,而是返回上一次计算属性执行后的值(计算属性的缓存)
基础例子
<div id="example">
<p>{{ message.split('').reverse().join('') }}</p>
<div>{{ message.split('').reverse().join('') }}</div>
</div>
复制代码
message 字符串翻转代码直接插入到DOM节点中显得代码过于繁琐,并且不能复用导致代码想当的臃肿
解决方法: message属性 字符串的反转运算封装到计算属性中
<div id="example">
<p>{{reverseMsg}}</p>
<div>{{reverseMsg}}</div>
</div>
<script>
new Vue({
el: '#example',
data: {
message: 'Hello world'
},
computed: {
reverseMsg() {
return this.message.split('').reverse().join('')
}
}
})
</script>
复制代码
实现购买按钮的描述功能
<div id="app">
<button>{{payBtnText}}</button>
<div>{{totalPrice}}</div>
<div>{{fakedata}}</div>
</div>
<script>
// 当 totalPrice 为 0 时,购买按钮显示 minPrice元起送
// 当 totalPrice 大于 0 小于minPrice时,购买按钮显示 还差minPrice-totalPrice元起送
// 当 totalPrice 大于等于 minPrice时,购买按钮显示 立即购买
let vm = new Vue({
el: '#app',
data: {
minPrice: 25,
totalPrice: 0,
fakedata: true
},
computed: {
payBtnText() {
console.log("computed running")
if(this.totalPrice <= 0 ) {
return `${this.minPrice}元起送`
}else if(this.totalPrice < this.minPrice) {
return `还差${this.minPrice - this.totalPrice}元起送`
}else {
return '立即购买'
}
}
}
})
</script>
复制代码
计算属性的缓存
上面的计算属性功能使用methods也可以实现,但是为什么我们要使用计算属性呢?
因为计算属性会将当前计算属性函数内调用的所有 data 和 其它计算属性 作为当前计算属性的依赖(当前计算属性会订阅
内部所有属性和其他计算属性变化
).,如果依赖发生改变计算属性会自动的重新计算自身的值。
如果内部任何依赖都没有发生变化计算属性将不会执行器内部代码,只会返回上一次计算出的值(缓存上一次的值,若依赖发生改变则重新计算值,若没有改变则返回缓存值。
//下面的计算属性now如果str属性不发生改变的化,下面的计算属性将不再更新,
// 因为 Date.now() 不是响应式依赖
computed: {
now: function () {
return this.str + Date.now()
}
}
复制代码
相信大家都还记得我们之前的那个Todo案例(传送门)吧,今天搞个升级版哦,利用
计算属性
加个过滤的功能
以及双击更换todo内容
的功能。代码就不展示了哦,注释啥的都在代码里面,点击下方的链接查看。
[案例] todo带过滤.html
计算属性的setter
概念: 计算属性默认只有 getter,不过在需要时你也可以提供一个 setter
语法:
计算属性名: {
get(){return},
set(val){}
}
复制代码
栗子:
<div id="app">
<p>姓: <input type="text" v-model="lastName"></p>
<p>名: <input type="text" v-model="firstName"></p>
<p>全名: <input type="text" v-model="fullName"></p>
</div>
<script>
new Vue({
el: '#app',
data: {
firstName: "小明",
lastName: "李"
},
computed: {
fullName: {
get() {
return `${this.lastName} ${this.firstName}`
},
set(val) {
console.log(val)
let names = val.split(' ')
this.firstName = names[1]
this.lastName = names[0]
}
}
}
})
</script>
复制代码
侦听器
概念: Vue提供了一个对当前实例属性侦听的配置选项,当前被侦听的属性发生改变时,对应侦听器绑定的callback函数就会被触发。
语法: watch:{侦听的属性名:callback(newValue, oldValue)}
- 参数一:旧值 (oldValue)
- 参数二:新值 (newValue)
<div id="app">
<div>{{hours}}</div>
<button @click="hours++">hours add</button>
</div>
<script>
new Vue({
el: '#app',
data: {
hours: 0
},
watch: {
hours: function(newValue, oldValue) {
if(newValue !== oldValue) {
if(newValue < 4) {
console.log('健康游戏时间')
}else if(newValue < 6) {
// alert(`你已经高强度网上冲浪${this.hours}`)
alert(`你已经高强度网上冲浪${newValue}小时请注意休息`)
}else {
alert(`强制下线`)
}
}
},
ccc() {
}
}
})
</script>
复制代码
注意: watch中的回调函数不能使用箭头函数,使用箭头函数会导致函数内的this不指向当前实例对象自身
结尾
今天就先到这里啦!我们下期再见!码字不易,觉得不错的可以动动小指头点点赞啥的哟~
系列文章
Vue系列
- Vue配置起步(一)
- Vue事件绑定(二)
- Vue渲染指令(三)
- Vue动画过渡(四)
- Vue – Todo案例(五)
- Vue表单数据绑定、Ref(六)
- Vue计算属性以及侦听器(七)
- Vue组件
- Vue插槽&过滤器
- Vue的反向传值 ($emit事件)