computed
在实际的应用中,我们会有一些原始数据,同时在应用中又会有一些数据是根据某些原始数据派生出来的,针对这样的一种情况,vue
定义了一个专门用来处理这种派生数据的选项:computed
data和computed
data 存储着没有经过计算(不限于数学)的数据
computed
- 依赖于data中的数据
- 存储着被计算过的数据,以及计算
- 如果数据需要被二次或多次处理,就属于计算属性
计算得到的数据
- 1.computed是一个对象,里面存放是属性,类似data,而不是methods,所以称为计算属性
- 2.里面的属性可以像data里面存放的数据一样去使用
- 3.这些属性的值是通过运算得到的
- 4.它的结构类似数据劫持中的defineProperty,getter,setter
- 5.计算属性的值同时还会根据它所依赖的数据的变化,而自动变化
计算属性的 getter
与 setter
默认情况下,计算属性函数是一个 getter
函数,如果计算属性只有 get 需求,则可以简写
computed: {
now() {
return Date.now();
}
// 等于
now: {
get() {
return Date.now();
}
}
}
但是有的时候,这种派生数据既有 get
需求,也有 set
需求
<div id="app">
<label><input type="radio" v-model="gender" value="" /> 所有</label>
<label><input type="radio" v-model="gender" value="男" /> 男</label>
<label><input type="radio" v-model="gender" value="女" /> 女</label>
<hr>
<ul>
<li v-for="user of showUsers">
<input type="checkbox" v-model="user.checked" />
{{user.username}}
</li>
</ul>
<label><input type="checkbox" v-model="checkAll">全选</label>
</div>
let app = new Vue({
el: '#app',
data: {
gender: '',
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}
]
},
computed: {
showUsers() {
return this.gender === '' ? [...this.users] : this.users.filter(user=>user.gender===this.gender);
},
checkAll: {
get() {
return this.users.every(user=>user.checked);
},
set(newValue) {
this.users = this.users.map(user=>{
return {
...user,
checked: newValue
}
});
}
}
}
});
watch
有的时候,我们需要的派生数据是通过异步的方式处理的,这个时候,计算属性就不太好用了(不能处理异步)。
我们可以使用另外一个选项:watch
computed:计算属性 / 计算数据 / 派出数据
watch: 异步的派出数据
computed和watch的区别:
- 1.computed是依赖数据变化 才去计算;
watch主动处理数据变化 - 2.computed没法处理异步的数据
watch可以直接处理异步
watch和computed各自使用的场景
- 1.watch适合处理:一个数据去影响多个数据 (比如说全选)
更适合处理数据相互独立的场景
主动监听 - 2.computed适合处理:一个数据受多个数据的影响 (比如说反选)
数据相互不独立的场景,也可以(get,set方法)
let app = new Vue({
el: '#app',
data: {
keyWord: '',
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}
],
showUsers: []
},
watch: {
keyWord(newVal, oldVal) {
// 模拟网络请求
setTimeout(_=>{
this.showUsers = this.users.filter(user=>user.username.includes(newVal));
}, 1000);
}
}
});
总结watch的三种用法
- 第一种用法:直接监听
users是需要监听的数据(属性)
(){…}是数据发生改变的时候调用的回调函数
users(){
// every() 一假即假
if(this.users.every(user => user.checked)){
this.all = true;
}else{
this.all = false;
}
}
-
第二种: watch :默认监听数据一层
深度监听:handler方法和deep属性结合,可以监听多层
users:{
handler(newVal,oldVal){
console.log("新的值" + newVal)
console.log("旧的值" + oldVal)
// every() 一假即假
if (this.users.every(user => user.checked)){
this.all = true;
}else{
this.all = false;
}
},
deep:true //默认false,只监听一层
}
- 第三种:多层监听
watch:监听数据,只有当数据变化的时候,才会执行,我们想让最初的时候就执行回调函数,需要 handler()和immediate属性
watch:{
a:{
handler(){
console.log("aaaa")
}
immediate:true
}
}