第
Vue中的侦听器及使用场景
目录基本示例?深层侦听器?即时回调的侦听器?回调的触发时机?this.$watch()?停止侦听器?
基本示例?
计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些副作用:例如更改DOM,或是根据异步操作的结果去修改另一处的状态。
在选项式API中,我们可以使用watch选项在每次响应式属性发生变化时触发一个函数。
exportdefault{
data(){
return{
question:,
answer:Questionsusuallycontainaquestionmark.;-)
watch:{
//每当question改变时,这个函数就会执行
question(newQuestion,oldQuestion){
if(newQuestion.includes()){
this.getAnswer()
methods:{
asyncgetAnswer(){
this.answer=Thinking...
try{
constres=awaitfetch(https://yesno.wtf/api)
this.answer=(awaitres.json()).answer
}catch(error){
this.answer=Error!CouldnotreachtheAPI.+error
}
p
Askayes/noquestion:
inputv-model=question/
p{{answer}}/p
watch选项也支持把键设置成用.分隔的路径:
exportdefault{
watch:{
//注意:只能是简单的路径,不支持表达式。
some.nested.key(newValue){
//...
}
深层侦听器?
watch默认是浅层的:被侦听的属性,仅在被赋新值时,才会触发回调函数而嵌套属性的变化不会触发。如果想侦听所有嵌套的变更,你需要深层侦听器:
exportdefault{
watch:{
someObject:{
handler(newValue,oldValue){
//注意:在嵌套的变更中,
//只要没有替换对象本身,
//那么这里的`newValue`和`oldValue`相同
deep:true
}
谨慎使用
深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。
即时回调的侦听器?
watch默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。
我们可以用一个对象来声明侦听器,这个对象有handler方法和immediate:true选项,这样便能强制回调函数立即执行:
exportdefault{
//...
watch:{
question:{
handler(newQuestion){
//在组件实例创建时会立即调用
//强制立即执行回调
immediate:true
//...
}
回调函数的初次执行就发生在created钩子之前。Vue此时已经处理了data,computed和methods选项,所以这些属性在第一次调用时就是可用的。
回调的触发时机?
当你更改了响应式状态,它可能会同时触发Vue组件更新和侦听器回调。
默认情况下,用户创建的侦听器回调,都会在Vue组件更新之前被调用。这意味着你在侦听器回调中访问的DOM将是被Vue更新之前的状态。
如果想在侦听器回调中能访问被Vue更新之后的DOM,你需要指明flush:post选项:
exportdefault{
//...
watch:{
key:{
handler(){},
flush:post
}
this.$watch()?
我们也可以使用组件实例的$watch()方法来命令式地创建一个侦听器:
exportdefault