Vue router application problem log

Get into the habit of writing together! This is the 11th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

foreword

This article records some problems encountered in the use of vue-router of vue2.

problem log

Application of Route Guard

According to the location where the routing guard is bound, there are the following three routing guards

global guard

beforeEach/beforeResolve/afterEach

Routing exclusive guard

beforeEnter

Guards inside components

beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave

For its complete navigation and parsing process, see the official documentation as follows:

  1. Navigation is triggered.
  2. Call beforeRouteLeavethe guard .
  3. Call the global beforeEachguard .
  4. Call beforeRouteUpdateguards .
  5. Called in the routing configuration beforeEnter.
  6. Parse asynchronous routing components.
  7. Called in the activated component beforeRouteEnter.
  8. Call global beforeResolveguards (2.5+).
  9. Navigation is confirmed.
  10. Call the global afterEachhook .
  11. Trigger a DOM update.
  12. Call the callback function passed to in the beforeRouteEnterguard with the created instance .next

The following are practical application scenarios of several commonly used hooks:

beforeRouteLeave: Before jumping the page, remind the user whether to save the information, or automatically save the draft for the user.

beforeEach: Determine whether to log in, whether you have permissions, etc., and perform operations such as jump login, request permission, and handle permission menus.

beforeRouteUpdate: Re-initialize and load data when re-entering the same page.

beforeRouteEnter:获取当前页面的前一个页面的信息,比如我们在登录页,登录后要重定向到前一个页面,就可以通过这个钩子获取。注意:这里, 不!能!获取组件实例 this,因为新组件还没有被创建。不过,可以传一个回调,给next来访问实例,在创建好实例后,会执行。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}
复制代码

其他几个路由守卫,我这边不常用,有补充的观众欢迎留下评论。

动态路由实现权限控制

应用场景:管理端根据不同权限,需要展示不同的菜单栏,同时希望没有权限的用户无法访问某些页面。

解决方案:我们在进入路由前,做一个拦截,先判断是否需要处理页面权限,再判断是否已经处理了权限,如果回答都是“是”,我们不需要做处理。否则,请求接口,获取到当前用户的权限菜单,再根据后台返回的信息,给router动态添加路由,再重新进入路由(避免拦截的访问是新添加的路由,出现访问不到的问题)。

具体看下面的伪代码:

router.beforeEach((to, from, next) => {
    if (needAuthority(to.name)) {  //不需要判断权限的页面,不处理
      next()
      return
    } 
    if (alreadyGetAuthorityMenu) {  //已经处理过权限菜单,不再处理
        next()
        return
    }
  
    handleAuthority().then(()=>{
        next({ ...to, replace: true })  //处理权限菜单接口成功,动态路由已经添加了,重新进入路由
      }).catch(() => {
        console.log('请求权限菜单接口错误')
        next()
    })

})
复制代码

handleAuthority中我们做了这些事情

  1. 判断是否有权限,没有权限的用户,跳转到权限申请页面
  2. 根据后台传过来的权限列表,用router.addRoutes(routes: Array)这个API,给router动态添加需要权限控制的页面对应的路由。
  3. 给router动态添加一个兜底页面,可以是提示没权限的页面,或者简单一个404页面。

需要注意的是,动态添加路由后,需要next({ ...to, replace: true })重新进入路由,否则,如果拦截的页面路由,是你后面才添加的路由,那新的路由会访问不到。

hash模式的路由参数被干扰

应用场景:比如微信分享链接会加上,类似'?from=singlemessage&isappinstalled=0'这类的参数,当我们使用hash模式路由,同时使用params的方式传参数的时候,常常会被外界的参数干扰到,导致页面无法访问或者参数获取不到,使用动态路由参数是更好的选择。

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})
const userId = '123'
// 两种跳转方式
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
复制代码

Further, we can use propsto decouple the component from the route, and define the id props in the component to get the passed parameters.

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true }
  ]
})
复制代码

Jump to the same component route without refreshing?

Application scenario: Jump to the page of the same component, but with different parameters, expect to refresh the page.

Solution: We can re-execute the code to be executed when entering the page in beforeRouteUpdate, but if we need to initialize all variables, there will inevitably be omissions. A simpler way is to monitor the route changes. If there are changes, this.$router.go(0 ) to refresh.

// 推荐
beforeRouteUpdate(to, from, next) {
    // 重新加载数据
    next();
},
复制代码
watch: {
 '$route'(to, from) {
    this.$router.go(0)
 }
}
复制代码

Good articles in the past

"Farewell to Bad Code"

2022 Code Specification Best Practices (with examples of optimal configuration for web and applets)

[Front-end exploration] Say goodbye to bad code! Encapsulate network requests with Chain of Responsibility pattern

[Front-end exploration] Farewell to the second issue of bad code! Encapsulate shared components with strategy pattern

Code Life

[Thinking about front-end development for three years] How to effectively read requirements?

A must-see guide for front-end stepping on the pit

[Front-end exploration] Best practices for image loading optimization

[Front-end exploration] Exploration of mobile terminal H5 to generate screenshots and posters

[Front-end exploration] H5 obtains user positioning? Enough to read this

[Front-end Exploration] Exploration of WeChat Mini Program Jump - Why Does Open Tab Exist?

Guess you like

Origin juejin.im/post/7085347539184156685