文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue3.0中怎么使用watch

2023-06-27 10:32

关注

这篇文章主要讲解了“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这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯