1 computed
1.1 特点
- 计算属性,看上去是方法,但实际上是实例计算属性
- 这个属性不需要调用直接可以在 DOM 里使用
<template>
<div class="app">
{{functionName}} //直接渲染到页面
</div>
</template>
<script>
.....
computed: {
functionName() {return ...}
}
</script>
- 会根据你所依赖的数据动态显示新的计算结果
- 计算属性如果依赖不变的话,它就会变成缓存,computed的值就不会重新计算
- 所有getter和setter的this自动地绑定为Vue实例
- 简化了template模板内{{}}中的内容,这也是computed的设计初衷
1.2 语法
computed:{
[key: string]: Function | { get: Function, set: Function }
}
- 实例1,此处Function默认为getter
<script>
.....
computed: {
functionName() {return ...}//返回值渲染到页面
}
</script>
- 实例2,此处Function分别为getter和setter
<script>
data:{
n:0
}
computed: {
functionName:{
get() {
return this.n
}
set(value) {
this.n=value
}
},
}
</script>
<template>
<button @click='functionName=1'></button> //设置functionName,n设置为1
<div> {{functionName}}</div> //读取functionName,1渲染到页面
</template>
2 watch
2.1 特点
- 监听/侦听,当数据变化时,执行一个函数
- Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性
- 当监听的数据变化时,Vue会自动传入 newVal 和 oldVal
<script>
new Vue({
data: {
n: 0
},
watch: {
n(newValue, oldValue) {
console.log(newValue,oldValue)
}
},
</script>
<template>
<div>
{{n}}
<button @click="n=1">n+1</button>
</div>
</template>
//newValue:1
//oldValue:0
- 如果你需要在某个数据变化时做一些事情,使用watch
- 不应该使用箭头函数来定义 watcher 函数
2.2 注意事项
- 用watch可以模拟computed的功能,但是并不建议这么做
new Vue({
data: {
user: {
nickname: "方方",
phone: "13812312312"
},
displayName: ""
},
watch: {
"user.nickname": {
handler: "changed",
immediate: true
},
"user.phone": {
handler: "changed",
immediate: true
},
template: `
<div>
{{displayName}}
<button @click="user.nickname=undefined">remove nickname</button>
</div>
`,
methods: {
changed() {
const user = this.user;
this.displayName = user.nickname ||user.phone;
}
}
}).$mount("#app");
->点击button,方方消失,13812312312出现
->虽然也可实现computed的功能,但displayName是Vue实例的真正属性,而不是计算属性
->'immediate: true'表示第一次渲染是也触发 watch
->从上面例子看到,如果是多级属性,watch可以这样写:
watch: {
"user.nickname": {
function(){}
}
- watch是异步的
watch:{
n(){
console.log(this.mode)
}
}
methods:{
this.mode = true;
this.n = old; // watch n 的函数会异步调用
this.mode = false //上一句执行完会立刻执行这一行,mode会马上false
}
//
为了让watch n 函数输出为true,可以使用Vue提供的$nextTick():
this.inUndoMode = true
this.n = old
this.$nextTick(() => {
this.inUndoMode = false //可以简单理解为:等一会再执行这行代码
}
2.3 watch完整语法
语法1:
watch:{
a: function (newVal, oldVal) {...},
// 方法名
b: 'someMethod',
c: {
handler: function (newVal, oldVal) {...},
},
d: {
handler: 'someMethod',
immediate: true
},
e: [
'handle1',
function handle2 (newVal, oldVal) {...},
{
handler: function handle3 (newVal, oldVal) {...},
}
],
'e.f': function (val, oldVal) {...}
}
语法2:
vm.$watch('xxx',fn,{deep:...,immediate:...})
3 对数据变化的理解
3.1 简单数据类型
简单数据类型看值,值变了则数据变化了
data: {
n:0
}
//data.n=1,则n变化了
3.2 复杂数据类型(对象)
复杂类型(对象)看地址,地址变化了则数据变化了
data: {
n:0
}
//data.n=1,n变化了,data没有变化
//data:{n:0},重新对data赋值,data变化了
3.3 'deep:true'选项
你可以利用Vue提供的'deep:true'选项来控制数据的变化
new Vue({
data:{
obj:{
n:0
m:0
}
},
watch:{
n(){},
m(){},
obj:{
handler(){}
deep:true
}
}
})
//添加'deep:true'选项后,如果n或m变化了,obj也随之变化了