考虑一个场景:在两个输入框中分别输入姓和名,下方显示出全名
插值语法实现
<!-- 准备好一个容器-->
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:{{firstName}}-{{lastName}}
</div>
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
}
})
通过v-model
实现实现属性和输入的双向绑定,使用插值语法{{firstName}}-{{lastName}}
实现全名的拼接显示
优化方向
- Vue官方推荐:组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法
- 复杂表达式会让模板变得不那么声明式。我们应该尽量描述应该显示什么,而非如何计算那个值。而且计算属性和方法使得代码可以复用
methods实现
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:{{fullName()}}
<!--测试函数调用次数-->
<br>全名:{{fullName()}}
<br>全名:{{fullName()}}
</div>
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三'
},
methods: {
fullName(){
console.log('调用了fullName()函数~')
return this.firstName + '-' + this.lastName
}
},
})
通过v-model
实现实现属性和输入的双向绑定,使用方法fullname()
实现全名的拼接显示
从图中可以看到fullname()
每次读取时都会执行一次。当数据发生改变时fullname()
会被重新调用。
优化方向:
- 可否让
fullname()
在第一次调用后形成缓存,后续仅在属性值发生修改时才再次调用
计算属性实现
- 定义:通过已有属性计算得来的属性
- 原理:底层借助了
Objcet.defineproperty
方法提供的getter
和setter
get()
函数什么时候执行?- 初次读取时会执行一次。
- 当依赖的数据发生改变时会被再次调用。
- 优势:与
methods
实现相比,内部有缓存机制(复用),效率更高,调试方便。 - 备注:
- 计算属性最终会出现在vm上,直接读取使用即可。
- 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
<div id="root">
姓:<input type="text" v-model="firstName"> <br/><br/>
名:<input type="text" v-model="lastName"> <br/><br/>
全名:{{fullName}}
<!--测试函数调用次数-->
<br>全名:{{fullName}}
<br>全名:{{fullName}}
</div>
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
},
computed:{
fullName:{
get(){
console.log('get()被调用了')
return this.firstName + '-' + this.lastName //此处的this是vm
},
set(value){
console.log('set',value)
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
})
若计算属性只读,则可以简写计算属性:
new Vue({
el:'#root',
data:{
firstName:'张',
lastName:'三',
},
computed:{
fullName(){
console.log('get()被调用了')
return this.firstName + '-' + this.lastName //此处的this是vm
},
}
})
通过v-model
实现实现属性和输入的双向绑定,使用计算属性fullname
实现全名的拼接显示
从图中可以看到get()
只在初次读取时会执行一次,后续会使用缓存实现复用。当依赖的数据发生改变时会被再次调用。