在类组件中提供装饰器 @Watch
对需要侦听的类属性进行描述,@Watch
的参数 1 是被侦听的属性名,参数 2 是一个可选的选项列表,分别是deep
、flush
、immediate
。
vue
<script lang="ts">
import { Component, Watch, Vue } from 'vue-facing-decorator';
@Component
export default class App extends Vue {
userName = 'admin';
passWord = '123456';
@Watch('userName')
userNameWatcher(newValue: string, oldValue: string) {
console.table([
{ '': 'userName', newValue: newValue, oldValue: oldValue },
]);
}
@Watch('passWord')
passWordWatcher(newValue: string, oldValue: string) {
console.table([
{ '': 'passWord', newValue: newValue, oldValue: oldValue },
]);
}
}
</script>
<template>
<div>
<p>UserName:<input v-model="userName" /></p>
<p>PassWord:<input v-model="passWord" /></p>
</div>
</template>
<script lang="ts">
import { Component, Watch, Vue } from 'vue-facing-decorator';
@Component
export default class App extends Vue {
userName = 'admin';
passWord = '123456';
@Watch('userName')
userNameWatcher(newValue: string, oldValue: string) {
console.table([
{ '': 'userName', newValue: newValue, oldValue: oldValue },
]);
}
@Watch('passWord')
passWordWatcher(newValue: string, oldValue: string) {
console.table([
{ '': 'passWord', newValue: newValue, oldValue: oldValue },
]);
}
}
</script>
<template>
<div>
<p>UserName:<input v-model="userName" /></p>
<p>PassWord:<input v-model="passWord" /></p>
</div>
</template>
深度监听
在面对普通的类属性时可以不指定任何的可选选项,但是对于对象类型的类属性来说,就必须用到 deep
选项了,作用同 vue option api。
vue
<script lang="ts">
import { Component, Watch, Vue } from 'vue-facing-decorator';
@Component
export default class App extends Vue {
login = {
userName: 'admin',
passWord: '123456',
};
@Watch('login', {
deep: true,
})
userNameWatcher(newValue: any, oldValue: any) {
console.log(newValue, oldValue);
}
}
</script>
<template>
<div>
<p>UserName:<input v-model="login.userName" /></p>
<p>PassWord:<input v-model="login.passWord" /></p>
</div>
</template>
<script lang="ts">
import { Component, Watch, Vue } from 'vue-facing-decorator';
@Component
export default class App extends Vue {
login = {
userName: 'admin',
passWord: '123456',
};
@Watch('login', {
deep: true,
})
userNameWatcher(newValue: any, oldValue: any) {
console.log(newValue, oldValue);
}
}
</script>
<template>
<div>
<p>UserName:<input v-model="login.userName" /></p>
<p>PassWord:<input v-model="login.passWord" /></p>
</div>
</template>
回调触发时机
当响应式的状态发生改变后,除了会触发侦听器以外还会触发 Vuejs 组件更新,也就是会触发 beforeUpdate
和 updated
生命周期。默认情况下执行的先后顺序是:Watcher
=> beforeUpdate
=> updated
,但是如果需要再 Watcher
中对更新前的 DOM 进行访问和操作时,就需要指定 flush 选项值为 post,这时的执行先后顺序就变更为:beforeUpdate
=> Watcher
=> updated
。
vue
<script lang="ts">
import { Component, Watch, Vue } from 'vue-facing-decorator';
@Component
export default class App extends Vue {
userName = 'admin';
@Watch('userName', {
flush: 'post'
})
userNameWatcher(newValue: any, oldValue: any) {
console.log(newValue, oldValue);
}
beforeUpdate() {
console.log('beforeUpdate')
}
updated() {
console.log('updated')
}
}
</script>
<template>
<div>
<p>UserName:<input id="username" v-model="userName" /></p>
</div>
</template>
<script lang="ts">
import { Component, Watch, Vue } from 'vue-facing-decorator';
@Component
export default class App extends Vue {
userName = 'admin';
@Watch('userName', {
flush: 'post'
})
userNameWatcher(newValue: any, oldValue: any) {
console.log(newValue, oldValue);
}
beforeUpdate() {
console.log('beforeUpdate')
}
updated() {
console.log('updated')
}
}
</script>
<template>
<div>
<p>UserName:<input id="username" v-model="userName" /></p>
</div>
</template>
立即执行的侦听器
侦听器默认情况下仅在响应状态发生变化时才会触发回调,但某些场景下会需要在侦听器被创建后就立即执行一次,比如说根据默认的响应状态要做一遍数据的筛选等等。
typescript
@Watch('userName', {
immediate: true,
})
userNameWatcher(newValue: any, oldValue: any) {
console.log(newValue, oldValue);
}
@Watch('userName', {
immediate: true,
})
userNameWatcher(newValue: any, oldValue: any) {
console.log(newValue, oldValue);
}