计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。
在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example"> {{ message.split('').reverse().join('') }} </div>
在这个地方,模板不再是简单的声明式逻辑。
你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。
当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性。
own:
<body>
<div >
<div>
<!-- split = 字符中间空格分割, reverse= 反转 join('') = 以空格合并 -->
{{ reverseStr }}
</div>
<!-- 绑定clickHandler 点击事件 -->
<button v-on:click='clickHandler'>切换</button>
</div>
<script type="text/javascript" src="./js/vue.js"></script>
<script>
var com = new Vue({
el:'#computed',
data:{
msg:'Hello Mark'
},
// 事件所要执行的函数
methods:{
clickHandler(){
this.msg = 'Hello MIMI'
}
},
// app名字 通过反射计算属性后返回
computed:{
//默认只有getter方法
// 计算数据属性 watch监听 reverseStr =属性值
reverseStr(){
return this.msg.split('').reverse().join('');
}
}
})
</script>
</body>
基础例子
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
结果:
Original message: "Hello"
Computed reversed message: "olleH"
这里我们声明了一个计算属性 reversedMessage。
我们提供的函数将用作属性 vm.reversedMessage 的 getter 函数:
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
你可以打开浏览器的控制台,自行修改例子中的 vm。
vm.reversedMessage 的值始终取决于 vm.message 的值。
你可以像绑定普通属性一样在模板中绑定计算属性。
Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。
而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。
<body>
<div >
<p>我是一个message:'{{message}}'</p>
<p>我是一个计算属性反装的message:'{{reversedMessage}}'</p>
<div>
<!-- split = 字符中间空格分割, reverse= 反转 join('') = 以空格合并 -->
{{ reverseStr }}
</div>
<!-- 绑定clickHandler 点击事件 -->
<button v-on:click='clickHandler'>切换</button>
</div>
<script type="text/javascript" src="./js/vue.js"></script>
<script>
var com = new Vue({
el:'#computed',
data:{
msg:'Hello Mark',
message:'Hello Mark',
},
// 事件所要执行的函数
methods:{
clickHandler(){
this.msg = 'Hello MIMI'
}
},
// app名字 通过反射计算属性后返回
computed:{
//默认只有getter方法
// 计算数据属性 watch监听 reverseStr =属性值
reverseStr(){
// this` 指向 Vue com 实例对象
return this.msg.split('').reverse().join('');
},
//Vue知道 reversedMessage依赖于message,当message改变,自身也会改变
reversedMessage(){
return this.message.split('').reverse().join('')
},
}
})
</script>
</body>
计算属性缓存 vs 方法
你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
我们可以将同一函数定义为一个方法而不是一个计算属性。
两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。
只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,
多次访问 reversedMessage计算属性会立即返回之前的计算结果,而不必再次执行函数。
own:
body> <div id="computed"> <p>我想说:'{{ reversedMessage() }}'</p> </div> <script type="text/javascript" src="./js/vue.js"></script> <script> var com = new Vue({ el: '#computed', data: { message: "我喜欢你这个装逼的朋友" }, // 事件所要执行的函数 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }, }) </script> </body>