开发中我们在 data 返回的对象中定义了数据,这个数据通过插值语法等方式绑定到 template 中

当数据变化时,template 会自动进行更新来显示最新的数据

但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用侦听器 watch 来完成

代码演示:

<body>

<div id="app">
<h2>{{message}}</h2>
<button @click="changeMessage">修改message</button>
</div>

<script src="../lib/vue.js"></script>
<script>
// Proxy -> Reflect
// 1.创建app
const app = Vue.createApp({
// data: option api
data() {
return {
message: "Hello Vue",
info: { name: "fredo", age: 18 }
}
},
methods: {
changeMessage() {
this.message = "你好啊, 李银河!"
this.info = { name: "kobe" }
}
},
watch: {
// 1.默认有两个参数: newValue/oldValue
message(newValue, oldValue) {
console.log("message数据发生了变化:", newValue, oldValue)
},
info(newValue, oldValue) {
// 2.如果是对象类型, 那么拿到的是代理对象
// console.log("info数据发生了变化:", newValue, oldValue)
// console.log(newValue.name, oldValue.name)

// 3.获取原生对象
// console.log({ ...newValue })
console.log(Vue.toRaw(newValue))
}
}
})

// 2.挂载app
app.mount("#app")
</script>
</body>

配置选项

当我们只修改一个属性 info.name 的值, 这个时候使用 watch 来侦听 info,是不可以侦听到的

  • 这是因为默认情况下,watch 只是在侦听 info 的引用变化,对于内部属性的变化是不会做出响应的
  • 这个时候我们可以使用一个选项 deep 进行更深层的侦听
  • watch 里面侦听的属性对应的也可以是一个 Object

还有另外一个属性,是希望一开始的就会立即执行一次

  • 使用 immediate 选项
  • 无论后面数据是否有变化,侦听的函数都会有限执行一次

代码演示:

<body>

<div id="app">
<h2>{{ info.name }}</h2>
<button @click="changeInfo">修改info</button>
</div>

<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data() {
return {
info: { name: "fredo", age: 18 }
}
},
methods: {
changeInfo() {
// 1.创建一个新对象, 赋值给info
// this.info = { name: "kobe" }

// 2.直接修改原对象某一个属性
this.info.name = "kobe"
}
},
watch: {
// 默认 watch 监听不会进行深度监听
// info(newValue, oldValue) {
// console.log("侦听到info改变:", newValue, oldValue)
// }

// 进行深度监听
info: {
handler(newValue, oldValue) {
console.log("侦听到info改变:", newValue, oldValue)
console.log(newValue === oldValue)
},
// 监听器选项:
// info进行深度监听
deep: true,
// 第一次渲染直接执行一次监听器
immediate: true
},
"info.name": function(newValue, oldValue) {
console.log("name发生改变:", newValue, oldValue)
}
}
})

// 2.挂载app
app.mount("#app")
</script>
</body>

其他方式

可以在 created 的生命周期中,使用 this.$watchs 来侦听

  • 第一个参数是要侦听的源
  • 第二个参数是侦听的回调函数 callback
  • 第三个参数是额外的其他选项,比如 deep、immediate
// 生命周期回调函数: 当前的组件被创建时自动执行
// 一般在该函数中, 会进行网络请求
created() {
// ajax/fetch/axios
console.log("created")

this.$watch("message", (newValue, oldValue) => {
console.log("message数据变化:", newValue, oldValue)
}, { deep: true })
}