问题
什么是计算属性
各种实现的案例
1、插值语法
<template id="my-app">
<--! 最基本的插值 -->
<h2>{{firstName + " " + lastName}}</h2>
<--! 三元运算符 -->
<h2>{{score >= 60 ? '及格': '不及格'}}</h2>
<--! 数据进行某种转化 -->
<h2>{{message.split(" ").reverse().join(" ")}}</h2>
</template>
data() {
return {
firstName: "Kobe",
lastName: "Bryant",
score: 80,
message: "Hello World"
}
}
2、通过methods
<template id="my-app">
<h2>{{getFullName()}}</h2>
<h2>{{getResult()}}</h2>
<h2>{{getReverseMessage()}}</h2>
</template>
methods: {
getFullName() {
return this.firstName + " " + this.lastName;
},
getResult() {
return this.score >= 60 ? "及格": "不及格";
},
getReverseMessage() {
return this.message.split(" ").reverse().join(" ");
}
}
3、computed
<template id="my-app">
<h2>{{fullName}}</h2>
<h2>{{result}}</h2>
<h2>{{reverseMessage}}</h2>
</template>
computed: {
// 定义了一个计算属性叫fullname
fullName() {
return this.firstName + " " + this.lastName;
},
result() {
return this.score >= 60 ? "及格": "不及格";
},
reverseMessage() {
return this.message.split(" ").reverse().join(" ");
}
}
==========================
和方法的(methods)的区别
1、缓存
2、调用次数
多个插值,计算属性只会调用1次,而方法会调用多次,性能更低
==========================
计算属性内部方法getter和setter
每个计算属性内的函数内部,默认有2个方法:set,get,默认调用的是get方法
get方法:外部要读取这个计算属性的值时,调用这个方法里面的函数
set方法:外部要改变计算属性的值时,调用这个方法里面的函数
内部是这样运作的,当html使用到了计算属性时(如下图
{{addNum}}
):1.先调用get方法
2.如果计算属性的值被其他改变了,就会调用set方法,set方法函数有一个参数n,n为这个计算属性获得的新值
3.然后再调用一次get方法
如下例子
1.先调用num,{{num}}显示0
2.再调用addNum,调用get方法,{{addNum}}显示1,
3.因为{{num}}发生了改变,因此{{num}}也会显示1
4.再运行一次addNum,由于计算属性的特性,只会运行一次,因此没变化
5.调用addAddNum,执行addAddNum的get方法,让addNum = 3
6.addNum 检测到值改变,因此把新的值3,传到了set方法里面的n,那么num变成11+3=14
7.然后再调用一次addNum的get方法,num变成15
8.num发生了改变,也显示15
调用的顺序,是和上面html从上到下执行有关的
<template>
<div id="app">
<div>{{num}}</div>
<div>{{addNum}}</div>
<div>{{addNum}}</div>
<div>{{addAddNum}}</div>
</div>
</template>
<script>
export default {
data(){
return {
num:0
}
},
computed:{
addNum:{
set:function(n){
this.num = n+11
},
get:function(){
return this.num+=1
}
},
addAddNum:function(){
this.addNum = 3
}
}
};
</script>
源码如何实现?
Vue 3写法
例子:
1、比如监听价格变量,我每次都想给这个变量加一个¥的符号,就可以通过计算属性返回加上符号的变量。这样不管价格怎么变,新变量都是加上符号的。
下面例子是Vue Cli 或者 Vite 等环境下用写组件的方法编写
<template>
<div>数值:{{money}}</div>
<div>价格:{{price}}</div>
<button @click="changeMoney">数值+1</button>
<button @click="changePrice">重置价格</button>
</template>
<script>
import { computed, ref } from "vue";
export default {
setup() {
let money = ref(12);
// 1、简单写法(只使用getter函数)
// let price = computed(() => return `¥ ${money.value}`) // 返回的本质上是ref对象
// 2、复杂写法(使用getter和setter函数)
let price = computed({ //监听一个变量money,这个变量变化时,执行get方法进行新的操作,操作后的值赋值给price变量
get: () => {
return `¥ ${money.value}`;
},
set: (newValue) => { // price 变量的值被直接改变时,调用set方法,用的比较少
return money.value = newValue; //这里例子,有人改变我的price,我会去同时影响源变量money,然后重新调用我的get方法加上¥符号
},
});
const changeMoney = () => { // 改变监听的变量money,调用计算属性的get方法
money.value += 1;
};
const changePrice = () => { // 改变price,调用计算属性的set方法
price.value = 0;
};
return { money, price, changeMoney,changePrice };
},
};
</script>
<style>
</style>