一、Vue-Router 需要实现的功能如下
1、vue插件:
vue插件会先调用vue.use() 方法,接收一个参数,如果传入的参数是一个函数,直接调用这个函数;如果是一个对象,就调用这个对象的install方法。 并将vue实例传入
2、实例对象router和route
在初始化Vue实例的时候传入 router,Vue实例中会生成$route
和$router
两个属性:$route
中存储了当前的路由规则,$router
中存储了路由实例对象,可以调用一些和路由相关的方法。
3、两个组件 router-view和router-link
4、动态路由
cosnt routes = [
{
// 使用动态路由
path: '/detail/:id',
name: 'Detail',
// 开启 props,会把 URL 中的参数传递给组件
// 在组建中通过 props 来接收 URL 参数
props: true,
// 路由懒加载
component: () => import('../views/Detail.vue')
}
]
5、路由传参
① 通过当前路由规则,获取数据 {
{
$route.params.id }},这种方式强依赖与路由,在使用组件的时候必须有路由给传递参数。
② 路由规则中开启 props ,路由会把 URL 中的参数传递给相应的组件,在组件接收这个props就可以了,这和父子组件传值的方式是一样的,不再依赖路由。 props: ['id']
6、嵌套路由
cosnt routes = [
// 嵌套路由
{
path: '/',
component: Layout,
children: [
{
path: '',
name: 'Index',
component: Index
},
{
// path 可以使用相对路径也可以使用绝对路径
// path: '/detail/:id',
path: 'detail/:id',
name: 'Detail',
props: true,
component: () => import('../views/Detail.vue')
}
]
}
]
7、编程式导航
this.$router.replace('/login') , 不会记录本次历史
this.$router.push({
name: 'Detail', params: {
id: 1 } })
this.$router.go(-2),如果传入-1,等同于 this.$router.back()
二、Hash 模式 和 History 模式
1、Hash 模式 和 History 模式 的区别:
表现形式的区别:
Hash 模式带有#,井号后面是路由地址
History 模式 就是普通的URL,需要服务端支持
原理的区别:
Hash 模式 是基于锚点,以及 onhashchange 事件
History 模式 是基于 HTML5 中的 History API
history.pushState(), IE10 以后才支持(不会发送请求,只是改变路由地址,并将这个地址记入历史记录)
history.replaceState()
2、History 模式
在服务端应该除了静态资源外都返回单页应用的 index.html
点击超链接的时候:
点击超链接,调用 history.pushState(),改变浏览器地址栏中的地址,但是不会发送请求,并将地址存入历史记录中,这些都是在客户端完成的。
刷新浏览器的时候:
浏览器向服务器发送请求,请求的地址是地址栏中的地址,如果服务器没有处理这个地址就会出现错误;如果服务器开启对 History 支持,当服务器判断当前路由地址不存在时,将单页应用的首页 index.html 返回给浏览器,浏览器接收到页面后再去判断路由地址,再去加载相应的组件内容进行渲染
三、模拟实现 Vue Router
1、Vue 前置知识:
插件、混入、Vue.observable()、插槽、render 函数、运行时和完整版的 Vue
2、Vue Router 实现原理
Hash 模式:
① URL 中 # 后面的内容作为路径地址,如果只改变#后面的地址,浏览器不会发送请求,会把这个地址记录到浏览器访问历史中;
② 监听 hashchange 事件,当hash改变后会触发hashchange事件,并且记录当前的路由地址;
③ 根据当前路由地址找到对应组件重新渲染。
History 模式:
① 通过 history.pushState() 方法改变地址栏,只改变地址并记录路由地址,不发送请求
② 监听 popstate 事件,可以监听到浏览器操作的变化,记录改变后的地址,调用pushState 或者 replaceState 的时候不会触发,浏览器的前进后退按钮 或者 back 和 forward 方法会触发
③ 根据当前路由地址找到相应组件重新渲染
3、Vue Router 用例代码
// 注册插件
// Vue.use() 内部调用传入对象的 install 方法
Vue.use(VueRouter)
// 创建路由对象
const router = new VueRouter({
routes: [
{
name: 'home', path: '/', component