引言
最近回顾了一下Vue的计算属性,现来浅浅地记录一下。我们知道在Vue组件的模板中常常会使用一些表达式,初衷是为了可以进行简单的运算。但是,一旦表达式逻辑比较复杂,这个时候就要考虑使用计算属性了。写一段代码做演示
<body>
<div id="root">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
全名: <span>{{fullName}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: 'y',
lastName: 'zm'
},
computed: {
fullName() {
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
我们写了一个fullName的计算属性,它是由firstName和lastName拼接起来的,只要firstName和lastName发生改变,fullName也会随之改变。有同学会说,我定义一个方法也能实现,确实能实现,我们来看一下
<body>
<div id="root">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
全名: <span>{{fullName()}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: 'y',
lastName: 'zm'
},
methods: {
fullName() {
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
使用定义一个方法的方式确实能够实现获取fullName值,并且一旦input框的值发生改变,fullName值也随之改变
那我们为什么要使用计算属性呢
使用计算属性的优点在于:计算属性存在缓存机制,只要计算属性所依赖的属性不发生改变,计算属性的方法就不会被再次调用。
为了直观理解,先看定义方法的方式,如下代码
<body>
<div id="root">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
全名: <span>{{fullName()}}</span>
全名: <span>{{fullName()}}</span>
全名: <span>{{fullName()}}</span>
全名: <span>{{fullName()}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: 'y',
lastName: 'zm'
},
methods: {
fullName() {
console.log('方法执行了!')
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
使用定义方法的方式,我们会看到,fullName被调用几次就执行几次
如果使用计算属性,如下代码:
<body>
<div id="root">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
全名: <span>{{fullName}}</span> <br>
全名: <span>{{fullName}}</span> <br>
全名: <span>{{fullName}}</span> <br>
全名: <span>{{fullName}}</span>
</div>
<script>
new Vue({
el: '#root',
data: {
firstName: 'y',
lastName: 'zm'
},
computed: {
fullName() {
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
使用计算属性的方式,我们会看到,fullName计算属性的方法执行了一次
小结
计算属性的方法一般在什么时候会被调用呢:
- 当计算属性首次被读取时
- 当计算属性所依赖的属性被修改时
拓展
计算属性一般就是被读取的,所以我们写的最多的方式就是上面的写法,其实它还有完整的写法,如下代码:
<body>
<div id="root">
姓:<input type="text" v-model="firstName"> <br>
名:<input type="text" v-model="lastName"> <br>
全名: <span>{{fullName}}</span> <br>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
firstName: 'y',
lastName: 'zm'
},
computed: {
fullName: {
get() {
console.log('get执行了');
return this.firstName + '-' + this.lastName
},
set(value) {
console.log('set执行了');
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
})
</script>
</body>
我们一般在读取的时候,会去调用get方法,这个方法又称为getter,同理也有一个setter,这就是通过我们的Object.defineProperty()方法来实现的。不熟悉这个可以去看一下。执行代码,进入浏览器控制台查看。
当我们去修改fullName时,set会执行
我们看到set执行了,get又执行了一遍,get执行是因为在set方法里面修改了firstName和lastName,又因为fullName又依赖于fisrName和lastName属性,所以get会执行一次,形成了连锁反应。