一、项目基础介绍

项目:vue3+ts

vue+ts项目,想要使用watch

需要安装:vue-property-decorator

yarn add vue-property-decorator

二、普通监听

// 实现基础的监听
<template>
  <div class="home">
    <div>watch</div>
    <div>
      <el-input v-model="data1" placeholder="Please input" />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import { Watch } from 'vue-property-decorator'

export default class Home extends Vue {
  public data1 = '11'
  @Watch('data1')
  private onData1Change(value: boolean) {
    if (value) {
      console.log('15', value)
    }
  }
}
</script>

效果:

三、immediate(立即执行)

这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算。如果想要一开始就让他最初绑定的时候就执行:

<template>
  <div class="home">
    <div>watch</div>
    <div>
      <el-input v-model="data1" placeholder="Please input" />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import { Watch } from 'vue-property-decorator'

export default class Home extends Vue {
  public data1 = '初始值'
  @Watch('data1', { immediate: true, deep: true })
  private onData1Change(value: boolean) {
    if (value) {
      console.log('15', value)
    }
  }
}
</script>

效果: 

四、deep(深度监听)

watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听

data1里有一个name属性:

如果deep为false,那么name变化时候,监听data1,监听不到变化

如果deep为false,immediate为true,那么name变化时候,监听data1,可以监听到一次,后续变化监听不到

如果deep为true,那么name变化时候,监听data1,可以监听到变化

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

<template>
  <div class="home">
    <div>watch</div>
    <div>
      <el-input v-model="data1.name" placeholder="Please input" />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import { Watch } from 'vue-property-decorator'

export default class Home extends Vue {
  public data1 = {
    name: '初始值'
  }
  @Watch('data1', { immediate: true, deep: true })
  private onData1Change(value: any) {
    if (value) {
      console.log('15', value)
    }
  }
}
</script>

deep优化:

我们可以是使用字符串形式监听

<template>
  <div class="home">
    <div>watch</div>
    <div>
      <el-input v-model="data1.name" placeholder="Please input" />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import { Watch } from 'vue-property-decorator'

export default class Home extends Vue {
  public data1 = {
    name: '初始值'
  }
  @Watch('data1.name', { immediate: true })
  private onData1Change(value: any) {
    if (value) {
      console.log('15', value)
    }
  }
}
</script>

效果:

五、$watch(随时监听)

<template>
  <div class="home">
    <div>watch</div>
    <div>
      <el-button @click="watchStart">watchStart</el-button>
      <el-input v-model="data1.name" placeholder="Please input" />
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import { Watch } from 'vue-property-decorator'

export default class Home extends Vue {
  public data1 = {
    name: '初始值'
  }
  private watchStart(){
    this.$watch('data1', (value: any) => {
      console.log('20', value);
    },
    {
      deep: true
    })
  }
}
</script>

效果:

六、监听路由

<template>
  <div class="home">
    <div>watch</div>
    <div>
      <el-button @click="changeRouter">改变路由</el-button>
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import { Watch } from 'vue-property-decorator'
import { Router } from 'vue-router'

export default class Home extends Vue {
  public data1 = {
    name: '初始值'
  }
  @Watch('$route')
  private onRouteChange(route: Router) {
    console.log('21', route)
  }
  private changeRouter(){
    this.$router.push('/watch?id=1')
  }
}
</script>

 效果:

七、监听 props 传来的值

成功监听到了

八、欢迎交流指正

九、参考链接

vue3,父组件通过props传递异步数据,子组件接收不到问题_vue3 父组件数据变化传给子组件,子组件监听不到-CSDN博客

this.$watch 和组件的 watch 有什么区别_qq_36437172的博客-CSDN博客_this.$watch

vue-class-component使用watch - (⊙o⊙)买噶 - 博客园

vue的watch和$watch(深度监听)_阿发今年二十八的博客-CSDN博客_vue watch和$watch