Vue3 - Chapter 6 (Listeners: watch, watchEffect)


1. Basic use of watch

  • In the composite API, we can use the watch function to trigger a callback function every time the reactive state changes:
    insert image description here

2. Listening data source type

  • The first parameter of watch can be a "data source" in different forms: it can be a ref (including computed properties), a reactive object, a getter function, or an array of multiple data sources:
    insert image description here
  • Note that you cannot directly listen to property values ​​of reactive objects, for example:
    insert image description here
  • Here you need to use a getter function that returns the property:
    insert image description here

3. Deep Listener

  • Passing a reactive object directly to watch() will implicitly create a deep listener - the callback function will be triggered on all nested changes:
    insert image description here
  • In contrast, a getter function that returns a reactive object will only trigger a callback if it returns a different object:
    insert image description here
  • It is also possible to explicitly add the deep option to the above example to force a deep listener:
    insert image description here
  • 谨慎使用深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

Fourth, watchEffect()

  • watch() is lazy: the callback is only executed when the data source changes.
  • But in some scenarios, we want to execute the callback immediately when the listener is created.
  • Say, for example, we want to request some initial data, then re-request the data when the relevant state changes.
    insert image description here
  • We can use the watchEffect function to simplify the above code.
  • watchEffect() will execute the callback function immediately. If the function produces side effects at this time, Vue will automatically track the dependencies of the side effects and automatically analyze the source of the response.
    insert image description here
  • In this example, the callback is executed immediately.
  • During execution, it automatically tracks url.value as a dependency (similar to the behavior of computed properties). Whenever url.value changes, the callback will be executed again.
  • watchEffect 仅会在其同步执行期间,才追踪依赖。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被追踪。

五、watch vs. watchEffect

  • Both watch and watchEffect can reactively execute callbacks with side effects.
  • The main difference between them is the way reactive dependencies are tracked:
  • watch : Only trace data sources that are explicitly listened to. It doesn't track anything accessed in the callback. Also, the callback is only fired when the data source actually changes. watch will avoid tracking dependencies when side effects occur, so we can more precisely control when the callback function is triggered.
  • watchEffect: will track dependencies during side effects. It will automatically track all accessible reactive properties during synchronous execution. This is more convenient, and the code tends to be cleaner, but sometimes its responsive dependencies are less explicit.

6. Trigger timing of callback

  • When you change the reactive state, it may trigger both Vue component updates and listener callbacks.
  • By default, user-created listener callbacks are called before any Vue components are updated. This means that the DOM you access in the listener callback will be the state before it was updated by Vue.
  • If you want to be able to access the DOM after being updated by Vue in the listener callback, you need to specify the flush: 'post' option:
    insert image description here
  • The post-refresh watchEffect() has a more convenient alias watchPostEffect():
    insert image description here

Seven, stop the listener

  • A listener created with a synchronous statement in setup() or <script setup> will be automatically bound to the host component instance, and will automatically stop when the host component is unloaded.
  • Therefore, in most cases, you don't need to care about how to stop a listener.
  • One key point is that listeners must be created with synchronous statements: if you create a listener with an asynchronous callback, then it will not be bound to the current component and you must stop it manually to prevent memory leaks.
    insert image description here
  • To manually stop a listener, call the function returned by watch or watchEffect:
    insert image description here
  • Note that there are very few cases where listeners need to be created asynchronously, so choose synchronous creation whenever possible. If you need to wait for some asynchronous data, you can use conditional listening logic:
    insert image description here

Guess you like

Origin blog.csdn.net/weixin_44733660/article/details/128629688