1

*mode: "history", //对浏览器比较友好
base: process.env.BASE_URL, 在vue.config.js(node代码)中配置的基础路径
vue.config.js 命令行工具要传给webpack的一些参数*

module.exports = {
publicPath: '/kCart', //在所有的路径前加的名称
configureWebpack: { //可配置代理和开发服务器数据的模拟
//开发服务器可配置代理和数据的模拟
devServer: {
before(app) { //before 服务器启动之前的一个钩子函数 可以对实例做一些提前的操作
//app是express实例 后台服务器
app.get('./goods',(req,res)=>{// 接收请求和响应 req请求中拿参数 res响应写数据
res.json([
{
id: 1,
text: 'afv'
},
{id:2,text:'afv'}
])
})
}
}
}
}

路由嵌套

配置:children
父组件:<router-view></router-view>

传参:

{
        path: '/detail/:id',
        component: Detail,
         meta: {
      requireLogin: true
       },//可在全局路由中使用  去判断条件   比如是否登陆
        props: true
      }, 

路由守卫(全局)

每次路由激活之前都会执行回调函数
router.beforeEach((to, from, next) => {
  console.log(to.meta)
  // 判断是否登录
  if (to.path === '/about' && !window.isLogin) {
    next('/login?redirect=' + to.path)
  } else {
    next()
  }
})

路由独享守卫(路由级)

{
    path: '/about',
    name: 'about',
    meta: {
      requireLogin: true
    },
    beforeEnter (to, from, next) {
      // 判断是否登录
      if (!store.state.isLogin) {
        next('/login?redirect=' + to.path)
      } else {
        next()
      }
    },
    // 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')
  }

获取查询参

 methods: {
    onLogin () {
      window.isLogin = true// 登录成功
      //   拿出重定向的地址
      // 获取查询参
      const redirect = this.$route.query.redirect || '/'
      //   路由到重定向的地址 $router路由器 路由的操作
      // 参数的附加者都是路由
      this.$router.push(redirect)
    }
  }

组件内的守卫(组件级)

export default{
   beforeRouteEnter(to,from,next){}
   beforeRouteUpodate(to,form,next){}
   beforeRouteLeave(to,from,next){}
}

完整的导航解析流程

*导航被触发
调用全局的beforeEach守卫 //可能初始化的一些工作还没做完
在重用的组件里调用beforeRouteUpdate守卫
在路由配置里调用beforeEnter
在激活的组件里调用beforeRouteEnter
调用全局的beforeResolve 守卫(2.5+)//组件里面提前的事情已经准备好,时间点与beforeEach比 靠后一点
导航被确认
调用全局的afterEach钩子//路由触发后做一些额外的事情
触发DOM更新*

通常用法

const routes = [
    {path:'/',component:Home},
    {path:'/book',component:Book},
    {path:'/movie',component:Movie}
]
const router = new VueRouter(Vue,{routes})
new Vue({
    el:'#app',
    router
})

实现vue-router插件

/**
 * 实现插件
 * url变化监听
 * 路由屏配置解析:{'/':home}
 * 实现全局组件:router-link,router-view
*/

class VueRouter {
  constructor (options) {
    this.$options = options
    this.routeMap = {}
    // 路由响应式
    this.app = new Vue({
      data: {
        current: '/'
      }
    })
  }
  init () {
    this.bindEvents()// 监听url变化
    this.createRouteMap(this.$options)// 解析路由配置
    this.initComponent()// 实现两个组件
  }
  bindEvents () {
    window.addEventListener('load', this.onHashChange.bind(this))
    window.addEventListener('hashchange', this.onHashChange.bind(this))
  }
  onHashChange () {
    this.app.current = window.location.hash.slice(1) || '/'
  }
  createRouteMap (options) {
    options.routes.forEach(item => {
      this.routeMap[item.path] = item.component
    })
  }
  initComponent () {
    // router-link,router-view
    // <router-link to="">ffff</router-link>
    Vue.component('router-link', {
      props: {to: String},
      render (h) {
        // h(tag,data,children)
        return h('a', {attrs: {href: '#' + this.to}}, [
          this.$slots.default
        ])
      }
    })
    // <router-view></router-view>
    Vue.component('router-view', {
      render: h => {
        // 在weppack中,如果想要通过Vue,把一个组件放到页面中展示,vm
        // 实例中的render函数可以实现
        // render: function (createElement) {
        //   return createElement(component)
        // }
        // 简写 render: c => c(component)
        const comp = this.routeMap[this.app.current]
        return h(comp)
      }
    })
  }
}
VueRouter.install = function (Vue) {
  // 混入
  Vue.mixin({
    beforeCreate () {
      // this是vue实例
      if (this.$options.router) {
        // 仅在根组件执行一次
        Vue.prototype.$router = this.$options.router
        this.$options.router.init()
      }
    }
  })
}

HappyCodingTop
526 声望847 粉丝

Talk is cheap, show the code!!