Scene
The code is roughly as follows, and a lot of irrelevant content has been deleted.
<template> <div> <SearchBar @search="handleSearch" /> <Pagination v-model:page="" :page-size="" :total="" /> </div> </template> <script setup lang="ts"> import { reactive, ref, watch, inject, computed } from 'vue' import SearchBar from '@/components/' const route = useRoute() const pagination = reactive({ page: 1, pageSize: ? 10 : 9, total: 0, }) const keyword = ref('') const fetchList = async () => { = true const res = await (`/api/${}`, { params: { pageSize: , page: , name: , }, }) = = false } watch( () => , async () => { = 1 fetchList() }, { immediate: true } ) watch( () => , async () => { fetchList() } ) watch( () => , async () => { if ( === 1) fetchList() else { = 1 } } ) const handleSearch = (val: string) => { = val } const handleDelete = async (item: MindMapItem) => { await ?.confirm() await ('/api/map/' + item._id) fetchList() } </script>
Originally there were only 2 watches, but today I added a keyword search for the new function, so I have to do morewatch
one。
So here it becomes 3 watches, and there is logic, even interdependent logic.
The above code has not been written, but after sorting it out, the final goal is as follows:
- There are three variables for the request parameter: keyword and pagination
- When changing, you need to reset pagination and keyword, and then re-request
- When keyword changes, you need to remake the pagination and then re-request it.
- Request is required when pagination changes
Watch is really good?
If you continue to use watch, because you need to reset the pagination and keyword, you can write the three watches into a task delegate effect. For example, if the page is 1 when modifying, you will directly request it, otherwise modify the page and let the page watch trigger the request.
watch( () => , async () => { if ( === 1) fetchList() else { = 1 } } )
Is this coupling really good? This is not good. I advised myself to reflect on it carefully.
The conclusion is:watch
Not a good civilization, can you not use itwatch
, don't use itwatch
。
This is not the first time I've beenwatch
I have opinions, and I have seen more than 5 complex components in my workwatch
, some have complex logic.
What's the point? Not commented yet...watch
It is natural that people don’t write comments, giving people a sense of “Ah, this value has changed, it’s natural to run the logic below.” Then ask yourself two months later, is this really the case? Can you understand the watch you wrote yourself? A value changes will trigger logic, but the problem is that there are many reasons for it to change.
sowatch
Born to be semantically unclear, it only explains the dependence on values, but does not explain the reason for dependence.
What about watchEffect?
The above example, iffetchList
WrittenwatchEffect
, in fact, it is still the same problem. You need to add if else to handle reset logic. But the logic is concentrated in onewatchEffect
It's probably better than scattering among N watches.
Summarize
To sum up, watch orwatchEffect
It has its place to work, but it is best to meet the following conditions:
- Only if the change trigger point is greater than 2
watch
(If there is only one trigger opportunity, just when to use it and when to run it) - All scenarios apply to the same processing logic
- Not coupled with other watches
However, if there is no event mechanism to trigger it, then it can onlywatch
Now.
After optimization
<template> <div> <SearchBar @search="handleSearch" /> <Pagination v-model:page="" @update:page="fetchList" :page-size="" :total="" /> </div> </template> <script setup lang="ts"> import { reactive, ref, watch, inject, computed } from 'vue' import SearchBar from '@/components/' const route = useRoute() const pagination = reactive({ page: 1, pageSize: ? 10 : 9, total: 0, }) const keyword = ref('') const fetchList = async () => { // Omitted } watch( () => , async () => { = '' = 1 fetchList() }, { immediate: true } ) const handleSearch = (val: string) => { = val = 1 fetchList() } const handleDelete = async (item: MindMapItem) => { await ?.confirm() await ('/api/map/' + item._id) fetchList() } </script>
After modification, only retainof
watch
, there will be no conflict, and the other two are triggered by events. As for triggering events, there is no need to write additional words.@change
, use it directly@update:xxx
That's it.
This way there is only easy-to-read reset logic, no if else! Refreshing!
This is the article about the need to analyze the necessity of using watch in Vue and its optimization. For more related Vue watch content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!