专栏首页前端有的玩使用Vue3.0,我收获了哪些知识点(二)

使用Vue3.0,我收获了哪些知识点(二)

最近在工作之余一直学习Vue3.0相关知识,虽然Vue3.0至今还是rc版,但这并不影响我们去学习。今天这篇文章是我关于Vue3.0的第四篇文章。在前文中我们讲解了如何通过vitevuecli搭建Vue3.0开发环境,然后介绍了Vue3.0中的setup,reactive,ref等,今天这篇文章主要讲解了以下内容:

  1. Vue3.0中使用watch
  2. Vue3.0中使用计算属性
  3. Vue3.0中使用vue-router
  4. Vue3.0中使用vuex

本文首发于公众号【前端有的玩】,这是一个专注于Vue面试相关的公众号,提升自己的市场竞争力,就在【前端有的玩】。同时点击以下链接即可访问小编关于Vue3.0的其他相关文章

学习Vue3.0,先来了解一下Proxy

使用vite搭建一个Vue3.0学习环境

使用Vue3.0,我收获了哪些知识点(一)

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更灵活的去监听某一个属性的变化。比如这样一个场景,我们有一个表单,然后希望在用户修改表单之后可以监听到表单的数据变化。但是有一个特殊的场景,就是表单的回填数据是异步请求过来的,这时候我们希望在后台请求完数据之后再去监听变化,这时候就可以使用

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">
    <h1>{{ name }}</h1>
  </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,那么就需要做一部分调整

  1. 取消beforeCreatecreated 在使用componsition api的时候,其实setup就代替了beforeCreatecreated,因为setup就是组件的实际入口函数。
  2. beforeDestroydestroyed 改名了 在setup中,beforeDestroy更名为onBeforeUnmount,destroyed更名为onUnmounted
  3. 将生命周期函数名称变为on+XXX,比如mounted变成了onMounted,updated变成了onUpdated

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

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

实际用法与Vue2.0基本是一致的,只是写法发生了变化,所以学习成本是很低的。

总结

这是小编关于Vue3.0的第四篇文章,每一篇文章都是自己在学习中做的一些总结。小编整理了一个vue3.0的开发环境,仓库地址为 https://gitee.com/f_zijun/vue-antd-admin.git,内部集成了typescript,eslint,vue-router,vuex,ant desigin vue等,希望可以帮到正在学习Vue3.0的你,同时关注公众号【前端有的玩】,带给你不一样的惊喜。喜欢本文,可以给小编一个赞哦。

结语

不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。——文森特・梵高

本文分享自微信公众号 - 前端有的玩(gh_918bae0a9616),作者:前端进击者

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 使用Vue3.0,我收获了哪些知识点(一)

    近期工作感觉很忙,都没有多少时间去写文章,今天这篇文章主要是将自己前期学习Vue3.0时候整理的一些笔记内容进行了汇总,通过对本文的阅读,你将可以自己完成Vue...

    用户1308196
  • 最强Vue3.0新特性讲解,99%的人都觉得很赞!

    2020年4月前端开发框架Vue发布了3.0-Beta版本,9月发布正式版。 纳尼?2.0还没玩转,3.0的时代就来了???

    pingan8787
  • 全网首发:Vue3.0+Vite避坑指南!升级后有新增了哪些看点?

    Vue2.0 全线升级,升级后的新版本 Vue3.0 凭借新特性,新工具,一经问世便在 IT 圈中引起广泛的讨论:

    用户3806669
  • 茶余饭后聊聊 Vue3.0 响应式数据那些事儿

    "别再更新了,实在是学不动了"这句话道出了多少前端开发者的心声,"不幸"的是 Vue 的作者在国庆区间发布了 Vue3.0 的 pre-Aplha 版本,这意味...

    政采云前端团队
  • 2021年,vue3.0 面试题分析(干货满满,内容详尽)

    2020年09月18日,vue3.0正式发布。随着它的发布,Vue.js再次被推上了前端的风口浪尖。 同时,面试官的提问也将加入一些有关Vue3.0的新元素(...

    winty
  • vue3.0 Composition API 上手初体验 使用 vue-router 构建多页面应用

    前两讲,我们已经顺利的使用 vue3.0 将项目跑起来了。但是实在是过于简陋,目前我们几乎不可能开发只有一个页面的应用。因此,vue-router 是必不可少的...

    FungLeo
  • 千层套路 - Vue 3.0 初始化源码探秘

    9 月初 Vue.js 3.0 正式发布,代号 "One Piece"。大秘宝都摆到眼巴前了,再不扒拉扒拉就说不过去了。那我们就从初始化开始。

    若川
  • 「小议」 我从读源码中收获到了什么?阅读源码那点小事

    说到源码,大家脑海里可能浮现出四个字 我太难了???。读源码貌似和我们遥不可及,因为在日常工作中,我们基本掌握在熟练的程度上,就能够满足工作需求,即便是想看源码...

    用户6835371
  • vue3.0 源码解析一 :响应式原理(上)

    从本文开始,我们正式进入vue3.0 源码解析流程。个人觉得从ceateApp入手并不是最佳的学习方案,所以我们先从composition-api响应式原理入手...

    用户6835371
  • 顺藤摸瓜,突然有点心疼尤雨溪,写vue3太难了

    就在前天凌晨6点多,我在公众号上推送了一篇文 《尤雨溪:Vue3.0全球发布会在线视频》,没看过的戳标题回顾,真的建议有空多看几遍,重温下尤大帅气的脸庞,才是最...

    闰土大叔
  • Vue3diff算法原理和优化

    你知道 Vue3.0 Object.difineProperty和vue3.0的proxy的区别吗?

    前端迷
  • 为什么 Vue3.0 要重写响应式系统

    面试的时候经常被问到 响应式 相关的内容,而Vue3.0 更新后,面试官又有了新的武器;

    西岭老湿
  • vue3.0 Composition API 上手初体验 构建基本项目开发环境

    目前,vue3.0 已经进入了 beta 版本了。众多的特性已经定下来了,相信有不少朋友都已经开始阅读相关的资料或源码了。

    FungLeo
  • 适合Vue用户的React教程,你值得拥有(二)

    上周小编我写了 适合Vue用户的React教程,你值得拥有,得到了小伙伴们的一致好评,今天这篇文章是这一系列的第二篇文章。今年的9月18日是九一八事变89周年,...

    用户1308196
  • Vue3.0 新特性以及使用变更总结(实际工作用到的)

    Vue3.0 在去年9月正式发布了,也有许多小伙伴都热情的拥抱Vue3.0。去年年底我们新项目使用Vue3.0来开发,这篇文章就是在使用后的一个总结, 包含Vu...

    @超人
  • vue3.0 源码解析三 :watch和computed流程解析

    之前我们分两个章节详细的介绍了vue3.0 数据相应原理,知道了用proxy代替Object.defineProperty 的利与弊,了解了依赖收集和派发更新的...

    用户6835371
  • 【红隼书签】一款简洁的在线书签导航网站

    ???【红隼书签】是一款简洁的在线书签导航网站。 名字的由来其实是,本着保护动物,爱护动物的初心,想到起一个鸟类的名称,其实最开始想了很多名字,小詹书签,麻雀书...

    叫我詹躲躲
  • 《Vue3.0抢先学》系列之:网友们都惊呆了!

    今天开始,我想给大家讲点新东西。大家不用大喊学不动,请放松心情随意观看,我也讲不出什么很深奥难学的东西,本系列文章都会是些比较浅显易懂的家常内容。

    一斤代码
  • vue3.0项目搭建详解

    在搭建vue3.0之前,我们首先来收悉一下vue3.0相比vue2.0做了那些改进,增加了那些特性。

    用户9032532

扫码关注云+社区

领取腾讯云代金券