第一章回顾
前言
在介绍完前面的指令后,接下来是对一些计算对象的介绍。当然之前已经提及了在Vue()中的methods
对象,这是一个方法对象,虽然它已经能够处理大部分的逻辑,但Vue另外提供了一些计算方法供我们选择。
计算属性
模板内的表达式非常便利,只要是合法的javascript语句都能被识别渲染出来,但是Vue设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如要把一个字符串翻转的操作:
<div id="example">
{
{ message.split('').reverse().join('') }}
</div>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。所以,对于任何复杂逻辑,除了使用方法进行运算,还可以使用计算属性。
实例如下:
<body>
<div id="app">
<p>{
{reverString}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el:'#app',
data:{
bool:false,
mse:"欲与天公试比高"
},
computed:{
/*
reverString:function () {
return this.mse.split(" ").reverse().join(" ")
},
*/
reverString() {
return this.mse.split("").reverse().join("")
}
}
})
</script>
</body>
<!--
显示结果
高比试公天与欲
-->
在这里是对字符串进行翻转的操作,和方法一样,在computed中,这两种方法都可以被正确识别,不过要注意的是,计算属性不是方法,不能进行参数传递,在{
{}}
中引用的时候直接写方法名就好,不要加括号,不然会报错
app.mse="长风破浪会有时"
console.log(app.reverString)
接着上面的例子,我们可以像绑定普通 property 一样在模板中绑定计算属性。Vue 知道 app.reverString依赖于app.mse,因此当 app.mse发生改变时,所有依赖app.reverString的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter
函数是没有副作用 的。
计算属性与方法的区别
在介绍之前,先运行一个实例,同时观察控制台输出的情况:
<body>
<div id="app">
<p>{
{reverString}}</p>
<p>{
{reverString}}</p>
<p>{
{reverString}}</p>
<hr>
<p>{
{reverStr()}}</p>
<p>{
{reverStr()}}</p>
<p>{
{reverStr()}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el:'#app',
data:{
bool:false,
mse:"高比试公天与欲"
},
methods:{
reverStr() {
console.log("这里是methods")
return this.mse.split("").reverse().join("")
}
},
computed:{
reverString() {
console.log("这里是computed")
return this.mse.split("").reverse().join("")
}
}
})
</script>
</body>
<!--
输出结果:
这里是computed
这里是methods
这里是methods
这里是methods
-->
对methods
和computed
的方法都调用三次,观察控制台的打印情况,根据结果我们可以发现computed被打印了一次,methods被打印了三次,说明计算属性是依赖缓存的,计算属性只在相关响应式依赖发生改变时它们才会重新求值,这也同样意味着下面的计算属性将不再进入缓存,计算属性将不再更新,因为 Date.now () 不是响应式依赖:
computed: {
now() {
return Date.now()
}
}
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 list,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 list。如果没有缓存,我们将不可避免的多次执行 list 的 getter!如果你不希望有缓存,请用 method 来替代。
计算属性的 getter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
<body>
<div id="app">
<p>{
{fullName}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el:'#app',
data:{
firstName:"Liu",
lastName:"Xiang"
},
computed:{
// 简写形式
// fullName () {
// return this.firstName + " " + this.lastName
// }
fullName:{
set:function (newValue) {
const names = newValue.split(" ")
this.firstName = names[0]
this.lastName = names[1]
},
get:function () {
return this.firstName + " " + this.lastName
}
}
}
// app.fullName = "English Name"
})
</script>
</body>
我们在使用计算属性的时候其实使简写,因为一般只是使用其中的get方法,这个方法只读,如果要进行修改,需要自定义set方法。在set方法中,对data中的数据进行赋值。设置完set方法之后再运行 app.fullName = 'John Doe'
时,setter 会被调用,app.firstName
和 app.lastName
也会相应地被更新。