用 Vue + Vue Router 创建单页应用非常简单:通过 Vue.js,我们已经用组件组成了我们的应用。当加入 Vue Router 时,我们需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们。
入门 | Vue Routerhttps://router.vuejs.org/zh/guide/
安装:
npm install vue-router@版本
或者在脚手架创建项目中选择 Router
配置:
安装完成后会在项目src文件夹下 自动新增 router 文件夹
router下 index.js:
//配置路由相关信息
import VueRouter from 'vue-router';
import Vue from "vue";
//1.用过Vue.use(插件) 来安装这个插件
Vue.use(VueRouter)
//2.创建VueRouter对象
const routes= [
{
// 重定向 意思页面默认进入到home路径
path: '/',
redirect:'/home'
},
]
const router =new VueRouter({
//配置路由和组件之间的嵌套关系
routes,
})
//将路由导出 然后在vue实例当中应用
export default router
main.js 中
import router from "./router";
new Vue({
router,
render: h => h(App)
}).$mount('#app')
使用:
首先在router/index.js 中配置组件与路径的对应关系
// 引入组件
// 之前引入import Home from "../components/Home";
// 这样写是懒加载 性能更高用到那个组件再加载
const Home = () => import('../components/Home')
const HomeNews = () => import('../components/HomeNews')
const HomeMessage = () => import('../components/HomeMessage')
const About = () => import('../components/About')
// 定义组件与路径的对应关系
const routes= [
{
path: '/',
redirect:'/home' // 重定向 进入页面时默认跳转到home
},
{path:'/home',
component:Home,
children:[ // 组件内部还可以包裹子路由
{
path: '',
redirect:'news' // 重定向 进入home时默认跳转到news
},
{
path:'news',
component:HomeNews,
meta:{
title:'首页',
show:true
}
},
{
path: 'message',
component:HomeMessage,
meta:{
title:'首页',
show:true
}
}
],
meta:{
title:'首页',
show:true
}
},
{path:'/about',
component:About,
meta:{ // meta 元数据 可以存放进入此路由的数据 例如进入此页面标题更新为 meta.title 根据meta.show 决定tabBar是否显示
title:'关于',
show:true
},
},
{
path:'/profile',
name:'danAn', // 除了路径名外 还可以通过 name 来标识跳转
component:Profile,
meta:{
title:'档案',
show:true
}
}
]
如何跳转
在想要展示的位置添加 <router-view></router-view>占位符
<keep-alive :exclude="['User','Profile','About']">
<router-view></router-view>
</keep-alive>
router-view 外部可疑包裹 keep-alive 决定里面的组件是否一致保持活跃(一般情况下跳转出去组件就会销毁) 还可以通过 exclude include 来指定 排除/包含 哪些组件
①手动输入具体路径
② 声明式导航 通过 router-link tag可以指定渲染标签 默认是a标签 可以指定渲染成按钮
<router-link to="/home" >首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-link :to="'/user" tag="button" replace>我的</router-link>
replace 控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种方式,分别为push和replace,push是追加历史记录,raplace是替换当前历史记录。路由跳转的默认方是push
当路由被激活时对应的router-link 会添加激活类名 .router-link-active
我们只需要在此类中添加想要的样式就可以了
.router-link-active{color: #fc3f1d}
还可以通过配置修改指定的样式名(一般不改)
const router =new VueRouter({
//配置路由和组件之间的嵌套关系
routes,
linkActiveClass:'active' // 改变默认选中添加的类名 一般不改
})
③ 编程式导航 通过事件触发回调函数 在当中进行操作
<button @click="pClick">query</button>
pClick(){
this.$router.push('/about') 跳转到指定路径
this.$router.back() 根据历史后退一步
this.$router.forward() 根据历史前进一步
},
路由传参params
在router/index.js 配置规则的时候先预留位置
{
path: '/animation/:id/:title',
component: Animation,
meta:{
title:'Vue动画',
show:true
},
进行跳转的时候可以传入参数
声明式导航
<router-link to="/animation/88/普大喜奔" tag="button" replace>Vue动画</router-link>
编程式导航
this.$router.push(`/animation/${id}/${title}`)
在组件页面中获取到传进来的参数
方法一: $route.params.id 获取
<h3>尊敬的用户:{{$route.params.id}}欢迎光临</h3>
方法二:通过props 接收
props:['id','title']
通常应用场景:跳转到商品详情页传入商品ID 根据ID请求对应商品数据
路由传参 query
声明式导航
<router-link :to="{path:'/profile',query:{name:'wu',age:'18',height:'1.81'}}">档案</router-link>
编程式导航
proClick(){
// 命名传参路由 路径过长时可以用自己设置的 name 代替 path
this.$router.push({
name:'danAn',
query:{
name:'wu',
age:18,
height:1.81
}
})
}
组件页面中展示
<h2>{{$route.query.name}}</h2>
<h2>{{$route.query.age}}</h2>
<h2>{{$route.query.height}}</h2>
params 传参结构较为简单 query 可以有更深的层级 具体使用哪一种看自己选择
小技巧 当url不想显示参数时 params可以使用 name 代替 path
$router 与 $route
$router是VueRouter的一个实例,他包含了所有的路由
为整体的路由添加记录
pClick(){
this.$router.push('/about') 跳转到指定路径
this.$router.back() 根据历史后退一步
this.$router.forward() 根据历史前进一步
},
$route 是某一个路由(当前路由)
获取当前路由的一些数据
<h2>{{$route.query.name}}</h2>
<h2>{{$route.query.age}}</h2>
<h2>{{$route.query.height}}</h2>
路由守卫
全局前置守卫
传入三个参数
from 从哪个页面
to 要跳转到哪个页面
......进行操作
next() 放行 可以进行操作判断后再放行
全局后置首位
跳转到新的页面之后 干什么
这里是根据meta.tltle 修改页面标题
//这个函数要三个参数 next() 调用该方法后才能进入下一个钩子
// 前置守卫
router.beforeEach((to,from,next)=>{
// 从from跳转到to
document.title=to.matched[0].meta.title
//console.log(to);
next()
})
//后置钩子 hook
router.afterEach((to,from)=>{
//console.log('钩子');
})
通常情况下还可以判定权限
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
/** to 将要访问的路径
* from 代表从哪个路径跳转而来
* next 表示放行
* **/
if (to.path === '/login') return next()// 去访问登录页面 直接放行
if (to.path === '/welcome'){
window.sessionStorage.removeItem('currPath')
next()
}
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')// 访问其他页面 检验有没有 token 没有就跳转到 login
next()
})
路由独享首页
{path:'/about',
component:About,
meta:{
title:'关于',
show:true
},
//独享守卫
beforeEnter:((to,from,next)=>{
console.log('关于的独享守卫被打印');
next()
})
},
组件内守卫
<template>
<h2>我是About组件的内容</h2>
</template>
<script>
export default {
name:'About',
// 通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
console.log('About--beforeRouteEnter',to,from)
if(localStorage.getItem('school')==='atguigu'){
next()
}else{
alert('学校名不对,无权限查看!')
}
},
// 通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
console.log('About--beforeRouteLeave',to,from)
next()
}
}
</script>