|
28 | 28 |
|
29 | 29 | # Ignorable watch
|
30 | 30 |
|
31 |
| -[VueUse's `useRefHistory`](https://vueuse.js.org/?path=/story/utilities--userefhistory) lets you watch a ref and keep track of its history, providing undo and redo functionality. It uses `flush 'pre'` by default to watching the source ref. Its semantics are aligned with the standard `watch`, creating history points that bundle all the changes done to the source value during the same "tick". The use of `flush 'sync'` is discouraged in the [Vue docs](https://v3.vuejs.org/guide/reactivity-computed-watchers.html#effect-flush-timing). Being able to buffers invalidated effects is important for performance, but also to avoid breaking invariants when generating spurious history points in updates that require several operations. One big caveat for example is that when deeply sync watching an array, a single splice call generates up to three triggers. |
| 31 | +[VueUse's `useRefHistory`](https://vueuse.org/core/useRefHistory/) lets you watch a ref and keep track of its history, providing undo and redo functionality. It uses `flush 'pre'` by default to watching the source ref. Its semantics are aligned with the standard `watch`, creating history points that bundle all the changes done to the source value during the same "tick". The use of `flush 'sync'` is discouraged in the [Vue docs](https://v3.vuejs.org/guide/reactivity-computed-watchers.html#effect-flush-timing). Being able to buffers invalidated effects is important for performance, but also to avoid breaking invariants when generating spurious history points in updates that require several operations. One big caveat for example is that when deeply sync watching an array, a single splice call generates up to three triggers. |
32 | 32 |
|
33 | 33 | Let's look at a simplified `useUndo` composable that only allows undoing of ref changes to understand how we were able to do it and how `ignorableWatch` was distilled so we can use the same technique when building other composables. The main difficulty to implement ref history is how to update the source when undoing without triggering the internal watch and re-adding this state to the history. If we only need to support sync flushing, it can be implemented in a straight forward way using a guard.
|
34 | 34 |
|
@@ -114,9 +114,9 @@ function ignorableWatch(source,cb,options) {
|
114 | 114 | ```
|
115 | 115 | The syncCount is incremented in sync with every change to the source ref value using a watch with `flush 'sync'`. This lets us know how many times the ref has been modified in this "tick". When calling `ignoreUpdates`, all sync changes to the source in the updater function will be counted and added to the `ignoreCount`. When the second watch flushes at the end of the tick, we know if there were more changes done to the source than the ones that were ignored so we can filter out the triggered effect if all the changes in the "tick" were marked to be ignored.
|
116 | 116 |
|
117 |
| -[VueUse's `ignorableWatch`](https://vueuse.js.org/?path=/story/watch--ignorablewatch) follows this idea supporting all flush modes. It is [implemented](https://github.com/antfu/vueuse/blob/master/packages/shared/ignorableWatch/index.ts) using the double watch scheme for flush `'pre'` and `'post'`, a sync watch allows us to count changes and ignore the triggered effect if all operations were flagged to be ignored in the current "tick". For `'sync'`, a single watch with a guard is used to implement `ignoreUpdates` and `ignorePrevAsyncUpdates` is a no-op provided so users can write generic code that does not depend on the `flush` mode. |
| 117 | +[VueUse's `ignorableWatch`](https://vueuse.org/shared/watchignorable/) follows this idea supporting all flush modes. It is [implemented](https://github.com/vueuse/vueuse/blob/main/packages/shared/watchIgnorable/index.ts) using the double watch scheme for flush `'pre'` and `'post'`, a sync watch allows us to count changes and ignore the triggered effect if all operations were flagged to be ignored in the current "tick". For `'sync'`, a single watch with a guard is used to implement `ignoreUpdates` and `ignorePrevAsyncUpdates` is a no-op provided so users can write generic code that does not depend on the `flush` mode. |
118 | 118 |
|
119 |
| -There is a related utility in VueUse called [pausableWatch](https://vueuse.js.org/?path=/story/watch--pausablewatch) that exposes two methods `pause()` and `resume()` allowing to ignore the watch while it is paused. `ignorableWatch` is different from it because in `pausableWatch` effects are ignored if the watch is paused at flush time. |
| 119 | +There is a related utility in VueUse called [pausableWatch](https://vueuse.org/shared/watchPausable/) that exposes two methods `pause()` and `resume()` allowing to ignore the watch while it is paused. `ignorableWatch` is different from it because in `pausableWatch` effects are ignored if the watch is paused at flush time. |
120 | 120 |
|
121 | 121 | ```js{2,5,8-10,12-13}
|
122 | 122 | const source = ref(0)
|
@@ -180,7 +180,7 @@ function useUndo(source, options) {
|
180 | 180 | }
|
181 | 181 | ```
|
182 | 182 |
|
183 |
| -You can check the [implementation of `useRefHistory`](https://github.com/antfu/vueuse/blob/master/packages/core/useRefHistory/index.ts) to see how `ignorableWatch` is used in the lib. In it, other useful features to deal with ref history are provided. |
| 183 | +You can check the [implementation of `useRefHistory`](https://github.com/vueuse/vueuse/blob/main/packages/core/useRefHistory/index.ts) to see how `ignorableWatch` is used in the lib. In it, other useful features to deal with ref history are provided. |
184 | 184 |
|
185 | 185 | I learned about the importance of `flush 'pre'` while developing undo support for [Layoutit Grid](https://github.com/Leniolabs/layoutit-grid). I was later able to upstream some of this experience to [VueUse](https://github.com/antfu/vueuse), and `ignorableWatch` was spawned organically as part of this process. This is a good example of how working in Apps using [Vue Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html) facilitates the discovery and sharing of reusable pieces.
|
186 | 186 |
|
|
0 commit comments