VueRouter 组件内守卫 beforeRouteEnter 的应用场景

3,937 阅读1分钟

今天产品给了这么个需求,很简单,如上图,点击 编辑 进入编辑页面,编辑完返回现在的列表页。

但是,如果在列表页有搜索条件,那么编辑完回来要保留搜索条件。不知道说清楚了没有。。。。

那么,作为一个熟练的 API 调用师,第一时间去查看了可能用到的API。

VueRouter 组件内守卫 官方文档点这里

const Foo = {
  template: `...`,
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  }
}

beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

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

有了这个,就完美解决了。

  1. 点击编辑时,跳转路由时把搜索条件带上。

    this.$router.push({
        name: 'edit',
        params: { searchFormData: { ...this.searchFormData } }
    })
    
  2. 从编辑页跳回列表页时,再带回来。

    let { searchFormData } = this.$route.params
    
    this.$router.push({
        name: 'list',
        params: { searchFormData }
    })
    
  3. 在路由守卫的回调中判断是否是 从编辑页到列表页,如果是,就从路由的params中取出保存的搜索条件。

    beforeRouteEnter(to, from, next) {
        if (from.name === 'edit') {
            if (from.params.searchFormData) {
                next(vm => {
                    vm.searchFormData = { ...from.params.searchFormData }
                    vm.handleClickSearch()
                })
                return
            }
        }
        next(vm => {
            vm.handleClickSearch()
        })
    },
    

至此,完美解决。