1 计算属性的基本了解
1.1 认识Mustache语法的不做
模板中的表达式非常便利,但设计的初衷时为了简单的运算,如果时复杂的逻辑运算,会比较难以维护,不容易理解其中的意思,
例如:
<div id="app">
<!-- 正常绑定数据 -->
{{msg}}
<!-- 对数据进行逻辑处理, 反向字符串 -->
{{msg.split("").reverse().join("")}}
<!-- 多次使用功能反向逻辑 -->
{{msg.split("").reverse().join("")}}
{{msg.split("").reverse().join("")}}
{{msg.split("").reverse().join("")}}
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello",
}
})
</script>
这样就非常不方便,因为如果我需要多次使用这个逻辑时就不那么方便了,所以对于任何复杂的逻辑运算,你都需要使用逻辑运算。
同时将太多的逻辑放入模板中处理,就会使得模板很臃肿,这样不利于代码的维护。
1.2 使用方法弥补Mustache的不足
那么我们首先可能会想到的及时使用方法, 把这些复杂的逻辑定义为一个方法, 然后通过多次调用这个方法来达到逻辑复用的目的
例如
<div id="app">
<!-- 利用方法来处理逻辑 -->
{{ reverseStr() }}
<!-- 多次调用方法复用代码逻辑 -->
{{ reverseStr() }}
{{ reverseStr() }}
{{ reverseStr() }}
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello",
},
methods: {
reverseStr(){
return this.msg.split("").reverse().join("")
}
}
})
</script>
其实我们发现这样可以达到复用的目的, 但是如果我们测试就会发现,函数在每一次调用的时候都会执行, 都会重新计算, 如果调用100次,函数就会执行100次, 对于性能不是特别好, 因为每一次的结果都是一样的
那么我们有没有办法吧数据缓存下来呢, 就不用每次都计算了呢?还真有
1.3 计算属性的了解
Vue给我们提供了一个计算属性Computed, 计算属性中的方法也是函数, 但是跟方法不同, 计算数据会将计算的结果挂在到Vue实例对象的属性上. 这样每次调用的时候,都是在调用Vue实例的属性, 这样我们同样的逻辑计算的结果就得到了缓存,每次使用属性值就可以了
例如:
<div id="app">
<!-- 利用计算属性来处理逻辑 -->
{{ reverseMsg }}
{{ reverseMsg }
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello",
},
methods: {
reverseStr(){
console.log(11)
return this.msg.split("").reverse().join("")
}
},
computed:{
reverseMsg(){
return this.msg.split("").reverse().join("")
}
}
})
</script>
这里我们在Vue 的 computed 属性中定义了一个方法 reverseMsg , Vue会自动计算这个方法的结果, 不需要我们自己调用, vue会将计算后的结果添加给Vue 实例对象的同名属性. 这就是我们所说的计算属性
因为是属性的关系,我们在{{}}中使用的使用不需要添加()执行, 就跟我们平时调用data 属性中的数据一样使用就好了
而且我们可以测试在多次调用计算属性的时候, 计算属性会不会被多次调用,
computed:{
reverseMsg(){
console.log(22)
return this.msg.split("").reverse().join("")
}
}
我们会发现无论你使用多少次计算属性, 计算属性的方法都只会执行一次,
这样就有弥补了Mustache语法和方法复用逻辑带来的问题
1.4 数据发生变化
如果如果我的数据发生了变化, 那计算后的结果也应该发生变化, 那么在数据发生变化的时候, 计算属性会不会执行呢,答案是肯定的.
例如:
<div id="app">
<!-- 利用计算属性来处理逻辑 -->
{{ reverseMsg }}
{{ reverseMsg }}
<!-- 点击按钮改变数据 -->
<button @click="changeMsg">点击改变数据</button>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello",
},
methods: {
changeMsg(){
this.msg = "word"
}
},
computed:{
reverseMsg(){
console.log(22)
return this.msg.split("").reverse().join("")
}
}
})
</script>
通过案例; 当我们点击改变数据按钮的时候, 数据发生变化, 数据一定发生变化,就会自动触发依赖这个数据的计算属性的方法, 通过计算的得到的结果将会覆盖原来的属性的结果, 也就会重现渲染页面结果
1.5 为什么称呼为计算属性
很多小伙伴要问? 为什么说他是属性而不是方法呢,铭铭就是定义了一个函数嘛
其实这个问题只要理解对象的属性和方法的区别就能理解
例如
var obj = {
name:'姓名',
eat: function(){
console.log("吃饭")
}
}
这个对象,我们称obj对象有一个属性name
,和方法eat
,为什么这么叫
其实eat
也是obj
对象的属性, 只不过这个属性值是一个函数,我们把属性值为函数的属性成为方法, 因为函数能实现一定的功能.
理解了属性和方法的区别以后,我们在来理解Vue的计算属性.
此时我们去控制台打印Vue实例化对象
image代码就是上面计算属性那一节的代码,
通过在控制台的打印我们发现,Vue初始化的选项对象中,无论是data
属性,methods
属性还是computed
属性中的值都会挂载在Vue实例化对象身上,成为Vue实例对象的属性.
此时也会发现,
-
methods
属性中的值在成为Vue实例对象属性时值为函数,所以叫methods
为方法属性. -
data
属性中的中数据成为Vue实例对象属性是值就是data
中定义的值, -
有趣的是
computed
属性中定义的reverseMsg
是一个函数, 但是在成为Vue实例对象属性后,结果却不是函数,而是函数的执行结果
所以现在能理解为什么称为计算属性了吧,因为computed
属性中的方法名会成为Vue实例对象的属性,但是值不是函数,所以不会被称呼为方法,同时因为属性的值是计算而来的,一次称呼计算属性.
2. 计算属性的getter和setter
2.1 计算属性语法的了解
重点要注意这个属性,computed是属性不是方法
方法是不会有缓存的,但是computed会根据依赖(依赖是归vue管理的数据,可以响应式的变化)的变化重新处理逻辑进行数据的缓存
其实计算由两部分组成,为get和set(不能只写set),一般情况下通过js赋值影响其他人或者表单元素设置值的时候会调用set方法
其实想想就能理解, 对象的属性, 获取的时候不就是get 当你改变对象属性的值,不就是重新赋值了嘛,也就是set啊,
语法:
{
computed:{
// 计算属性写成对象,就需要手动设置get方法,set方法
sum:{
get(){
// 获取时调用的方法
},
set(val){
// 设置时调用
}
},
// 如果计算属性写成函数,默认调用的就是get方法,没有set方法
sum(){
}
}
}
2.2 get 语法
那么我们首先来看get 获取计算属性的值
计算属性默认只有 get ,不过在需要时你也可以提供一个 set
我们默认的计算就是只有get操作
例如:
一般都没有set,只有输入框这种可能有set
<div id="app">
<!-- 显示计算属性结果-->
<div>
firstname:
<input type="text" v-model="firstName">
</div>
<div>
lastname:
<input type="text" v-model="lastName">
</div>
<div>
getfullname:
<input type="text" v-model="fullName">
</div>
<div>
setfullname:
<input type="text" v-model="fullName">
</div>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
firstName:"Foo",
lastName: "Bar",
},
computed:{
// 这里Fullname只有get功能
fullName(){
return this.firstName + ' ' + this.lastName
}
}
})
</script>
我们发现每次计算属性FullName所依赖的firstname 和lastname 值一旦发生变化, FullName也将重新计算获取最新的计算结果,
2.3 set语法
但是如果我想改变计算属性的值,能不能反向的修改firstname 和lastname的值呢, 发现不可以,因为我们没有添加set计算属性设置
如果想添加计算属性的set功能,我们就的改变咱们计算属性的写法
<script>
const vm = new Vue({
el: "#app",
data: {
firstName:"Foo",
lastName: "Bar"
},
computed:{
fullName:{
// 计算属性的get
get(){
console.log("get")
return this.firstName + ' ' + this.lastName
},
// 计算属性的set, set是设置,设置就需要新值传入
set(value){
console.log("set")
let fullNameArr = value.split(" ");
this.firstName = fullNameArr[0] ? fullNameArr[0]: '';
this.lastName = fullNameArr[1] ? fullNameArr[1]: '';
}
}
}
})
</script>
3. 案例区
案例: 全选按钮
<div id="app">
<!-- 全选案例-->
<div>
全选: <input type="checkbox" v-model="checkAll">
</div>
<ul>
<li
v-for="fruit in fruits"
:key="fruit.title"
>
<input type="checkbox" v-model="fruit.isSelect">
{{fruit.title}}: 价格{{fruit.price}}元/斤
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
fruits:[
{
title:"西瓜",
price: 10,
isSelect:false,
},
{
title:"苹果",
price: 22,
isSelect:false,
},
{
title:"香蕉",
price: 11,
isSelect:false,
}
]
},
computed:{
checkAll:{
get(){
console.log(11)
// 如果用户全部选中,那么计算数据返回true,否则返回false
return this.fruits.every((fruit) => {
return fruit.isSelect;
})
},
set(isCheckAll){
// 更加用户是否点击全选改变数据里的选中问题
this.fruits.forEach(fruit => {
fruit.isSelect = isCheckAll
});
}
}
}
})
</script>
网友评论