vue-router 路由

# vue-router 路由

# 路由配置

import Vue from "vue";
import Router from "vue-router";
import store from '../store/index';

Vue.use(Router);

const router = new Router({
  routes: [{
      path: "/",
      redirect: "/index"
    },
    {
      path: "/order",
      meta: { 适合做权限管理,这个对象能在路由守卫中获取到,这里可以任意添加属性,自定义
        title: '我的订单',
        needLogin: true
      },
      component: () => import("@/views/order/index")
    },
    {
      path: "/cart",
      meta: {
        title: '购物车',
        needLogin: true
      },
      component: () => import("@/views/cart/index")
    },
    {
      path: '/login',
      component: () => import('@/views/login/index'),
      meta: {
        title: '登陆'
      }
    },
    {
      path: '/index',
      component: () => import('@/views/index/index'),
      meta: {
        title: '首页'
      }
    },
    {
      path: "/my",
      component: () => import("@/views/my"),
      redirect: '/my/center',
      children: [{
        path: 'center',
        meta: {
          title: '个人中心',
        },
        component: () => import('@/views/my/center')
      }, {
        path: 'set',
        meta: {
          title: '设置',
        },
        component: () => import('@/views/my/set')
      }]
    },
    {
     // 404配置
     path: '*',
   component: () => import('@/views/notFound')
    }
  ],
  // 解决vue框架页面跳转有白色不可追踪色块的bug,当从A页面的最底部跳到B页面,B页面在回到A页面还是跳转前的位置
  scrollBehavior: () => ({ x: 0, y: 0 }),
});


router.beforeEach((to, from, next) => {
  let {
    title,
    needLogin
  } = to.meta;
  // 从vuex获取登录状态
  let isLogin = store.state.isLogin;
  document.title = title;

  if (needLogin && !isLogin) {
    next({
      path: '/login'
    })
  } else {
    next();
  }
})

export default router;

# 重定向 redirect

全局配置重定向

在路由配置中,如果路由没有匹配到项,就会重定向到 './home'
  {
    path: '*',
    redirect: '/home'
  },

重定向的目标也可以是一个命名的路由:

{
    path: '*',
    redirect: {name:'Home'}
  },

还可以是一个方法,用箭头函数,里边传一个 [to]参数,to 是要进入的路由

{
    path: '*',
    redirect: (to)=>{
        // 方法接收 目标路由 作为参数
        // return 重定向的 字符串路径/路径对象
    }
  },

# 别名

解释

“重定向”的意思是,当用户访问 /a 时,URL 将会被替换成 /b,然后匹配路由为 /b,那么“别名”又是什么呢?

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。 我的理解就是,访问/a 就是当前,你访问/b 显示的还是我这个/a,但是地址栏显示的是/b

# 路由传参

先有如下场景 点击当前页的某个按钮跳转到另外一个页面去,并将某个值带过去

<div @click="get(2)">查看详情</div>

# 第一种方法 页面刷新数据不会丢失

methods:{
  get(id) {
       //直接调用$router.push 实现携带参数的跳转
        this.$router.push({
          path: `/about/${id}`,
        })
}

需要对应路由配置如下:

{
     path: '/about/:id',
     name: 'about',
     component: about
   }

另外页面获取参数如下

this.$route.params.id;

# 第二种方法 页面刷新数据会丢失

通过路由属性中的 name 来确定匹配的路由,通过 params 来传递参数。

methods:{
  get(id) {
       this.$router.push({
          name: 'about',
          params: {
            id: id
          }
        })
  }

对应路由配置: 注意这里不能使用:/id 来传递参数了,因为组件中,已经使用 params 来携带参数了。

 {
     path: '/about',
     name: 'about',
     component: about
   }

子组件中: 这样来获取参数

this.$route.params.id;

# 第三种方法

使用 path 来匹配路由,然后通过 query 来传递参数
这种情况下 query 传递的参数会显示在 url 后面?id=?

methods:{
  get(id) {
        this.$router.push({
          path: '/about',
          query: {
            id: id
          }
        })
  }

对应路由配置:

{
     path: '/about',
     name: 'about',
     component: about
   }

对应子组件: 这样来获取参数

this.$route.query.id;

注意:

特别注意哦,
组件中 获取参数的时候是 route.params 而不是 router 这很重要~~~

# 动态路由

https://juejin.cn/post/6965057432544346143?utm_source=gold_browser_extension

# 路由守卫

# 全局前置守卫 beforeEach

router.beforeEach(async (to, from, next) => {
	to:即将进入的页面信息
	from:即将要离开的页面信息
	next:它是一个回调函数,
		  一、不传任何东西的话就是允许跳转;
		  二、如果传入一个false就会阻止页面跳转;
		  三、next('/') 或者 next({ path: '/' }) 跳转到不同的地址。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
		  四、next(error) ) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
});

# 全局后置守卫 afterEach

只有两个参数,to:进入到哪个路由去,from:从哪个路由离。

router.afterEach((to,from)=>{
  alert("after each");
})

# 组件守卫

  • beforeRouteEnter 到达这个组件时
export default {
    data(){
        return{
            name:"Arya"
        }
    },
    beforeRouteEnter:(to,from,next)=>{
        next(vm=>{
            alert("hello" + vm.name);
        })
    }
}

  • beforeRouteLeave 离开这个组件时 点击其他组件时,判断是否确认离开。确认执行next();取消执行next(false),留在当前页面
beforeRouteLeave:(to,from,next)=>{
	if(confirm("确定离开此页面吗?") == true){
		next();
	}else{
		next(false);
	}
}

# 独享的守卫 beforeEnter

这些守卫与全局前置守卫的方法参数是一样的。

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        to:是当用户点击进入当前页面的时候,我们可以进行一些拦截设置
        from:当来自其他页面进入当前页面的时候,我们也可以进行拦截提示用户
		next:它是一个回调函数,
			  一、不传任何东西的话就是允许跳转;
			  二、如果传入一个false就会阻止页面跳转;
			  三、next('/') 或者 next({ path: '/' }) 跳转到不同的地址。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
			  四、next(error) ) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
      }
    }
  ]
})

# 回到跳转前的位置

::: warnings 注意: 这个功能只在支持 history.pushState 的浏览器中可用 :::

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
  }
})