一、路由实现方案
1. 动态路由
// routes.js
const routes = [
{
// ':id' 是占位符,该写法匹配 /car/123 ,/car/1/2/3 等路径
path: '/car/:id',
// 设置为 true 可以使用组件中 props 属性来接收 ‘:id’ 的内容
props: true,
// 路由地址匹配的组件
component: () => import('./view/carDetail.vue')
}
]
<!-- carDetail.vue -->
<template>
<div>
<!-- 直接使用 this.$route 的方式获取,但是这种方式更加依赖路由传参
如果路由没有传参,则 this.$route 中获取不到值 -->
{{$route.params.id}}
</div>
</template>
<script>
exoprt default {
// 通过与组件传参方式一样的方式接受路由参数,在路由没有传参的时候
// 还可以通过组件传参拿到参数
props:['id']
}
</script>
2. 嵌套路由
// routes.js
const routes = [
{
path: '/',
component: () => import('./Main.vue'),
children: [
{
// ':id' 是占位符,该写法匹配 /car/123 ,/car/1/2/3 等路径
path: '/car/:id',
// 设置为 true 可以使用组件中 props 属性来接收 ‘:id’ 的内容
props: true,
// 路由地址匹配的组件
component: () => import('./view/carDetail.vue'),
}
]
}
]
<!-- Main.vue -->
<template>
<div>
<!-- 通过 router-view 的方式,可以匹配 Main 路由下面的子路由的组件 -->
<!-- 并且把子路由的组件替换到 router-view 标签的位置 -->
<router-view></router-view>
</div>
</template>
3. 编程式导航
可以使用 this.$route.push() 方法,传入路由地址和路由参数,达到跳转页面的目的
二、Hash 和 History
1. hash 和 history 的区别
首先这两种实现方式都是前端实现,在交互的过程中,通过改变网站地址,并且配合 ajax,来营造出跳转了页面的假象,其实并没有跳转页面,或者重新请求新页面。
并且两者在地址展示上是有区别的,hash 模式需要在网站地址中加入 # ,?等特殊字符,而history 模式则不需要。
2. hash
hash 的实现原理是通过 location.hash = #/about.html 的方式改变网站域名中 #和#之后的值,并且通过 location.hash 获取改变后的值,并且用 onhashchange 监听 hash 值的改变进行 ajax 请求,#只能跟在域名后面。
3. history
history 的实现原理利用的 IE10 之后才支持的 HTML5 history API,通过 history.pushState , history.replaceState 这两个方法来将新的地址新增或替换历史记录,并且修改当前地址,并且监听 popstate 改变时进行 ajax 请求。注意:在 history.pushState 和 history.replaceState 执行时不触发 popstate 监听。
3. Vue-Router History 实现
1. 首先规划 vue-router 类,类有三个属性,options 记录类传入的规则对象,routeMap 记录地址和组件的对应关系,data 是一个对象,里面有一个 current 属性记录当前地址,并且 data 为响应式对象,路由地址改变后,要更新对应的组件。类还有几个方法,其中静态方法 install 用来实现vue 的插件机制,因为 vue 引入插件会调用插件的 install 方法。构造函数 constructor 方法。用来初始化类的三个属性。initEvent 方法注册 popstate 监听事件。createRouteMap 是用来初始化 routeMap 属性的,把组件和地址对应规则变成键值对的方式储存下来。initComponents 是用来创建 router-link 和 router-view 这两个组件。
2. install 静态方法的实现
static install(Vue) {
// 全局定义 _Vue 属性,然后把 install 传进来的 Vue 方法赋值给 _Vue
_Vue = Vue
// Vue 本质是一个函数,mixmin 是直接 Vue.mixin = fun 的方式赋值在 Vue上的
// 所以在 Vue 还没有编程实例的时候就可以调用
_Vue.mixin({
// Vue 的生命周期,所有 Vue 实例都有
beforeCreate() {
// 但是只有根 Vue 实例在实例化的时候被传入了 router 属性,所以用 router 属性来
// 判断是否是跟实例,如果是根实例,则把 router 赋值给 _Vue 的原型对象
if (this.$options.router) {
// 把 router 赋值给 _Vue 的原型对象,保证在组件实例中,通过this.router
// 能获取到 router 实例进行ruoter.push 等操作。注意:vue组件是继承了 Vue 实例
_Vue.prototype.$router = this.$options.router
}
}
})
}