先说结论
- computed是计算属性,一般的计算属性值是一个函数,这个函数会返回一个值,并且其函数内部还可能会依赖别的变量,别的变量改变其也会改变。
- watch是监听,通常用来监听数据变化,一般在变化的时候会执行一个函数。比较重要的属性有两个,一个是deep,一个是immediate,尤其要注意的是为了防止this的丢失,里面一般不适合使用箭头函数。
computed
eg
现在我们假设data为
data: {
user: {
name: 'fangfang',
email: '1111@qq.com',
phone: '123456'
}
}
我们的需求是将其按顺序的展示出来,若是没有这个computed属性,我们将要对每个单独操作,不仅修改麻烦而且会不断重复自己
但是当我们使用这个计算属性,我们将会使得其无论是修改亦或者是代码简洁程度大大降低。
computed: {
displayName: {
get() {
const user = this.user
return user.name || user.email || user.phone
},
set(value) {
this.user.name = value
}
}
},
而且这样写逻辑非常清晰,明确了要计算的属性是什么
我们可以看看另外一个例子,这里是证明了computed里面的属性也可以已函数形式存在。
假设我们需要对列表中的男女进行分类,点一下按钮就可以分类。首先我们整了一个创建用户的函数
let id = 0
const createUser = function (name, gender) {
id += 1
return { id: id, name: name, gender: gender }
}
这个函数作用非常简单,不赘述了,接下来我们自然要再data中将用户信息输入
data() {
return {
user: [
createUser('aa', '男'),
createUser('bb', '男'),
createUser('cc', '男'),
createUser('dd', '女'),
],
gender: ''//性别暂时未知,设为空
}
}
接下来我们要做的就是,第一把男女区分,第二使得点男的出现男的,女的出现女的,这里可以在computed里面先做一个hash,区分男女,然后进行分类讨论即可
computed: {
displayUser() {
const hash = {
male: "男",
female: "女"
}
const { user, gender } = this
if (gender === "") {
return user
} else if (gender) {
return user.filter(u => u.gender === hash[gender])
} else {
throw new Error("无此gender")
}
}//计算属性就是把一个函数形式做为属性
要注意的是,这里我们在视图处有使用vue的v-for功能
template:
`
<div>
<div>
<button @click="setGender('') ">全部</button>
<button @click="setGender('male')">男</button>
<button @click="setGender('female')">女</button></div>
<ul>
<li v-for="(u,index) in displayUser" :key="index">{{u.name}} - {{u.gender}}</li>
</ul>
</div>`,
methods: {
setGender(x) {
this.gender = x
}
}
这个例子很好的展示了computed的用法,实际上我们就是要把需要通过计算,或者需要分类的属性放在computed处,使得代码逻辑更加顺畅而且也可以简洁,不用多处重复自己
v-for怎么用可以参考v-for,这是我从官方文档上看了大概抄下来的。
watch
watch的用法主要就是当数据变化后进行实时的监听,执行一个函数。
举一个撤销的例子
要做的很简单,就是对于数据的变化记录下路,然后按撤销的时候撤销即可
eg
data() {
return {
n: 0,
history: [],
inundomode: false
}
},
watch: {
n: function (val, oldVal) {
console.log('已经watch到变化了')
if (this.inundomode === false) {
this.history.push({ from: oldVal, to: val })
}
}
},
这个是data和watch,其实就是watch监听n,然后把history显示出来,最精髓的是撤销undo的写法
undo() {
const last = this.history.pop()
this.inundomode = true
this.n = last.from
this.$nextTick(() => {
this.inUndoMode = false;
})
}
最精髓的是最后这一步,用了一个异步操作,因为watch本身就是异步,所以如果直接改变this.inUndoMode = false
,将会使得watch的时候永远是在false,未曾开过,所以要用一个异步操作,使得其在撤销完先执行watch,这时候watch发现其处于true的模式,然后不执行push,然后再回到这个undo这个函数将其关闭。
注意事项
不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。
3个比较重要的属性
deep
要注意的是,如果没有开启deep模式(默认关闭),那么就会出现一个对象如果数据变化,实际上是不会被监听的,因为其存放的地址没有改变。但是如果开了就是只要改变就算变
immediate
这个属性是一开始监听与否,因为数据如果是从无到有,不开启时候默认不监听
handler
处理的方法
eg
handler: function (val, oldVal) { /* ... */ }
也就是将如何处理这个数据