<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                >[success] # watchEffect 1. `watchEffect `是一個新的`api`,需要將這個單詞拆解來看`watch `和`effect `,**effect全稱叫side effect,副作用**。在watch里面進行異步請求,這個請求是隨時的不可控的這個就是一種副作用,所以可以理解成`watchEffect`的意思就是在觀察(watch)到變化后執行一些操作(effect) * `onTrack `和 `onTrigger `只能在開發模式下工作。可用于調試偵聽器的行為。`onTrack`作為依賴項被追蹤時被調用。`onTrigger `將在依賴項變更導致副作用被觸發時被調用。 * `flush : 'pre' | 'post' | 'sync' `默認是`pre`,`pre` 會在 Vue 組件更新**之前**被調用。這意味著你在偵聽器回調中訪問的 DOM 將是被 Vue 更新之前的狀態,`post`,在偵聽器回調中能訪問被 Vue 更新**之后**的 DOM,`sync` 是每一步都會觸發(實際vue 為了防止使用隊列緩沖回調。回調只會添加到隊列中一次,即使所監視的值更改了多次。中間值將被跳過,并且不會傳遞給回調,但`sync`是次次觸發) ,具體可[查看的案例參考](https://github.com/vuejs/core/issues/5721) ~~~ watchEffect(() => {}, { flush: 'post', onTrack(e) { debugger }, onTrigger(e) { debugger } }) ~~~ >[danger] ##### 特點 1. `watchEffect` 不需要指定監聽的屬性,監聽是立即執行的(**會默認初始時就會執行第一次, 從而可以收集需要監聽的數據**) 2. 調用返回值以停止偵聽 3. 傳入`watchEffect `函數可以接收一個 `onInvalidate `函數作入參,用來注冊清理失效時的回調,失效回調會被觸發 條件: * 副作用即將重新執行時 * 偵聽器被停止 (如果在 setup() 或生命周期鉤子函數中使用了 watchEffect,則在組件卸載時) 4. 調整`watchEffect`的執行時機,`watchEffect`立即執行時候`dom `還沒被渲染,可以調整執行時機來獲取`dom` * 沒有任何指定的屬性依然會執行下面案例運行后控制臺打印1,`watchEffect `需要先立即執行收集內部需要**被監聽的數據** ~~~ <template> <div> </div> </template> <script lang="ts"> import {ref, watchEffect} from 'vue' export default { setup() { const stop = watchEffect(()=>{ console.log(1) }) return { } } } </script> ~~~ * **自動只能收集是屬性**雖然會自動收集監聽但是,如果是一個`reactive `對象是不會觸發,**但是如果是其一個具體屬性值可以觸發** 第立即執行時候都執行,但第二次改變時候`info`的`watchEffect `沒觸發 ![](https://img.kancloud.cn/dd/2c/dd2cdcc9f7aac8f9bd033e0a6e7cd273_716x288.png) ~~~ <template> <button @click="changeInfo">change</button> </template> <script> import { watchEffect, ref, reactive } from '@vue/runtime-core' export default { name: 'App', setup() { const test = ref(1) const info = reactive({ name: 'w', hobbies: ['footer'] }) const changeTest = () => {} const changeInfo = () => { info.hobbies[0] = 'sleep' test.value = 12 } watchEffect(() => { console.log(info) }) watchEffect(() => { console.log(info.hobbies[0]) }) watchEffect(() => { console.log(test.value) }) return { test, info, changeInfo, changeTest, } }, } </script> <style></style> ~~~ >[danger] ##### 簡單案例 1. 下面代碼執行結果先打印**1 0 "w" ** 在一秒后打印 **8 1 10 "z"** ,因為`watchEffect `是立即執行因此先打印一次,在第一次立即執行的時候收集了需要監聽的響應屬性,在定時器1s后執行改變了監聽的響應數據,因此`watchEffect `**被觸發** ~~~ <template> <div> </div> </template> <script lang="ts"> import {ref, watchEffect} from 'vue' export default { setup() { const count = ref(0) const str = ref('w') const stop = watchEffect(()=>{ console.log(1,count.value,str.value) count.value = 100 }) setTimeout(()=>{ count.value = 10 str.value = "z" },1000) return { count } } } </script> ~~~ >[danger] ##### 調用返回值以停止偵聽 1. 在一些情況下,也可以顯式調用返回值以停止偵聽,下面案例只打印了**1 0 "w"** 在一秒后并沒有打印 **8 1 10 "z"**原因手動調用了**停止響應式監聽** ~~~ <template> <div> </div> </template> <script lang="ts"> import {ref, watchEffect} from 'vue' export default { setup() { const count = ref(0) const str = ref('w') const stop = watchEffect(()=>{ console.log(1,count.value,str.value) count.value = 100 }) // 停止了響應式監聽 stop() setTimeout(()=>{ count.value = 10 str.value = "z" },1000) return { count } } } </script> ~~~ >[danger] ##### 清除副作用 1. 回調函數還提供了參數,例如下面`onInvalidate `在沒有放開下面兩條注釋條件任意一個的時候`onInvalidate `不會執行,但是放開其中任意一個條件`onInvalidate `都將會執行,說明參數會在觸發監聽屬性改變前執行即,如果放開下面1s后執行的注釋控制臺打印的結果: ~~~ 1 0 "w" 執行回調 1 10 "z" ~~~ 所以`onInvalidate `觸發跟你放的順序無關 ~~~ <template> <div> </div> </template> <script lang="ts"> import {ref, watchEffect} from 'vue' export default { setup() { const count = ref(0) const str = ref('w') const stop = watchEffect((onInvalidate )=>{ console.log(1,count.value,str.value) onInvalidate(()=>{ console.log('執行回調') }) }) // 停止了響應式監聽 --偵聽器被停止觸發回調 // stop() // ---------------------- // setTimeout(()=>{ // 副作用即將重新執行時 // count.value = 10 // str.value = "z" // },1000) return { count } } } </script> ~~~ * 官網給了一個案例參考 1. 當請求 id 改變時候,請求接口,但是id 是高頻率變化,希望每次變化如果上次接口數據沒請求完則銷毀 ~~~ watchEffect(onInvalidate => { const token = performAsyncOperation(id.value) onInvalidate(() => { // id has changed or watcher is stopped. // invalidate previously pending async operation token.cancel() }) }) ~~~ >[danger] ##### 關于停止監聽說明 1. 除了手動觸發 停止監聽,實際同步語句創建的偵聽器會自動綁定到宿主組件實例上,并且會在宿主組件卸載時自動停止,所以不用擔心如果頁面已經銷毀了監聽還在內存中。 2. 但如果是異步創建 ,必須手動監聽例如下面例子 ~~~ <script setup> import { watchEffect } from 'vue' // 它會自動停止 watchEffect(() => {}) // ...這個則不會! setTimeout(() => { watchEffect(() => {}) }, 100) </script> ~~~ >[danger] ##### 雖然監聽是立即執行的但可控 1. 監聽雖然立即執行但是可以使用**條件式的偵聽邏輯** 來控制內部代碼 ~~~ // 需要異步請求得到的數據 const data = ref(null) watchEffect(() => { if (data.value) { // 數據加載后執行某些操作... } }) ~~~ >[danger] ##### 渲染 是獲取不到dom 1. 默認情況下,用戶創建的偵聽器回調,都會在 Vue 組件更新之前被調用。這意味著你在偵聽器回調中訪問的DOM 將是被 Vue 更新之前的狀態 ~~~ <template> <div ref="test"></div> </template> <script> import { watchEffect, ref } from '@vue/runtime-core' export default { name: 'App', setup() { const test = ref(null) watchEffect(() => { console.log(test.value) }) return { test, } }, } </script> <style></style> ~~~ * 如圖 ~~~ 1第一次執行時候dom 還沒掛載此時獲取為null,當掛載上后再次觸發此時為dom元素 ~~~ ![](https://img.kancloud.cn/14/56/1456d9bf1be18cd1a5b42664512950d5_278x68.png) * 解決上面方法 ~~~ watchEffect(()=>{.....}, { flush: 'post' }) 或者 import { watchPostEffect } from 'vue' watchPostEffect(() => { /* 在 Vue 更新后執行 */ }) 兩個都是在vue更新后執行此時第一次就能獲取dom ~~~ >[success] # watchPostEffect()[](https://cn.vuejs.org/api/reactivity-core.html#watchposteffect) [`watchEffect()`](https://cn.vuejs.org/api/reactivity-core.html#watcheffect)使用`flush: 'post'`選項時的別名。 >[success] # watchSyncEffect()[](https://cn.vuejs.org/api/reactivity-core.html#watchsynceffect) [`watchEffect()`](https://cn.vuejs.org/api/reactivity-core.html#watcheffect)使用`flush: 'sync'`選項時的別名。 >[info] ## 官網參考 [## watchEffect](https://cn.vuejs.org/api/reactivity-core.html#readonly) [## `watchEffect()`](https://cn.vuejs.org/guide/essentials/watchers.html#watcheffect)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看