中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue3.0中怎么使用watch

發布時間:2022-02-24 15:49:34 來源:億速云 閱讀:448 作者:iii 欄目:開發技術

這篇文章主要講解了“Vue3.0中怎么使用watch”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Vue3.0中怎么使用watch”吧!

Vue3.0中使用watch

watchVue3.0中并不是一個新的概念,在使用Vue2.x的時候,我們經常會使用watch來監聽Vue實例上面的一個表達式或者一個函數計算結果的變化。

回顧Vue2.0中的watch

在 Vue2.0 中,我們使用watch可以通過下面多種方式去監聽Vue實例上面的表達式或者函數計算結果的變化,如下羅列了其中的幾種

最常規使用方式

   export default {
     data() {
       return {
         name: '子君',
         info: {
           gzh: '前端有的玩'
         }
       }
     },
     watch: {
       name(newValue, oldValue) {
         console.log(newValue, oldValue)
       },
       'info.gzh': {
         handler(newValue, oldValue) {
           console.log(newValue, oldValue)
         },
         // 配置immediate會在watch之后立即執行
         immediate: true
       }
     }
   }

我們可以在watch屬性里面配置要監聽的Vue實例上面的屬性,也可以通過.鍵路徑去監聽對象中的某一個屬性的變化,也可以通過配置immediate在監聽后立即觸發,配置deep去深度監聽對象里面的屬性,不論嵌套層級有多深。

使用$watch監聽

除了常規的watch對象寫法之外,Vue實例上面提供了$watch方法,可以通過$watch更靈活的去監聽某一個屬性的變化。比如這樣一個場景,我們有一個表單,然后希望在用戶修改表單之后可以監聽到表單的數據變化。但是有一個特殊的場景,就是表單的回填數據是異步請求過來的,這時候我們希望在后臺請求完數據之后再去監聽變化,這時候就可以使用$watch。如下代碼所示:

   export default {
     methods: {
       loadData() {
         fetch().then(data => {
           this.formData = data
           this.$watch(
             'formData',
             () => {
               // formData數據發生變化后會進入此回調函數
             },
             {
               deep: true
             }
           )
         })
       }
     }
   }

監聽函數表達式

除了監聽字符串之外,$watch的第一個參數也可以是一個函數,當函數的返回值發生變化之后,觸發回調函數

   this.$watch(() => this.name, () => {
     // 函數的返回值發生變化,進入此回調函數
   })

上文中就是 Vue2.0 中我們使用watch的一些常用寫法,對于Vue3.0,因為其對 Vue2.0 做了部分的向下兼容,所以上面的用法在Vue3.0中基本都可以使用,但是Vue3.0一個很大的亮點就是composition API,所以除了 Vue2.0 中的寫法之外,也可以使用componsition api中提供的watch

Vue3.0中使用watch

Vue3.0中,除了 Vue2.0 的寫法之外,有兩個api可以對數據變化進行監聽,第一種是watch,第二種是watchEffect。對于watch,其與 Vue2.0 中的$watch用法基本是一模一樣的,而watchEffectVue3.0新提供的api

watch的用法

下面的示例演示了如何使用watch

import { watch, ref, reactive } from 'vue'
export default {
  setup() {
    const name = ref('子君')
    const otherName = reactive({
      firstName: '王',
      lastName: '二狗'
    })
    watch(name, (newValue, oldValue) => {
      // 輸出 前端有的玩 子君
      console.log(newValue, oldValue)
    })
    // watch 可以監聽一個函數的返回值
    watch(
      () => {
        return otherName.firstName + otherName.lastName
      },
      value => {
        // 當otherName中的 firstName或者lastName發生變化時,都會進入這個函數
        console.log(`我叫${value}`)
      }
    )


    setTimeout(() => {
      name.value = '前端有的玩'
      otherName.firstName = '李'
    }, 3000)
  }
}

watch除了可以監聽單個值或者函數返回值之外,也可以同時監聽多個數據源,比如下面代碼所示:

export default {
  setup() {
    const name = ref('子君')
    const gzh = ref('前端有的玩')
    watch([name, gzh], ([name, gzh], [prevName, prevGzh]) => {
      console.log(prevName, name)
      console.log(prevGzh, gzh)
    })


    setTimeout(() => {
      name.value = '前端有的玩'
      gzh.value = '關注我,一起玩前端'
    }, 3000)
  }
}
watchEffect的用法

watchEffect的用法與watch有所不同,watchEffect會傳入一個函數,然后立即執行這個函數,對于函數里面的響應式依賴會進行監聽,然后當依賴發生變化時,會重新調用傳入的函數,如下代碼所示:

import { ref, watchEffect } from 'vue'
export default {
  setup() {
    const id = ref('0')
    watchEffect(() => {
      // 先輸出 0 然后兩秒后輸出 1
      console.log(id.value)
    })


    setTimeout(() => {
      id.value = '1'
    }, 2000)
  }
}

停止執行

Vue2.0 中的$watch會在調用的時候返回一個函數,執行這個函數可以停止watch,如下代碼所示

   const unwatch = this.$watch('name',() => {})
   // 兩秒后停止監聽
   setTimeout(()=> {
     unwatch()
   }, 2000)

Vue3.0中,watchwatchEffect同樣也會返回一個unwatch函數,用于取消執行,比如下面代碼所示

   export default {
     setup() {
       const id = ref('0')
       const unwatch = watchEffect(() => {
         // 僅僅輸出0
         console.log(id.value)
       })

   
       setTimeout(() => {
         id.value = '1'
       }, 2000)
       // 1秒后取消watch,所以上面的代碼只會輸出0
       setTimeout(() => {
         unwatch()
       }, 1000)
     }
   }

清除副作用

想象一下這樣的一個場景,界面上面有兩個下拉框,第二個下拉框的數據是根據第一個下拉框的數據聯動的,當第一個下拉框數據發生變化后,第二個下拉框的數據會通過發送一個網絡請求進行獲取。這時候我們可以通過watchEffect來實現這個功能,比如像下面代碼這樣

      import { ref, watchEffect } from 'vue'


      function loadData(id) {
        return new Promise(resolve => {
          setTimeout(() => {
            resolve(
              new Array(10).fill(0).map(() => {
                return id.value + Math.random()
              })
            )
          }, 2000)
        })
      }


      export default {
        setup() {
          // 下拉框1 選中的數據
          const select1Id = ref(0)
          // 下拉框2的數據
          const select2List = ref([])
          watchEffect(() => {
            // 模擬請求
            loadData(select1Id).then(data => {
              select2List.value = data
              console.log(data)
            })
          })


          // 模擬數據發生變化
          setInterval(() => {
            select1Id.value = 1
          }, 3000)
        }
      }

現在假如我切換了一下第一個下拉框的數據之后,這時候數據請求已經發出,然后我將這個頁面切換到另一個頁面,因為請求已經發出,所以我希望在頁面離開的時候,可以結束這個請求,防止數據返回后出現異常,這時候就可以使用watchEffect為第一個回調函數傳入的入參來處理這個情況,如下代碼所示

      function loadData(id, cb) {
        return new Promise(resolve => {
          const timer = setTimeout(() => {
            resolve(
              new Array(10).fill(0).map(() => {
                return id.value + Math.random()
              })
            )
          }, 2000)
          cb(() => {
            clearTimeout(timer)
          })
        })
      }


      export default {
        setup() {
          // 下拉框1 選中的數據
          const select1Id = ref(0)
          // 下拉框2的數據
          const select2List = ref([])
          watchEffect(onInvalidate => {
            // 模擬請求
            let cancel = undefined
            // 第一個參數是一個回調函數,用于模擬取消請求,關于取消請求,可以了解axios的CancelToken
            loadData(select1Id, cb => {
              cancel = cb
            }).then(data => {
              select2List.value = data
              console.log(data)
            })
            onInvalidate(() => {
              cancel && cancel()
            })
          })
        }
      }

Vue3.0中使用計算屬性

想一想在 Vue2.0 中我們一般會用計算屬性做什么操作呢?我想最常見的就是當模板中有一個復雜計算的時候,可以先使用計算屬性進行計算,然后再在模板中使用,實際上,Vue3.0中的計算屬性的作用和 Vue2.0 的作用基本是一樣的。

Vue2.0中使用計算屬性

     computed: {
       getName() {
         const { firstName, lastName } = this.info
         return firstName + lastName
       }
     },

Vue3.0中使用計算屬性

   <template>
     <div class="about">
       <h2>{{ name }}</h2>
     </div>
   </template>
   <script>
   import { computed, reactive } from 'vue'


   export default {
     setup() {
       const info = reactive({
         firstName: '王',
         lastName: '二狗'
       })


       const name = computed(() => info.firstName + info.lastName)


       return {
         name
       }
     }
   }
   </script>

和 Vue2.0 一樣,Vue3.0的計算屬性也可以設置gettersetter,比如上面代碼中的計算屬性,只設置了getter,即加入cumputed傳入的參數是一個函數,那么這個就是getter,假如要設置setter,需要像下面這樣去寫

   export default {
     setup() {
       const info = reactive({
         firstName: '王',
         lastName: '二狗'
       })

   
       const name = computed({
         get: () => info.firstName + '-' + info.lastName,
         set(val) {
           const names = val.split('-')
           info.firstName = names[0]
           info.lastName = names[1]
         }
       })

   
       return {
         name
       }
     }
   }

Vue3.0中使用vue-router

初始化vue-router

在 Vue2.0 中我們使用vue-router的時候,會通過new VueRouter的方式去實現一個VueRouter實例,就像下面代碼這樣

import Vue from 'vue'
import VueRouter from 'vue-router'


Vue.use(VueRouter)
const router = new VueRouter({
  mode: 'history',
  routes: []
})
export default router

但到了Vue3.0,我們創建VueRouter的實例發生了一點點變化,就像Vue3.0main.js中初始化Vue實例需要像下面寫法一樣

import { createApp } from 'vue'
createApp(App).$mount('#app')

vue-router也修改為了這種函數的聲明方式

import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
  // vue-router有hash和history兩種路由模式,可以通過createWebHashHistory和createWebHistory來指定
  history: createWebHashHistory(),
  routes
})


router.beforeEach(() => {

  
})


router.afterEach(() => {

  
})
export default router

然后在main.js中,通過

 createApp(App).use(router)

來引用到Vue

setup中使用vue-router

在 Vue2.0 中,我們通過this.$route可以獲取到當前的路由,然后通過this.$router來獲取到路由實例來進行路由跳轉,但是在setup中,我們是無法拿到this的,這也意味著我們不能像 Vue2.0 那樣去使用vue-router, 此時就需要像下面這樣去使用

import { useRoute, useRouter} from 'vue-router'


export default {
  setup() {
    // 獲取當前路由
    const route = useRoute()
    // 獲取路由實例
    const router = useRouter()
    // 當當前路由發生變化時,調用回調函數
    watch(() => route, () => {
      // 回調函數
    }, {
      immediate: true,
      deep: true
    })

    
    // 路由跳轉
    function getHome() {
      router.push({
        path: '/home'
      })
    }

    
    return {
      getHome()
    }
  }
}

上面代碼我們使用watch來監聽路由是否發生變化,除了watch之外,我們也可以使用vue-router提供的生命周期函數

import { onBeforeRouteUpdate, useRoute } from 'vue-router'
export default {
  setup() {
    onBeforeRouteUpdate(() => {
      // 當當前路由發生變化時,調用回調函數
    })
  }
}

除了onBeforeRouteUpdate之外,vue-router在路由離開的時候也提供了一個生命周期鉤子函數

onBeforeRouteLeave(() => {
   console.log('當當前頁面路由離開的時候調用')
})

Vue3.0中使用vuex

其實vuexVue3.0中的使用方式和vue-router基本是一致的

初始化vuex

首先新建store/index.js,然后添加如下代碼

import { createStore } from 'vuex'


export default createStore({
  state: {},
  mutations: {},
  actions: {}
})

然后在main.js中,通過以下方式使用

 createApp(App).use(store)

setup中使用vuex

useRouter一樣,vuex也提供了useStore供調用時使用,比如下面這段代碼

import router from '@/router'
import store from '@/store'
router.beforeEach(async (to, from, next) => {
  if (
    to.path !== '/login' &&
    store.getters['permission/getRoleMenus'].length === 0
  ) {
    await store.dispatch('permission/loadRoleMenus')
    next()
  } else {
    next()
  }
})

其余的使用方式基本和Vue2.0中的用法是一致的,大家具體可以參考vuex官方文檔

Vue3.0中的生命周期鉤子函數

在前文中,我們說到Vue3.0是兼容一部分 Vue2.0 的,所以對于 Vue2.0 的組件寫法,生命周期鉤子函數并未發生變化,但是假如你使用的是componsition api,那么就需要做一部分調整

取消beforeCreatecreated

在使用componsition api的時候,其實setup就代替了beforeCreatecreated,因為setup就是組件的實際入口函數。

beforeDestroydestroyed 改名了

setup中,beforeDestroy更名為onBeforeUnmount,destroyed更名為onUnmounted

將生命周期函數名稱變為on+XXX,比如mounted變成了onMounted,updated變成了onUpdated

setup中使用生命周期函數的方式

setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  }

實際用法與 Vue2.0 基本是一致的,只是寫法發生了變化,所以學習成本是很低的。

感謝各位的閱讀,以上就是“Vue3.0中怎么使用watch”的內容了,經過本文的學習后,相信大家對Vue3.0中怎么使用watch這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

纳雍县| 沾益县| 和平县| 右玉县| 高安市| 宁都县| 米脂县| 鹤山市| 射阳县| 开江县| 晴隆县| 双流县| 宝清县| 清镇市| 高淳县| 丽水市| 即墨市| 建平县| 乌拉特后旗| 永丰县| 富源县| 拉孜县| 洛阳市| 定边县| 三门峡市| 原平市| 类乌齐县| 冕宁县| 旌德县| 丹凤县| 九台市| 西畴县| 洮南市| 嵩明县| 会同县| 南城县| 射阳县| 昆山市| 新绛县| 吉木萨尔县| 沙河市|