1.路由的概念:
对应关系
2.前端路由的概念:
hash地址与组件之间的对应关系(和锚链接类似)
3.什么是url的hash地址:
url链接中#号及之后的部分
4.案例:
锚链接
5.前端路由的工作方式:
a.用户点击了页面上的路由链接,URL地址栏中的hash值发生了变化
b.前端路由监听hash地址的变化
c.前端路由把当前hash地址对应的组件渲染出来
6.小知识:
获取当前页面hash地址-----location.hash
7.小知识:
window.onhashchange事件监听hash地址的变化
8.案例:
手动实现简易路由
9.vue-router:
vue官方提供的路由解决方案,能够轻松的管理SPA项目中组件的切换
10.vue-router手动安装、配置和使用(vue-cli可自动安装配置)
a.安装vue-router
npm i vue-router -S
b.创建路由模块(js文件)
在src目录下新建router/index.js路由模块,并初始化代码
//导入Vue是为了能使用Vue.use()函数
import Vue from 'vue'
//导入vue-router
import VueRouter from 'vue-router'
//调用Vue.use()函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
// 创建路由的实例对象
const router = new VueRouter()
// 向外共享路由的实例对象
export default router
c.在main.js中导入并挂载路由模块
import Vue from 'vue'
import App from './App.vue'
// 导入 bootstrap 样式
import 'bootstrap/dist/css/bootstrap.min.css'
// 全局样式
import '@/assets/global.css'
// 导入路由模块
// import router from './router/index.js'
// 在进行模块化导入时,如果给定的是文件夹,则默认导入该文件夹下名为index.js的文件
import router from './router'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// 挂载路由
// router:router,
// 键和值相同可简写
router
}).$mount('#app')
d.使用:
(1)在App.vue中声明路由链接和占位符
<template>
<div class="app-container">
<h1>App 组件</h1>
<!--
<a href="#/home">首页</a>
<a href="#/movie">电影</a>
<a href="#/about">关于</a> -->
<!-- 只要项目中安装配置了vue-router,就可以使用router-link组件了 -->
<!-- router-link的作用是替换超链接标签 -->
<!-- #号不用再写了,会被自动加上-->
<router-link to="/home">首页</router-link>
<router-link to="/movie">电影</router-link>
<router-link to="/about">关于</router-link>
<hr />
<!-- 只要项目中安装配置了vue-router,就可以使用router-view组件了 -->
<!-- router-view的作用是作为组件切换的占位符 -->
<router-view></router-view>
</div>
</template>
<script></script>
<style lang="less" scoped></style>
(2)在路由模块(router/index.js)中声明路由规则
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '../components/Home.vue'
import Movie from '../components/Movie.vue'
import About from '../components/About.vue'
Vue.use(VueRouter)
// 创建路由的实例对象
const router = new VueRouter({
// routes是一个数组,作用:定义hash地址和组件的对应关系--路由规则
routes:[
//当用户访问/的时候,通过redirect属性跳转到/home对应的路由规则
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{path:'/about',component:About},
]
})
export default router
11.嵌套路由
a.概念:
通过路由实现组件的嵌套展示
b.使用:
(1)在about组件中声明子路由链接和占位符
<template>
<div class="about-container">
<h3>About 组件</h3>
<router-link to="/about/tab1">Tab1</router-link>
<router-link to="/about/tab2">Tab2</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script></script>
<style lang="less" scoped></style>
(2)在路由模块router/index.js中通过children声明嵌套路由规则
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '../components/Home.vue'
import Movie from '../components/Movie.vue'
import About from '../components/About.vue'
import Tab1 from '../components/tabs/Tab1.vue'
import Tab2 from '../components/tabs/Tab2.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes:[
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{
path:'/about',
component:About,
//子路由
children:[
{path:'tab1',component:Tab1},
{path:'tab2',component:Tab2}
]
}
]
})
export default router
(3)以上不能在进入about组件时自动显示tab1组件,解决这个问题有两种方式:
(a)通过rediret解决:
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '../components/Home.vue'
import Movie from '../components/Movie.vue'
import About from '../components/About.vue'
import Tab1 from '../components/tabs/Tab1.vue'
import Tab2 from '../components/tabs/Tab2.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes:[
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{
path:'/about',
component:About,
redirect:'/about/tab1',
children:[
{path:'tab1',component:Tab1},
{path:'tab2',component:Tab2}
]
}
]
})
export default router
(b)通过默认子路由解决:
在默认子路由中,如果children数组中某个路由规则的path值为空字符串,这条规则叫默认子路由,并且自动进入此组件
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '../components/Home.vue'
import Movie from '../components/Movie.vue'
import About from '../components/About.vue'
import Tab1 from '../components/tabs/Tab1.vue'
import Tab2 from '../components/tabs/Tab2.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes:[
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{
path:'/about',
component:About,
children:[
//默认子路由
{path:'',component:Tab1},
{path:'tab2',component:Tab2}
]
}
]
})
export default router
同时需要在about组件中更改声明的子路由链接
<template>
<div class="about-container">
<h3>About 组件</h3>
//修改
<router-link to="/about">Tab1</router-link>
<router-link to="/about/tab2">Tab2</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script></script>
<style lang="less" scoped></style>
12.动态路由
a.概念:
把hash地址中可变的部分定义为参数项,从而提高路由规则的复用性
b.使用:
在vue-router中使用英文冒号 : 定义路由的参数项
c.案例:
(1)如果存在场景:
<router-link to="/movie/1">电影1</router-link>
<router-link to="/movie/2">电影2</router-link>
<router-link to="/movie/3">电影3</router-link>
<router-view></router-view>
(2)路由规则定义如下:
{path:'/movie/:id',component:Movie},
//如果有1w个电影,要定义1w个路由规则,这样路由规则的复用性太差
//{path:'/movie/1',component:Movie},
//{path:'/movie/2',component:Movie},
//{path:'/movie/3',component:Movie},
(3)在movie组件中获取动态参数id(方式一)
//this可省略
//this.$route.params.id
$route.params.id
//$route是vue内置对象,是路由的参数对象
//$router是vue内置对象,是路由的导航对象
(4)在movie组件中获取动态参数id(方式二,props传参)
{path:'/movie/:id',component:Movie,props:true}
<template>
<p>{{ id }}</p>
</template>
<script>
export default {
//props:['id']
props:{
id:{
default: ,
type: ,
required:
}
}
}
</script>
<style></style>
d.动态组件拓展
(1)$route是vue内置对象,是路由的参数对象
(2)$router是vue内置对象,是路由的导航对象
(3)在hash地址中,/后面的参数项叫路径参数,通过$route.params访问
(4)在hash地址中,?后面的参数项叫查询参数,通过$route.query访问
(5)在$route中,还有fullPath和path属性。fullPath是完整地址,path只包含路径部分
13.导航
a.声明式导航:
在浏览器中,通过点击链接实现导航的方式,叫做声明式导航。a链接、<router-link>都属于声名式导航
b.编程式导航:
location.href跳转方式,属于编程式导航
c.vue-router中的编程式导航API
this.$router.push('hash地址') --- 跳转,并增加一条历史记录
this.$router.replace('hash地址') --- 跳转,替换当前的历史记录
this.$router.go(数值n) --- 在浏览历史中前进或后退
this.$router.back() --- 在历史记录中,后退到上一个页面
this.$router.forward() --- 在历史记录中,前进到下一个页面
14.导航守卫
a.作用:
导航守卫可以控制路由的访问权限
b.全局前置守卫:
每次发生路由的导航跳转时,都会触发全局前置守卫。
可对每个路由进行访问权限的控制
在路由模块index.js中声明使用:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({})
//全局前置守卫
//只要发生了跳转,就会触发beforeEach中的回调函数
router.beforeEach(function(to,from,next){
//to是将要访问的路由的信息对象
//form是将要离开的路由的信息对象
//next是一个函数,调用next()表示放行,允许此次路由跳转
next()
})
export default router
next的三种调用方式:
next()---放行
next('hash地址')---强制跳转其他路由
next(false)---停留原路由,不做跳转
c.案例:
登录权限控制
d.额外说明:
在使用导航守卫时,如果有很多个路由需要判断,可以这样:
router.beforeEach(function(to,from,next){
//数组过长可以用外部js文件,再导入使用
const pathArr = ['/home','/home/users','/home/rights']
if(pathArr.indexOf(to.path) !== -1){
if(localStorage.getItem('token')){
next()
}else{
next('/login')
}
}else{
next()
}
})
也可以使用正则匹配、截取字符串、是否包括字符串判断