computed
计算属性!
我们通过代码来逐步了解什么是computed
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let users = [
{ id: 1, username: 'baogege', gender: '男' },
{ id: 2, username: 'mt', gender: '男' },
{ id: 3, username: 'haigege', gender: '男' },
{ id: 4, username: 'zMouse', gender: '男' },
{ id: 5, username: 'reci', gender: '女' },
{ id: 6, username: 'lisi', gender: '女' }
]
let app = new Vue({
el: "#app",
data: {
users,
showUser:users, // filter处理不了原数据的时候,需要准备一个变量存储处理过了的数据
}
})
</script>
</body>
我们现在有一个数组 users 我们要做的就是要数据驱动视图 所以我们需要操控一下数据
<body>
<div id="app">
<div>
<button>全部</button>
<button>男</button>
<button>女</button>
</div>
<hr>
<ul>
<li v-for="user of users">
{{user.username}}
</li>
</ul>
</div>
</body>
我们现在的需求就是,点击全部就全部显示,点击男就性别为男的显示,点击女就显示性别为女的
我们先定义一个方法
methods: {
getUsers(gender) {
if (gender === "") {
this.showUser = this.users;
} else {
this.showUser = this.users.filter(user => user.gender === gender);
}
}
}
我们调用一下刚才定义的方法
<button :class="{active:gender===''}" @click="getUsers('')">全部</button>
<button :class="{active:gender==='男'}" @click="getUsers('男')">男</button>
<button :class="{active:gender==='女'}" @click="getUsers('女')">女</button>
然后我们的需求就实现了,这只是为了让大家知道,data里的users是原数据,showUsers是计算后得到的数据(计算属性)
我们现在增加一个需求,点击那个按钮,就让那个按钮亮起,告诉用户是那个按钮执行的
.active{
background-color: pink;
}
...
<button :class="{active:gender===''}" @click="getUsers('')">全部</button>
<button :class="{active:gender==='男'}" @click="getUsers('男')">男</button>
<button :class="{active:gender==='女'}" @click="getUsers('女')">女</button>
...
let app = new Vue({
el: "#app",
data: {
users,
showUser:users,
gender:"" // 新增
},
methods: {
getUsers(gender) {
this.gender = gender; // 新增
if (gender === "") {
this.showUser = this.users;
} else {
this.showUser = this.users.filter(user => user.gender === gender);
}
}
}
})
页面效果



我们现在来看一下通过computed计算属性如何完成上述功能
我们上述代码的功能里边的getUsers这个函数,实际上需要放在computer里边去写
data: {
users,
gender:""
},
computed: {
showUser:{
// 当showUser这个数据被获取是,触发
get(){
if(this.gender === ""){
return this.users
}else{
return this.users.filter(user => user.gender === this.gender);
}
}
},
}
data 与 computed 的区别
- data:存储这没有经过计算的数据
- computed: 依赖于data中的数据, 存储着 被计算过的数据 以及计算的过程, 如果数据需要被二次或者多次处理,就属于计算属性
计算得到的数据
- computed是一个对象,里面存放是属性。类似data,而不是methods,所以统称为计算属性
- 里面的属性可以像 data 里面存放的数据一去使用
- 这些属性的值是通过运算得到的
- 它的结构类似(defineProperty),getter/setter
- 计算属性的值同时还会根据它所依赖的数据的变化 而自动变化
现在我们通过新需求来了解到computed的set方法
<div id="app">
<div>
<button :class="{active:gender===''}" @click="gender = ''">全部</button>
<button :class="{active:gender==='男'}" @click="gender = '男'">男</button>
<button :class="{active:gender==='女'}" @click="gender = '女'">女</button>
</div>
<span> {{gender}} </span>
<hr>
<ul>
<li v-for="user of showUser">
<input type="checkbox" v-model="user.checked">
{{user.username}}
</li>
</ul>
<!--
v-model : 代替标签自身的事件,不同的标签触发的事件不同
input : onchange
-->
<input type="checkbox" v-model="checkAll"/> 全选
</div>
我们在每条li内部加上一个inout框
并且添加一个全选按钮
<input type="checkbox" v-model="checkAll"/> 全选
...
data: {
users,
gender:"",
checkAll:false
},
需求:
- 所有li里边的多选框被选中后,全选就被选中。
- 全选被选中时,所有li里边的多选框也要被选中
那我们就可以吧checkAll理解为一个计算属性,那我们就把它放在computed里边
checkAll:{
get(){
// every() 遍历制定目标的所有内容,一假即假
return this.users.every(user => user.checked)
},
set(newval){
return this.users.forEach(user => {
user.checked = newval
});
}
}
现在处理一下数据,给每个数据加一个checked的属性
let users = [
{ id: 1, username: 'baogege', gender: '男' ,checked:false},
{ id: 2, username: 'mt', gender: '男' ,checked:false},
{ id: 3, username: 'haigege', gender: '男' ,checked:false},
{ id: 4, username: 'zMouse', gender: '男' ,checked:false},
{ id: 5, username: 'reci', gender: '女' ,checked:false},
{ id: 6, username: 'lisi', gender: '女' ,checked:false}
]
...
<li v-for="user of showUser">
<input type="checkbox" v-model="user.checked">
{{user.username}}
</li>
这样我们就实现了上述新需求
computed:计算属性的值,在依赖数据未发生改变时/或者没有依赖数据,自动缓存到应用中,下次获取时不重新计算
我们通过一个页面效果来看
<body>
<div id="app">
<p v-if="showDate"> {{getNow()}} </p>
<button @click="showDate = !showDate">点我</button>
<p v-if="showDate"> {{now}} </p>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
showDate:true
},
methods: {
getNow(){
return Date.now();
}
},
computed: {
// now:{
// get(){
// return Date.now();
// }
// },
// 如果某个计算属性只需要处理get(),那么可以简写
now(){
return Date.now();
},
},
})
</script>
</body>
直接打开浏览器的反馈

点击按钮删除标签后重新创建加载到页面后

可以看出第二个是没有任何变化的
这也就证明了:computed在依赖数据未发生改变时/或者没有依赖数据,自动缓存到应用中,下次获取时不重新计算
watch
上述代码我们可以看出computed的惰性很大的,他不会主动监听你,但是watch是比较积极的,会去主动监听你。
我们下边就通过代码来看一下
<body>
<div id="app">
<input type="text" v-model.lazy="keyword">
<ul>
<li v-for="user of showUsers">
{{user.username}}
</li>
</ul>
</div>
<script>
let users = [
{ id: 1, username: 'baogege', gender: '男', checked: false },
{ id: 2, username: 'mt', gender: '男', checked: false },
{ id: 3, username: 'haigege', gender: '男', checked: false },
{ id: 4, username: 'zMouse', gender: '男', checked: false },
{ id: 5, username: 'reci', gender: '女', checked: false },
{ id: 6, username: 'lisi', gender: '女', checked: false }
]
let app = new Vue({
el:"#app",
data: {
keyword:"",
users,
showUsers:[]
},
watch: {
keyword(){
// includes(指定的内容):查找是否包含指定的值
this.showUsers = this.users.filter(user => user.username.includes(this.keyword))
// setTimeout(()=>{
// this.showUsers = this.users.filter(user => user.username.includes(this.keyword))
// },1000)
}
},
})
</script>
</body>
现在页面上来之后是没有数据的

但是在input框输入一个就会有对应的数据

我们也可以通过定时器来延迟拿到数据
总结上边我们可以看出
- computed是依赖数据变化才去计算
watch主动处理数据变化 - computed没法处理异步的数据
watch可以直接处理异步
各自使用场景:
- watch:适合处理 一个数据影响多个数据
更适合处理数据相互独立的场景
主动监听 - computed:适合处理 一个数据受多个数据的影响 / 多个数据影响一个数据
数据相互不独立的场景,也可以
本文深入探讨Vue中的计算属性(computed)和侦听器(watch),通过实例讲解它们的工作原理及应用场景,对比数据处理方式,帮助读者掌握高效利用计算属性优化前端性能的技巧。
1327

被折叠的 条评论
为什么被折叠?



