介绍

image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <template id="my-app">
  12. 您的问题: <input type="text" v-model="question">
  13. <!-- <button @click="queryAnswer">查找答案</button> -->
  14. </template>
  15. <script src="https://unpkg.com/vue@next"></script>
  16. <script>
  17. const App = {
  18. template: '#my-app',
  19. data() {
  20. return {
  21. // 侦听question的变化时, 去进行一些逻辑的处理(JavaScript, 网络请求)
  22. question: "Hello World",
  23. anwser: ""
  24. }
  25. },
  26. watch: {
  27. // question侦听的data中的属性的名称
  28. // newValue变化后的新值
  29. // oldValue变化前的旧值
  30. question: function(newValue, oldValue) {
  31. console.log("新值: ", newValue, "旧值", oldValue);
  32. this.queryAnswer();
  33. }
  34. },
  35. methods: {
  36. queryAnswer() {
  37. console.log(`你的问题${this.question}的答案是哈哈哈哈哈`);
  38. this.anwser = "";
  39. }
  40. }
  41. }
  42. Vue.createApp(App).mount('#app');
  43. </script>
  44. </body>
  45. </html>

2个配置

image.png

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <template id="my-app">
  12. <h2>{{info.name}}</h2>
  13. <button @click="changeInfo">改变info</button>
  14. <button @click="changeInfoName">改变info.name</button>
  15. <button @click="changeInfoNbaName">改变info.nba.name</button>
  16. </template>
  17. <script src="https://unpkg.com/vue@next"></script>
  18. <script>
  19. const App = {
  20. template: '#my-app',
  21. data() {
  22. return {
  23. info: { name: "why", age: 18, nba: {name: 'kobe'} }
  24. }
  25. },
  26. watch: {
  27. // 默认情况下我们的侦听器只会针对监听的数据本身的改变(内部发生的改变是不能侦听)
  28. // info(newInfo, oldInfo) {
  29. // console.log("newValue:", newInfo, "oldValue:", oldInfo);
  30. // }
  31. // 深度侦听/立即执行(一定会执行一次)
  32. info: {
  33. handler: function(newInfo, oldInfo) { // handler 是固定写法,表示监听后怎么处理
  34. console.log("newValue:", newInfo.nba.name, "oldValue:", oldInfo.nba.name);
  35. },
  36. deep: true, // 配置一:深度侦听,可以监听对象里面的N层对象的变化,默认为false
  37. immediate: true // 配置二:立即执行,就是一开始会执行一次,不管有没有编号,默认为false
  38. }
  39. },
  40. methods: {
  41. changeInfo() {
  42. this.info = {name: "kobe"};
  43. },
  44. changeInfoName() {
  45. this.info.name = "kobe";
  46. },
  47. changeInfoNbaName() {
  48. this.info.nba.name = "james";
  49. }
  50. }
  51. }
  52. Vue.createApp(App).mount('#app');
  53. </script>
  54. </body>
  55. </html>

其他方式

image.png

image.png

image.png

======================

组件监听(常用)

一般都是通过父组件传值给子组件,子组件里面监听Prop属性

======================

Vue3写法

image.png

watchEffect 数据变化时执行

image.png
组件创建完成后会执行一遍watchEffect内的函数,写在里面的响应式对象(如上图的name),会被收集,后面这个对象的响应式内容发生变化,就会再运行watchEffect内的函数。

一开始一定会调用一次,如果你不想这样(因为可能会有一大堆代码无效率得执行一遍),可以用watch。

停止监听

image.png

停止监听前(清除副作用)

每次监听变化,总会先调用一个函数,来让你处理事情。

假如在监听某个变化然后执行代码A,代码A执行过程中,就stop停止监听了,这时你要对代码A还没执行完的部分进行处理
image.png

image.png
上面的例子是,不停点击时,会不停清理上面设定的setTimeout的时间,直到不点击的时候,才会执行显示setTimeout

执行时机

image.png
image.png
image.png
post就是等DOM挂载完后再开始执行监听
image.png

追踪 onTrack 和 触发 onTrigger

image.png

watch 某个数据变化时执行

image.png
image.png
第一个参数可以是以下几种类型
image.png

情况一: 第一个参数是reactive对象,获取到的newValue和oldValue本身都是reactive对象
image.png
情况二: 第一个参数是ref对象,获取newValue和oldValue是value值的本身

监听多个

可以写多个watch
image.png
或者 写在一起
image.png
image.png
想把newValue和oldValue变成普通对象,和上面一样用解构
image.png

追踪 onTrack 和 触发 onTrigger

参考watchEffect 的,一样的

停止监听

停止监听前

参考watchEffect 的,一样的
image.png

监听的深度

deep为true时,不管监听的对象内部有多少层,都会进行监听
image.png
源码那里,如果监听的对象是reactive,那么默认是深度监听

立刻执行

image.png