vue-router

一、创建路由

路由router/index.js

// 1 引入vue和vue-router
import Vue from 'vue';
import VueRouter from 'vue-router';

// 2 通过 Vue.use() 明确地安装路由功能
Vue.use(VueRouter);

/*
 *  3 定义一些路由(即一个对象代表一个路由,都存放在数组routes中,也可以由外部导入)
 *  每个路由都需要映射一个组件(即一个path对应一个component)
 *  其他配置项包括name redirect meta等等
*/
const routes = [
  {
    // 会拼接到地址栏, 名字是自定义的('/'代表页面默认打开时的路由)
    path: '/',
    // 路由重定向(即只要到该路由就会被重定向到某路由,此处为'/home',所以此处无需映射组件)
    redirect: '/home'
  },
  {
    // 路由路径(当地址栏显示/home时,app.vue中的router-view便显示Home.vue的内容)
    path: '/home',
    // 路由名称(路由跳转时可以通过path,也可以通过name)
    name: 'home',
    // 组件懒加载(即处于此路由时才会导入该组件,而不是一开始就导入组件,利于性能优化)
    // 也可以由其他文件直接导入
    component: () => import('../views/Home.vue'),
    // 默认显示子路由one
    redirect: '/home/one',
    // 路由的子路由(子路由的出口即router-view是需要写在其父级路由中的)
    children:[
         // 写法1,不加'/', 即代表'/home/list'
        {path: 'one', component: () => import('../views/One.vue')},
         // 写法2,加'/', 就需要写完整路由,也代表'/home/list'
        {path: '/home/two', component: () => import('../views/Two.vue')}
    ],
    // 路由源信息(按需使用)
    meta: {
        title: '主页',// 标题
        icon: 'el-icon-s-home',// 图标
        roles: ['admin', 'editor'],// 路由权限时使用
        keepAlive: true,// 组件缓存时使用
    } 
  }
];

// 4 创建路由实例
const router = new VueRouter({
  // history模式地址栏不会显示#号,hash模式会显示#号,默认值是hash
  mode: 'history',
  routes
});

// 解决重复点击同一个路由时,控制台出现报错问题
// 报错内容:Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation
const VueRouterPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (to) {
  return VueRouterPush.call(this, to).catch(err => err)
}
VueRouter.prototype.replace = function replace (to) {
  return VueRouterPush.call(this, to).catch(err => err)
}

// 5 导出路由实例
export default router

二、路由出口

一级路由的出口一般在app.vue中

二级及以上路由的出口,一般是在其父级路由相对应的组件内部

 

三、路由跳转

路由的跳转方式有两种,一种是声明式,一种是编程式(常用)

1、声明式路由(通过html标签跳转)

必传参数

        
        one
        two

其他参数

        
        one

2、编程式路由(通过js跳转)

常用的跳转方式

// 封装一个函数,通过事件调用即可
methods: {
  goOne() {
    // 1、push (跳转到指定的url,在history中添加记录)
    // this.$router.push('/home/one')
    // this.$router.push({ path: '/home/one' })
    // this.$router.push({ path: '/home/one', query: { a: 1 } })
    // this.$router.push({ name: 'HomeOne' })
    // this.$router.push({ name: 'HomeOne', params: { a: 1 } })

    // 2、replace重定向(跳转到指定的url,不在history中添加记录)
       this.$router.replace('/home/one');// 推荐写法
    // this.$router.replace({ path: '/home/one' })
    // this.$router.replace({ path: '/home/one', query: { a: 1 } })
    // this.$router.replace({ name: 'HomeOne' })
    // this.$router.replace({ name: 'HomeOne', params: { a: 1 } })
  }
}

其他跳转方式

this.$router.forward();    // 前进
this.$router.back();       // 后退
this.$router.go();         // 向前或向后跳转n个页面(n/-n)

四、路由传参

具体的写法在上面路由跳转时已说明,此处主要说明params和query的区别以及如果接收参数

1、参数接收

this.$route.params.id
this.$route.query.id

2、query和params的区别

1、搭配方式不同:query通常搭配path使用、params通常搭配name使用;

2、地址栏是否显示:query地址栏显示参数,params,地址栏不显示参数;

3、刷新是否造成数据丢失:query传值页面刷新也存在,params一刷新就没了(解决方案:在配置路由时加入占位符)

五、动态路由 

在path配置一个字段“:name”,它表示此字段是动态的。此时不管是路径'/home/two/Tom',还是'/home/two/John’,或者是其他的,都会跳转到此路由。

router/index.js

{
    path: '/home/two/:name', 
    component: () => import('../views/Two.vue')
},

跳转

const name = 'xxx'; // name是动态变化的
this.$router.replace('/home/one/'+name);

六、路由导航守卫

1、全局导航守卫

router/index.js

// 全局导航守卫(即在路由跳转前后做一些事情)
// 1.全局前置守卫
router.beforeEach((to, from, next) => {
    // 1.1 判断是否需要登录
    if (to.meta.requireAuth) {
        // 1.1.1 判断是否登录
        if (store.state.token) {
            next();
        } else {
            // 1.1.2 未登录则跳转到登录页面
            next({
                path: '/login',
                // 1.1.3 将跳转的路由path作为参数,登录成功后跳转到该路由
                query: {redirect: to.fullPath}
            })
        }
    } else {
        next();
    }
    // 1.2 判断是否需要权限
    if (to.meta.roles) {
        // 1.2.1 判断是否有权限
        if (store.state.roles.some(role => to.meta.roles.includes(role))) {
            next();
        } else {
            // 1.2.2 无权限则跳转到401页面
            next({
                path: '/401',
                // 1.2.3 将跳转的路由path作为参数,登录成功后跳转到该路由
                query: {redirect: to.fullPath}
            })
        }
    } else {
        next();
    }
});
// 2.全局后置守卫(后置守卫没有next参数)
router.afterEach((to, from) => {
    // 2.1 设置标题
    document.title = to.meta.title;
    // 2.2 设置面包屑
    store.commit('setBreadcrumb', to);
});

2、路由独享守卫

路由独享守卫,在进入该路由前执行的函数,可以用来判断是否有权限进入该路由,如果没有权限则跳转到其他路由。

{
    path: '/home',
    component: () => import('../views/Home.vue'),
    beforeEnter: (to, from, next) => {
      next();
    }
  },

3、组件内导航守卫

组件内导航守卫,只在当前组件生效,父子组件互不影响

export default {
    name: 'Home',
    // 导航守卫
    beforeRouteEnter(to, from, next) {
        console.log('beforeRouteEnter')
        next()
    },
    beforeRouteUpdate(to, from, next) {
        console.log('beforeRouteUpdate')
        next()
    },
    beforeRouteLeave(to, from, next) {
        console.log('beforeRouteLeave')
        next()
    },
    methods: {
        
    }
};

你可能感兴趣的:(vue2,vue.js,javascript,前端,1024程序员节)