多个路由通过路由器进行管理。
前端路由的概念和原理
(编程中的)路由(router)就是一组key-value
对应关系,分为:后端路由和前端路由
后端路由指的是:请求方式、请求地址和function处理函数之间的对应关系
在SPA程序中,所有组件的展示和切换都在这唯一的一个页面内完成,此时,不同组件之间的切换需要通过前端路由来实现
通俗易懂的来说,前端路由是:Hash地址(url中#的部分)与组件之间的对应关系
前端路由的工作方式
- 用户点击了页面上的路由链接
- 导致了URL地址栏中的Hash值发生了变化
- 前端路由监听到了Hash地址的变化
- 前端路由把当前Hash地址对应的组件渲染到浏览器中
实现简易的前端路由(底层实现原理)
App.vue根组件
这是App根组件
Home
Movie
About
vue-router的基本使用
vue-router是vue.js官方给出的路由解决方案,它只能结合vue项目进行使用,能够轻松的管理SPA项目中的组件切换。
- vue-router 3.x 只能结合vue2进行使用,官方文档:https://router.vuejs.org/zh/
- vue-router 4.x 只能结合vue3进行使用,官方文档:https://next.router.vuejs.org/
二者差异主要是在声明router配置文件上。
vue-router 3.x的基本使用步骤
- 在项目中安装vue-router
npm install vue-router@3.5.2 -S
- 在
src
源代码目录下,新建router/index.js
路由模块
//导入包
import Vue from 'vue'
import VueRouter from 'vue-router'
//插件引入
Vue.use(VueRouter)
//创建路由的实例对象
const router = new VueRouter
//向外共享
export default router
- 在入口文件
main.js
中引入
import router from '@/router/index.js'
......
new Vue({
...
router:router
...
}).$mount('#app')
vue-router 4.x的基本使用步骤
- 在项目中安装vue-router
npm install vue-router@next -S
- 定义路由组件
MyHome.vue、MyMovie.vue、MyAbout.vue
- 声明路由链接和占位符
可以使用
标签(会被渲染成a链接)来声明路由链接,并使用
标签来声明路由占位符
这是App根组件
首页
电影
我的
- 创建路由模块
从项目中创建router.js路由模块,按照以下四步:
从vue-router中按需导入两个方法
import { createRouter, createWebHashHistory } from 'vue-router' //createRouter方法用于创建路由的实例对象 //createWebHashHistory用于指定路由的工作方式(hash模式)
导入需要使用路由控制的组件
import MyHome from './MyHome.vue' import MyMovie from './MyMovie.vue' import MyAbout from './MyAbout.vue'
创建路由实例对象
const router = createRouter({ history: createWebHashHistory(), routes: [ { path: '/home', component: MyHome }, { path: '/movie', component: MyMovie }, { path: '/about', component: MyAbout }, ] })
向外共享路由实例对象
export default router
在main.js中导入并挂载路由模块
import { createApp } from 'vue' import App from './App.vue' import './index.css' import router from './components/router' const app = createApp(App) //挂载路由写法 app.use(router) app.mount('#app')
- 导入并挂载路由模块
vue-router的高级用法
路由重定向
指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特点的组件页面
通过路由规则的redirect属性,指定新的路由地址
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/',redirect:'/home' //访问根路径会重定向到home组件
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout
},
]
})
路由传参
query
参数
我的
我的
params
参数
声明时:
path:'/about/home/message/:id/:title'
我的
我的
this.$route 是路由的”参数对象”
this.$router 是路由的”导航对象”
路由高亮
- 使用默认的高亮class类名
被激活的路由链接,默认会使用router-link-active的类名,开发者可以使用此类名选择器,为激活的路由链接设置高亮样式
- 自定义路由高亮的class类
在创建路由的实例对象时,开发者可以基于linkActiveClass属性,自定义类名
const router = createRouter({
history: createWebHashHistory(),
linkActiveClass:'active-router',
routes: [
{
path: '/home', component: MyHome
},
{
path: '/',redirect:'/home' //访问根路径会重定向到home组件
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout
},
]
})
嵌套路由
通过路由来实现组件的嵌套展示
步骤:
- 声明子路由链接和子路由占位符
MyAbout组件
tab1
tab2
- 在父路由规则中,通过children属性嵌套声明子路由规则
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout,children:[
{
path:'tab1',component:Tab1
},
{
path:'tab2',component:Tab2
},
]
},
]
})
子路由规则的path不要以/开头
在嵌套路由中实现路由的重定向
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/movie', component: MyMovie
},
{
path: '/about',
component: MyAbout,
redirect:'/about/tab1',
children:[
{
path:'tab1',component:Tab1
},
{
path:'tab2',component:Tab2
},
]
},
]
})
动态路由匹配
指的是:把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性,在vue-router中使用英文冒号:来定义路由的参数
{
path: '/movie/:id', component: MyMovie
},
获取动态路由参数值的方法:
- $route.params参数对象
Mymovie组件---{{$route.params.id}}
- 使用props接受路由参数
{
path: '/movie/:id', component: MyMovie,
props: true,
},
为了简化路由参数的获取形式,vue-router允许在路由规则中开启props传参
编程式导航
通过调用API实现导航的方式,叫做编程式导航,与之对应的,通过点击链接实现导航的方式,叫做声明式导航。
- 普通网页中点击a链接,vue项目中点击
都属于声明式导航 - 平台网页中调用
location.herf
跳转到新页面的方式,属于编程式导航
vue-router中编程式导航API
- this.$router.push(‘hash地址’) 跳转到指定Hash地址,并增加一条历史记录,从而展示对应的组件。
- this.$router.replace(‘hash地址’) 跳转到指定Hash地址,并替换当前的历史记录,从而展示对应的组件。
- this.$router.go(‘数值n’) 实现导航历史的前进、后退(-1),超过最大层数,则原地不动。
$router.back() 后退到上一层页面
$router.forward() 前进到下一层页面
命名路由
通过name属性为路由规则定义名称,叫做命名路由,name值不能重复,具有唯一性
Hash地址特别长时体现出命名路由的优势
- 使用命名路由实现声明式导航
MyHome组件
goToMovie
- 使用命名路由实现编程式导航
MyHome组件
导航守卫
导航守卫可以控制路由的访问权限
如何声明全局的导航守卫
全局的导航守卫会拦截每个路由规则,从而对每个路由都进行访问权限的控制
const router = createRouter({
...
})
//调用路由实例对象的beforeEach函数,fn必须是一个函数吗,每次拦截后,都会调用fn进行处理
//声明全局的导航守卫,fn称为守卫方法
router.beforeEach(fn)
router.beforeEach(()=>{
console.log('Ok')
})
守卫方法的三个形参(可选)
router.beforeEach((to,from,mext)=>{
console.log('Ok')
//to 目标路由对象(信息)
//from当前导航正要离开的路由对象
//next 是一个函数,表示放行
})
注:
在守卫方法中不声明next形参,则默认允许用户访问每一个路由
在守卫方法中声明了next形参,则必须调用next()函数,否则不允许用户访问如何一个路由!
next函数的3种调用方式
//声明全局的导航守卫
router.beforeEach((to, from, next) => {
if (to.path === '/main') {
//证明用户要访问后台主页
next(false)//强制用户停留在之前所处的组件
next('login')//强制用户调转到指定页面
} else {
//证明用户要访问的不是后台主页
next()
}
})
结合token控制后台主页的访问权限
router.beforeEach((to, from, next) => {
const tokenStr = localStorage.getItem('token') //读取token
if (to.path === '/main' && !tokenStr) { //token不存在,需要登录
//证明用户要访问后台主页
// next(false)//强制用户停留在之前所处的组件
next('login')//强制用户调转到指定页面
} else {
//证明用户要访问的不是后台主页
next()
}
})
Hash&History
路由器的两种工作模式:hash
&history
。
对于url
来说:#及后面的内容就是hash
值,hash
值不会带给服务器。
hash
模式:
- 地址中永远带着
#
号,不美观; - 若地址校验严格,会被标记为不合法;
- 兼容性较好;
history
模式:
- 地址干净,美观;
- 兼容性比
hash
模式较差; - 应用部署上线需要后端支持,解决刷新页面服务端404问题;(
node
可以使用connect-history-api-fallback
)
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net