拼接名字案例
<template>
<div id="app">
<!-- 原始拼接方式 -->
<p>{{ fastName }} {{ lastName }}</p>
<!-- 在模板语法中进行计算 -->
<p>{{ fastName + " " + lastName }}</p>
<!-- 调用函数计算 -->
<p v-text="fullName2()"></p>
<!-- 使用计算属性计算 -->
<p>{{ fullName1 }}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
fastName: "Tracy",
lastName: "McGrady",
};
},
computed: {
fullName1: function () {
return this.fastName + " " + this.lastName;
},
},
methods: {
fullName2: function () {
return this.fastName + " " + this.lastName;
},
},
};
</script>
运行结果:
购物车价格统计案例
<template>
<div id="app">
<p>{{ totalPrice }}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
bookes: [
{ id: 100, name: "Unix编程艺术", price: 119 },
{ id: 200, name: "Java编程思想", price: 105 },
{ id: 300, name: "高并发编程", price: 98 },
{ id: 400, name: "Spring5", price: 99 },
],
};
},
computed: {
totalPrice: function () {
let result = 0;
// 普通循环
/* for(let i = 0;i < this.bookes.length;i++){
result += this.bookes[i].price;
} */
// 增强for循环,i为索引
/* for(let i in this.bookes){
result += this.bookes[i].price;
} */
// ES6新增for循环直接获取对象
for (let book of this.bookes) {
result += book.price;
}
return result;
},
},
};
</script>
运行结果就是在浏览器上显示出来商品的价格:421
以上两个案例供给各位练习和体验计算属性的用法,他的原理是什么?怎么实现的?他和我自己定义函数调用有什么区别?
计算属性的完整写法其实是其中包含了 getter 和 setter 方法,声明一个fullName对象,因为我们一般只获取值,所以会将其省略写成上边案例的方式,我们在获取数据时会调用get方法,设置数据时会调用 set方法。
目标: 计算属性也是变量, 如果想要直接赋值, 需要使用完整写法
语法:
computed: {
"属性名": {
set(值){
},
get() {
return "值"
}
}
}
需求:
- 计算属性给v-model使用
页面准备输入框
<template>
<div>
<div>
<span>姓名:</span>
<input type="text" v-model="full">
</div>
</div>
</template>
<script>
// 问题: 给计算属性赋值 - 需要setter
// 解决:
/*
完整语法:
computed: {
"计算属性名" (){},
"计算属性名": {
set(值){
},
get(){
return 值
}
}
}
*/
export default {
computed: {
full: {
// 给full赋值触发set方法
set(val){
console.log(val)
},
// 使用full的值触发get方法
get(){
return "无名氏"
}
}
}
}
</script>
<style>
</style>
总结: 想要给计算属性赋值, 需要使用set方法
案例-小选影响全选
目标: 小选框都选中(手选), 全选自动选中
- 需求: 小选框都选中(手选), 全选自动选中
分析:
① 先静态后动态, 从.md拿到静态标签和数据
② 循环生成复选框和文字, 对象的c属性和小选框的选中状态, 用v-model双向绑定
③ 定义isAll计算属性, 值通过小选框们统计c属性状态得来
<template>
<div>
<span>全选:</span>
<!-- 4. v-model 关联全选 - 选中状态 -->
<input type="checkbox" v-model="isAll" />
<button @click="btn">反选</button>
<ul>
<li v-for="(obj, index) in arr" :key="index">
<!-- 3. 对象.c - 关联 选中状态 -->
<input type="checkbox" v-model="obj.c" />
<span>{{ obj.name }}</span>
</li>
</ul>
</div>
</template>
<script>
// 目标: 小选框 -> 全选
// 1. 标签+样式+js准备好
// 2. 把数据循环展示到页面上
export default {
data() {
return {
arr: [
{
name: "猪八戒",
c: false,
},
{
name: "孙悟空",
c: false,
},
{
name: "唐僧",
c: false,
},
{
name: "白龙马",
c: false,
},
],
};
},
// 5. 计算属性-isAll
computed: {
isAll: {
set(val) {
// 7. 全选框 - 选中状态(true/false)
this.arr.forEach((obj) => (obj.c = val));
},
get() {
// 6. 统计小选框状态 -> 全选状态
// every口诀: 查找数组里"不符合"条件, 直接原地返回false
return this.arr.every((obj) => obj.c === true);
},
},
},
methods: {
btn() {
// 8. 让数组里对象的c属性取反再赋予回去
this.arr.forEach((obj) => (obj.c = !obj.c));
},
},
};
</script>
计算属性缓存
methods和computed的区别的问题,下方代码分别使用插值语法、 methods 、 计算属性来做数据渲染。
<template>
<div>
<!-- 原始方式,该方式面对数据计算时比较繁琐,不推荐使用 -->
<p>名字:{{ name }} 工作:{{ job }}</p>
<!-- methods方式,每获取一次数据就调用一次函数 -->
<p>{{ getInfo1() }}</p>
<p>{{ getInfo1() }}</p>
<p>{{ getInfo1() }}</p>
<p>{{ getInfo1() }}</p>
<!-- computed方式,当数据没有发生变化时,仅调用一次,会将数据进行缓存 -->
<p>{{ getInfo2 }}</p>
<p>{{ getInfo2 }}</p>
<p>{{ getInfo2 }}</p>
<p>{{ getInfo2 }}</p>
<p>{{ getInfo2 }}</p>
</div>
</template>
<script>
export default {
data() {
return {
name: "麦迪",
job: "NBA球星",
};
},
methods: {
getInfo1: function () {
console.log("methods");
return "名字:" + this.name + "工作:" + this.job;
},
},
computed: {
getInfo2: function () {
console.log("computed");
return "名字:" + this.name + "工作:" + this.job;
},
},
};
</script>
<style>
</style>
1)、methods和computed看起来都能实现我们的功能
2)、计算属性会进行缓存,如果多次使用时,计算属性只会调用一次