介绍
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
您的问题: <input type="text" v-model="question">
<!-- <button @click="queryAnswer">查找答案</button> -->
</template>
<script src="https://unpkg.com/vue@next"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
// 侦听question的变化时, 去进行一些逻辑的处理(JavaScript, 网络请求)
question: "Hello World",
anwser: ""
}
},
watch: {
// question侦听的data中的属性的名称
// newValue变化后的新值
// oldValue变化前的旧值
question: function(newValue, oldValue) {
console.log("新值: ", newValue, "旧值", oldValue);
this.queryAnswer();
}
},
methods: {
queryAnswer() {
console.log(`你的问题${this.question}的答案是哈哈哈哈哈`);
this.anwser = "";
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
2个配置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{info.name}}</h2>
<button @click="changeInfo">改变info</button>
<button @click="changeInfoName">改变info.name</button>
<button @click="changeInfoNbaName">改变info.nba.name</button>
</template>
<script src="https://unpkg.com/vue@next"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
info: { name: "why", age: 18, nba: {name: 'kobe'} }
}
},
watch: {
// 默认情况下我们的侦听器只会针对监听的数据本身的改变(内部发生的改变是不能侦听)
// info(newInfo, oldInfo) {
// console.log("newValue:", newInfo, "oldValue:", oldInfo);
// }
// 深度侦听/立即执行(一定会执行一次)
info: {
handler: function(newInfo, oldInfo) { // handler 是固定写法,表示监听后怎么处理
console.log("newValue:", newInfo.nba.name, "oldValue:", oldInfo.nba.name);
},
deep: true, // 配置一:深度侦听,可以监听对象里面的N层对象的变化,默认为false
immediate: true // 配置二:立即执行,就是一开始会执行一次,不管有没有编号,默认为false
}
},
methods: {
changeInfo() {
this.info = {name: "kobe"};
},
changeInfoName() {
this.info.name = "kobe";
},
changeInfoNbaName() {
this.info.nba.name = "james";
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
其他方式
======================
组件监听(常用)
一般都是通过父组件传值给子组件,子组件里面监听Prop属性
======================
Vue3写法
watchEffect 数据变化时执行
组件创建完成后会执行一遍watchEffect内的函数,写在里面的响应式对象(如上图的name),会被收集,后面这个对象的响应式内容发生变化,就会再运行watchEffect内的函数。
一开始一定会调用一次,如果你不想这样(因为可能会有一大堆代码无效率得执行一遍),可以用watch。
停止监听
停止监听前(清除副作用)
每次监听变化,总会先调用一个函数,来让你处理事情。
假如在监听某个变化然后执行代码A,代码A执行过程中,就stop停止监听了,这时你要对代码A还没执行完的部分进行处理
上面的例子是,不停点击时,会不停清理上面设定的setTimeout的时间,直到不点击的时候,才会执行显示setTimeout
执行时机
post就是等DOM挂载完后再开始执行监听
追踪 onTrack 和 触发 onTrigger
watch 某个数据变化时执行
第一个参数可以是以下几种类型
情况一: 第一个参数是reactive对象,获取到的newValue和oldValue本身都是reactive对象
情况二: 第一个参数是ref对象,获取newValue和oldValue是value值的本身
监听多个
可以写多个watch
或者 写在一起
想把newValue和oldValue变成普通对象,和上面一样用解构
追踪 onTrack 和 触发 onTrigger
参考watchEffect 的,一样的
停止监听
停止监听前
参考watchEffect 的,一样的
监听的深度
deep为true时,不管监听的对象内部有多少层,都会进行监听
源码那里,如果监听的对象是reactive,那么默认是深度监听