1.计算属性
1.1相关概念
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
1.2计算属性的添加
在Vue实例中添加computed:
new Vue({
el: '#root',
data:{
firstName:'李',
lastName:'大龙'
}
//在computed中写入参与属性计算的语句
computed:{
}
})
2.小案例:输入姓、名,实现姓名的更新
2.1差值语法实现姓名案例
<div id="root">
姓:<input type="text" v-model="firstNme"><br><br>
名:<input type="text" v-model="lastName"><br><br>
姓名:<span>{{firstNme}}{{lastName}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstNme: '张',
lastName: '三',
}
})
</script>
2.2通过定义方法来实现姓名案例
<div id="root">
姓:<input type="text" v-model="firstNme"><br><br>
名:<input type="text" v-model="lastName"><br><br>
<!-- 使用插值语法的形式调用函数,函数的返回值直接就是姓+名的组合
当lastName 和 firstName发生改变时,Vue模板会重新解析,fullName()会被重新调用
-->
姓名:<span>{{fullName()}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstNme: '张',
lastName: '三',
},
methods: {
fullName() {
console.log('被调用了');
return this.firstNme + this.lastName
}
}
})
</script>
2.3 通过计算属性实现姓名案例
2.3.1 完整的写法
fullname 是我们计算后要得到的属性,
当有人调用fullName时,就调用get,且返回值就作为fullnamne的值。
get什么时候调用? 1.初次读取fullName的时候, 2.所依赖的数据发生变化时
const vm = new Vue({
el: '#root',
data: {
firstNme: '张',
lastName: '三',
},
computed:{
fullname:{
get(){
return this.firstNme + this.lastName
},
//当fullname被修改的时候,set被调用
set(){
//通过 - 更好地分割 姓和名
const arr = value.splice('-');
this.firstNme = arr[0];
this.lastName = arr[1];
this.fullName = this.firstNme + this.lastName;
}
}
}
2.3.2 简单的写法
所谓简单的写法就是直接将fullname写成函数的形式,里面只写get函数体的内容的,无需考虑修改fullname的情况(省去了set函数)
computed:{
fullName() {
return this.firstNme + this.lastName
}
}
3.监视属性
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
3.1监视属性实现天气案例
点击按钮,让天气在炎热和凉爽之间切换
<div id="root">
<h2>今天的天气很{{info}}</h2>
<button @click="changeWeather">天气切换</button>
<!-- <button @click="isHot = !isHot">天气切换</button> -->
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
isHot: true
},
methods: {
changeWeather() {
this.isHot = !this.isHot;
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽';
}
},
监视属性
watch: {
info: {
//初始化的时候会让handler调用一下
immediate: true,
//handler 当ishot发生改变的时候 handler就会被调用,有两个参数 一个是修改前的值,一个是修改后的值
handler(newValue, oldValue) {
console.log('info变化了');
console.log(newValue, oldValue);
},
}
}
})
// 监视属性的另一种写法。通过Vue实例直接写
vm.$watch('isHot', {
immediate: true,
handler(newValue, oldValue) {
console.log('info变化了');
console.log(newValue, oldValue);
},
})
</script>
watch的用法
watch:{
//info是被监控的属性,只要info发生变化就会触发handler
info:{
handler(newvalue,oldvalue){
//写入需要进行的操作
//newvalue 是监测到的新指,oldvalue是老值,按实际业务需求可以对这两个值进行操作
}
}
}
上面的这个案例不需要watch也能实现,只不过加上watch之后获取参数很方便,可以服务于更多的业务场景
3.2深度监视
当我们想要监视如下代码中的numbers时(numbers中任意一个值发生改变都能被监测到),watch就局限了,numbers中出现了多层级的数。
new Vue({
el:'#root',
data:{
isHot:true,
numbers:{
a:1,
b:1,
c:{
d:{
e:100
}
}
}
},
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
具体做法
watch:{
//监视多级结构中某个属性的变化
'numbers.a':{
handler(){
console.log('a被改变了')
}
}
//监视多级结构中所有属性的变化
numbers:{
deep:true,
handler(){
console.log('numbers改变了')
}
}
}
3.3 watch实现姓名案例
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:<span>{{fullName}}</span> <br/><br/>
</div>
const vm = new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
fullName:'张-三'
},
watch:{
firstName(val){
this.fullName = val + '-' + this.lastName
},
lastName(val){
this.fullName = this.firstName + '-' + val
}
}
})
在监视属性中可以加入一些异步操作,例如,而计算属性就没地方可添加
watch:{
firstName(val){
setTimeout(()=>{
console.log(this)
this.fullName = val + '-' + this.lastName
},1000);
}
}
4.计算属性和监视属性的对比
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,
这样this的指向才是vm 或 组件实例对象。