vueRouter是基于vue的前端路由库(设计成了 vue的插件)
让前端实现SPA(single page application)单页面应用
spa优点:切换速度快 (加载速度快)
缺点: 前端渲染 (nuxt 解决seo问题)
seo 搜索引擎优化 爬虫
不利于seo
npm 安装:
cnpm i vue-router
模块化工程中使用
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
页面首先会加载,全局唯一一个html
引入
<script src="vue.js">
后面引入vue-router
<script src="vue-router.js">
定义 路由组件
const Home = {
template:`
<div>
<h1>home页</h1>
</div>
`
}
const News = {
template:`
<div>
<h1>新闻页</h1>
</div>
`
}
创建路由对象,
routes规则在外部定义,有哪些路由,路由对应的组件是什么
const routes = [ // 路由规则
{
path: '/home',
component: Home
},
{
path: '/news',
component: News
}
]
// 创建路由对象
const router = new VueRouter({
routes
})
在实例上增加router属性
const vm = new Vue({
el:"xxx",
router
})
在模板上 需要 新增出口(占位)
在路由匹配到某个组件时,组件在router-view位置渲染
<router-view />
router-link组件做路由跳转
to定义跳转path,tag定义渲染的标签
在匹配的router-link中会自定加入 router-link-active 高亮类
<router-link to="/home" tag="button"></router-link>
解决 /路由默认显示 某个组件问题
1,新增路由规则
{
path: '/',
component: Home
}
2,重定向 推荐
当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b
可以使home router-link 高亮
{
path: '/',
redirect: '/home' // 当地址为 / 会自动变成/home
}
动态路由
当vue-router引入时,
如果是直接script src引入的话,
自动往构造函数以及原型中添加一个属性$route保存了当前路由的基础信息,
所有组件就可以直接通过 this.$route获取当前路由基础信息
定义动态路由:
routes = [
{
path:"/detail/:id", //定义一个动态路由 定义了一个变量是id
component: Detail
}
]
跳转:
此时 2 是 动态路由定义的 变量id 的值
router-link to="/detail/2"
获取:this.$route.params.定义变量名,获取动态路由传的参数
// path
{
path:"/a/:b/c/:d"
}
跳转路径: /a/b/c/d
/a/2/3/e 路径是错误的
结果:
this.$route.params
{
b:"b",
d:"d"
}
动态路由监听路由参数(动态路由传的动态的值)的变化
watch:{
"$route"(to, from){ // to去哪 from 从哪来
console.log('变化了')
console.log(to,from)
}
}
解决404
{
path:"*", // *匹配任意路由 尽量将404页面 路由规则放到最后
component: NoutFound
}
嵌套路由
一级路由中 在路由组件中 还可以显示 (根据路由的变化 父级组件)显示不同子级的组件
const routes = [
{
path: '/news',
component: News,
children: [ // 在父级路由规则中新增 children,在属性中定义二级路由
{
path: '/news/native', // 建议二级路由path 携带一级路由的path作为前缀
component: Native
},
{
path:"/news/abroad",
component: Abroad
}
],
}
]
// 在一级路由 对于的 组件中 新增router-view 作为二级路由 出口(占位)
const News = {
template:`
<div>
<h1>news组件</h1>
<router-view/>
</div>
`
}
<route-view />
命名路由
给每个路由规则新增name属性,相当于给每个路由起个名字
routes = [
{
path:'/home',
name:'首页', //给这个路由新增name属性
component:xxx
}
]
编程式导航
声明式导航:利用组件跳转路由(router-link)
编程式导航:js内部通过方法来控制路由跳转
跳转路由的参数同router-link的to属性
跳转路由 并往历史记录中添加一条新的记录
this.$router.push()
跳转路由 参数同router-link 的to 属性
跳转路由,不添加新记录 而是 覆盖当前的记录
this.$router.replace()
跳转路由
this.$router.go(n)
0 //刷新
-1 //回退一步
1 // 前进一步
n // 前进n步
别名
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
路由组件传参
- 动态路由传参
{
path:"/news/:id"
component:News
}
// 跳转时
<router-link to="/news/2">
// 获取
this.$route.params.id
- params传参
1,直接写字符串这种情况必须写path
router-link to="/news"
this.$router.push("/news")
2,参数可以是对象
router-link :to="{name:'home'}" 可以以名字跳转
params传参
1,声明式导航
<router-link :to="{name:'news',params:{a:10,b:20}}">
2,编程式导航
this.$router.push({name:'news',params:{a:10,b:20}})
获取:
this.$route.params.xxx
注意:
params传参 必须结合命名路由一起使用
跳转时,必须要通过name跳转,否则传不过去
params传参的优点:隐式传参 地址栏看不见
缺点:刷新后数据会丢失
- query传参
router-link
:to="{path:'/news',query:{a:10,b:20}}"
this.$router.push({
path:'/news',
query:{
a:10,
b:20
}
})
获取
this.$route.query.xxx
优点:刷新后 数据不丢失
缺点:参数放在地址栏上
query最好结合path 尽量不结合name
路由模式
1,hash模式
原理:利用浏览器的url 的hash值得变化(url加hash值 #/home)
利用 window.onhashchange 当地址栏的hash值改变时触发
优势:地址栏的 路径指向不会改变
缺点:丑
2,history模式
/home #/news 变成 xxx/home xxx/news
原理:h5新增的api history pushState方法和replaceState()方法
优点:好看 没有#
缺点:/写在最前面 代表根路径,在本地和浏览器运行不一样
导航守卫 、 导航钩子函数
监听甚至拦截路由变化
- 全局守卫 (拦截所有的路由)
// 全局前置 守卫
router.beforeEach((to,from,next)=>{
// to 目标路由
// from 从哪来路由
// next 拦截器 不调用next()路由无法进入,next参数同router-link to属性的值,重定向地址
next()
})
- 路由独享的 (定义在路由规则中,只拦截这个路由)
- 组件内部