const path = require('path');
const BASE_URL = process.env.NODE_ENV === 'production' ? './' : '/';
const resolve = dir => path.join(__dirname,dir);
module.exports = {
lintOnSave: false,
publicPath : BASE_URL,
chainWebpack : config => {
config.resolve.alias
.set('@',resolve('src')) // 配置:用 @ 符号来代替 src 的根目录
.set('_s',resolve('src/assets/style'))
},
//打包时不生成 .map 文件 减小打包体积 缩短打包时间
productionSourceMap : false,
devServer : {
proxy : 'http://localhost:4000'
}
}

上述为配置:后面所有例子都以该配置为主

一般项目中会把路由文件分为两个部分: 1.配置路由列表文件 2. 创建路由实例文件(需引入vue-router插件)

// 配置路由列表
import Home from '@/views/Home.vue'
export default [
  {
    path: '/', //path 指代路径
    component: Home
  },
  {
    path: '/about',// route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue')
  },
  {
    path : '/argu/:name',
    component : () => import('@/views/argu.vue')
  }
]
//上面例子概述了两种组件的引入方式 : 第一种 Home 的引入方式 将组件以变量的形式引入 第二种直接在 component 中引入
// 创建路由实例
import Vue from 'vue'
import Router from 'vue-router' // 插件
import routes from './router'  //引入路由列表文件
Vue.use(Router)
export default new Router({
    routes
})

实例化一个vue:

import Vue from 'vue'
import App from './App.vue'   //引入App组件 赋值给App
import router from './router' //引入创建路由实例文件 赋值给变量 router
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app') //app为vue渲染的元素
//App.vue组件
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |  //router-link封装了一个 a 标签 to指定的值是路径 也就是路由列表中的 path
      <router-link :to="{name : 'about'}">About</router-link>
    </div>
    <router-view/> //视图渲染组件通过 router-link 加载的组件都会在这边渲染
  </div>
</template>

动态路由匹配:

//在配置路由列表中
{
    path : '/argu/:name',
    component : () => import('@/views/argu.vue') //引入 argue 组件
},
//argue组件
<template>
    <!--$route表示当前加载页面的路由对象 params是参数 name是值-->
    <div>{{$route.params.name}}</div>
</template>
<script>
    export default {
        //
    }
</script>

 嵌套路由:

//在配置路由列表中
{
    path : '/parent',
    component : () => import('@/views/parent.vue'),
    children : [  //嵌套子组件
      {
        path : 'child',//子组件路径不需要加 '/'
        component : () => import('@/views/child.vue')
      }
    ]
}
<!-父组件-->
<template>
    <div>
        I am parent
        <router-view/>
    </div>
</template>
<script>
    export default {
        // name: "parent"
    }
</script>
<!--子组件-->
<template>
    <div>I am child</div>
</template>
<script>
    export default {
        // name: "child"
    }
</script>

命名路由 :

      <!--命名路由 name值与路由列表中的name值对应-->
      <router-link :to="{name : 'about'}">About</router-link> 
//在配置路由列表中配置(router.js)
{
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue')
  }

命名视图:(同一个页面上显示多个视图)

    <router-view/>
    <!--命名视图-->
    <router-view name="email"/>
    <router-view name="tel"/>
  {
    path: '/name_view',
    components:{
      default: () => import('@/views/child.vue'),
      email: () => import('@/views/email.vue'),
      tel: () => import('@/views/tel.vue'),
    }
  }

注意:路由列表中组件的优先级是由上而下的,上面的优先级较高

前置守卫:

// 创建路由实例
import Vue from 'vue'
import Router from 'vue-router' // 插件
import routes from './router'  //引入路由列表文件

Vue.use(Router)

const router = new Router({
    mode : 'history',//默认hash模式
    routes
})
//实例化一个登录页面
const HAS_LOGINED = true  // 做一个简单的判断 是否登录
//注册一个全局前置守卫
//to 即将跳转页面的路由对象 from当前操作的路由对象 next时一个函数
router.beforeEach((to,from,next) => {
    if(to.name !== 'login'){//如果即将跳转的页面不是登录页面
        //判断是否登录 如果已经登录直接执行 next() 跳转
        if(HAS_LOGINED) next()
        //如果没有登录直接执行 next() 跳转到 login 页面
        else next({name : 'login'})
    }else{
        if(HAS_LOGINED) next({name : 'home'})
        else next()
    }
})
export default router
//在配置路由列表中配置(router.js)
  {
    path : '/login',
    name : 'login',
    component: () => import(/* webpackChunkName: "about" */ '@/views/login.vue')
  },
//login.vue文件
<template>
    <div>login-page</div>
</template>
<script>
    export default {
        name: "login"
    }
</script>

组件独享守卫:

 {
    path: '/',
    name: 'home',
    component: Home,
    //to 即将跳转页面的路由对象 from当前操作的路由对象 next时一个函数
    beforeEnter : (to,from,next) => {
      if(from.name === 'about') alert('这是由about页面跳转来的')
      else alert('这不是由about页面跳转来的')
      next()
    }
  }

在组件内使用守卫:

<template>
  <div class="home">
    <img alt="Vue logo" src="@/assets/image/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <button @click="hendleClick">返回上一页</button>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'home',
  components: {
    HelloWorld
  },
  beforeRouteEnter(to,from,next){
    alert(to.name + from.name)
    next()
  },
  //多用在文本编辑 
  beforeRouteLeave(to,from,next){
    const leave = confirm('您确定要离开吗')
    if(leave) next()
    else next(false)
  },
  methods: {
    hendleClick: function () {
      this.$router.back()
    }
  }
}
</script>

完整的导航解析流程:

  1. 导航被触发

  2. 在失活的组件(即将离开的组件)里调用离开守卫 beforeRouteLeave

  3.调用全局的前置守卫 beforeEach

  4.在重用的组件里调用 beforeRouteUpdate

  5.调用路由独享的守卫 beforeEnter

  6.解析异步路由组件

  7.在被激活的组件(即将进入的组件)里调用 beforeRouteEnter

  8.调用全局的解析守卫 

  9. 导航被确认

  10. 调用全局的后置守卫

  11.触发DOM更新

 

posted on 2019-10-06 00:05  yu_bin  阅读(574)  评论(0编辑  收藏  举报