前端路由的实现方式
目前前端的路由实现主要是两种方式,这两种方式都是基于浏览器自身的特性,两种方式分别是
hash
路由history
路由
hash
路由
hash
这个概念,可能听起来有些陌生,不过,其实我们在之前的前端开发中,其实是有所接触的。hash
路由一个明显的标志#
,通过这个监听URL
中的hash
变化来进行路由的跳转
例如,在某些情况下,我们需要定位页面上的某些位置,就像下面的例子中展现的那样,我想要通过点击不同的按钮就跳转到指定的位置,这里我们使用的锚点定位其实就是 hash
。
<div id="content">
<div class="btn-container">
<a class="btn" href="#image1">图片1</a>
<a class="btn" href="#image2">图片2</a>
</div>
[外链图片转存失败(img-Q168h1rT-1562138834017)(https://mp.csdn.net/mdeditor/xxx/xxx.jpg)]
[外链图片转存失败(img-UXJVuQZx-1562138834019)(https://mp.csdn.net/mdeditor/xxx/xxx.jpg)]
</div>
hash
路由的本质是浏览器 location
对象中的 hash
属性,它会记录链接地址中 '#'
后面的内容(e.g.:#part1)。因此,我们可以通过监听 window.onhashchange
事件获取到跳转前后访问的地址,从而实现地址切换的目的。
history
路由
在之前的 html
版本中,我们可以通过 history.back(), history.forward()
和 history.go(number)
方法来完成在用户历史记录中向后和向前的跳转。而history
路由则是使用了 html5
中新增的 pushState
事件和 replaceState()
事件。
Vue
中的路由Vue Router
在 Vue
中,Vue Router
是官方提供的路由管理器。它和Vue.js
的核心深度集成,因此,不管是采用 hash
的方式还是使用 history api
实现我们的前端路由都有很好的支持,即Vue-router
或者react-router
是封装好的,兼容性更好的hash
或者H5 History
实现,所以这里我们采用Vue Router
这一组件来实现我们的前端路由。
Vue
中的路由Vue Router
实现
首先我们需要将Vue Router
添加引用到我们的项目中,这里我还是采用直接引用 js
文件的方式为我们的示例代码添加前端路由支持。然后在 Vue
中使用 Vue Router
构建单页面应用,我们只需要将组件 (components
) 映射到定义的路由 (routes
) 规则中,然后告诉 Vue Router
在哪里渲染它们,并将这个路由配置挂载到 Vue
实例节点上即可。
在
Vue Router
中,我们使用router-link
标签来渲染链接,当然,默认生成的是a
标签,如果你想要将路由信息生成别的html
标签,则可以使用tag
属性指明需要生成的标签类型。
<!-- 默认渲染成 a 标签 -->
<router-link to="/home">主页</router-link>
<!-- 渲染成 button 标签 -->
<router-link to="/home" tag="button">主页</router-link>
可以看到,当我们指定 tag
属性为 button
后,页面渲染后的的标签就变成了button
按钮。同样的,它还是会监听点击,触发导航。
同时,从上图可以看出,当前的链接地址为 #/home
,也就是说,通过 router-link
生成的标签,当页面地址与对应的路由规则匹配成功后,将自动设置class
属性值为 router-link-active
。当然,我们也可以通过指定 active-class
属性或者在构造 VueRouter
对象时使用 linkActiveClass
来自定义链接激活时使用的 CSS
类名。
<!-- 使用属性来设定自定义激活类名 -->
<router-link to="/home" active-class="aaaa">主页</router-link>
<!-- 在构造对象时设定全局默认类名 -->
const router = new VueRouter({
routes: [],
linkActiveClass: 'aaaaa'
})
当路由表构建完成后,对于指向路由表中的链接,需要在页面上找一个地方去显示已经渲染完成后的组件,这时,我们就需要使用 router-view
标签去告诉程序,我们需要将渲染后的组件显示在当前位置。
在下面的示例代码中,模拟了 Vue
中路由的使用,当访问#/home
时会进行加载home
组件,而当链接跳转到#/account
时则会加载account
组件。同时,我们可以发现,在 account
组件中又包含了两个子路由,通过点击 account
组件中的子路由地址,从而加载对应的 login
组件和register
组件。
<script src="../../lib/vue.js"></script>
<script src="../../lib/vue-router.js"></script>
<style>
.container {
background-color: aquamarine;
margin-top: 20px;
width: 740px;
height: 300px;
}
</style>
<div id="app">
<!-- 通过 router-link 标签来生成导航链接 -->
<router-link to="/home">主页</router-link>
<router-link to="/account">账户</router-link>
<div class="container">
<!-- 将选中的路由渲染到 router-view 下-->
<router-view></router-view>
</div>
</div>
<template id="tmpl">
<div>
<h3> account page </h3>
<!-- 生成嵌套子路由地址 -->
<router-link to="/account/login">登录</router-link>
<router-link to="/account/register">注册</router-link>
<!-- 生成嵌套子路由渲染节点 -->
<router-view></router-view>
</div>
</template>
<script>
// 1、定义路由跳转的组件模板
const home = {
template: '<div> home page </div>'
}
const account = {
template: '#tmpl'
}
const login = {
template: '<div> login page</div>'
}
const register = {
template: '<div> register page</div>'
}
// 2、定义路由信息
const routes = [{
path: '/',
redirect: '/home'
},
{
path: '/home',
component: home
},
{
path: '/account',
component: account,
children: [{
path: 'login',
component: login
},
{
path: 'register',
component: register
}
]
}
]
const router = new VueRouter({
//mode: 'history', //使用 history 模式还是 hash 路由模式
routes
})
// 3、挂载到当前 Vue 实例上
const vm = new Vue({
el: '#app',
data: {},
methods: {},
router: router
});
</script>
在上面的代码中,也使用到了嵌套路由和路由的重定向。通过使用路由重定向,我们可以将用户访问网站的根目录 /
时进行重定向到/home
,而嵌套路由则可以将 URL
中各段动态路径也按某种结构对应到实际嵌套的各层组件。
例如,这里的login
组件和 register
组件,它们都是位于 account
组件中的,因此,在构建url
时,我们应该将该地址位于 /account url
后面,从而更好地表达这种关系。所以这里,我们在accoun
t 组件中又添加了一个 router-view
标签,用来渲染出嵌套的组件内容。同时,通过在定义routes
时在参数中使用 children
属性,从而达到配置嵌套路由信息的目的。
以
/
开头的嵌套路径会被当作根路径,而我们的login
组件和register
组件都是包含在account
中,所以这里直接定义path
参数即可。