使用
路由的安装:npm install vue-router --save 也可以在安装脚手架进行选择
在src中创建router文件夹里面创建一个index.js
index.js
//配置路由相关信息
//引入Vue
import Vue from 'vue'
//1.导入路由插件
import VueRouter from 'vue-router'
//2.通过Vue.use(插件),安装插件
Vue.use(VueRouter);
//3.引入自己写的组件
import Home from '../components/Home.vue'
import About from '../components/About.vue'
//4.创建VueRouter对象
const router = new VueRouter({
//配置路由和组件之间的映射关系
routes:[
{//每个路径是一个路径 path属性写路径 component显示的组件
path:'/home',
component:Home,
},
{
path:'/about',
component:About,
}]
});
//3.将router对象传入vue实例中
export default router;
Home.vue和About.vue组件
在components文件夹下
//Auout.vue
<template>
<div>
<h2>我是关于</h2>
<p>呵呵呵</p>
</div>
</template>
<script>
export default {
name:"About"
}
</script>
<style scoped></style>
//Home.vue
<template>
<div>
<h2>我是首页</h2>
<p>哈哈哈</p>
</div>
</template>
<script>
export default {
name:"Home"
}
</script>
<style scoped></style>
App.vue
<template>
<div id="app">
//router-link 在router组件中 由于在index.js以注册进vue直接使用即可 会被渲染成a标签 to写路径
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
//router-view 相当于占位 点击上面两个标签 显示的内容会展示在router-view的位置
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style></style>
main.js
import Vue from 'vue'
import App from './App.vue'
//将router对象导入进来
import router from './router/index.js'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
设置重定向
在routers数组中 //当访问/的时候默认跳到/home
{
path:'/',
redirect:'/home'
}
修改url模式
const router = new VueRouter({
//配置路由和组件之间的映射关系
routes: [
{//每个路径是一个路径 path属性写路径 component显示的组件
path: '/home',
component: Home,
},
{
path: '/about',
component: About,
},
{
path: '/',
redirect: '/home'
}
],
mode:'history',//默认是hash url带#通过mode属性修改为history url路径就不带#号了
});
router-link
<router-link to =""></router-link> to属性 用于指定跳转路径
<router-link tag =""></router-link> tag属性 用于指定渲染成什么标签 默认a标签
<router-link replace></router-link> replace属性 没有值 设置后退键不能返回到上个页面
<router-link active-class =""></router-link> active-class属性 当路由匹配成功后会默认给当前元素增加一个router-link-active的class 可以通过active-class进行重新设置
通过代码实现跳转
<template>
<div id="app">
<button @click="homeClick">首页</button>
<button @click="aboutClick">关于</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
methods:{
homeClick(){
this.$router.push('home');//跳转后可以后退
this.$router.replace('/home')//跳转后不可以后退
},
aboutClick(){
this.$router.push('about');
this.$router.replace('/about')
}
}
}
</script>
动态路由的使用
router设置
{
path:'/user/:userId',//通过:userId进行占位 在对应组件中通过 this.$route.userId变化的值
component:User
},
给占位赋值
<div id="app">
<router-link :to="'/user/'+userId">用户</router-link> //进行绑定的方式引用data的值
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
userId:"zhangsan"
}
}
}
</script>
<template>
<div>
<h2>用户界面</h2>
<p>相关信息</p>
<h2>{{userId}}</h2> $route.params.userId 可以直接获取 不用通过计算属性
</div>
</template>
<script>
export default {
name:'User',
computed:{
userId(){
$route和$router不同 $router是获取的路由 $route获取的是刚点击的路由也就是活跃的路由
return this.$route.params.userId;//获取变化的值 userId是在路由中设置的占位
}
}
}
</script>
路由的懒加载
router文件下
{
path: '/about',
component:()=>import('../components/About.vue')
},
路由的嵌套
比如在/home页面中 通过/home/news访问其他一些内容
const router = new VueRouter({
routes: [
{
path: '/home',
component: () => import('../components/Home.vue'),
children: [//设置子路径
{
path:'/',
redirect:'new'//设置进入home路径默认选择的子路径
},
{
path: 'new',//不要加/new
component:()=>import('../components/HomeNew.vue'),
}
],
},
],
});
在Home.vue中
<template>
<div>
<h2>你好 home</h2>
<router-link to="/home/new">new</router-link>
<router-view></router-view>
</div>
</template>
参数传递
两种方式
params的类型
配置路由格式 :/router/:id
传递方式:在path后跟上对应值//动态路由的使用
格式:/router/123
<router-link :to="'/user/' + userId">用户</router-link>
获取:{{$route.params.userId}}
query的类型
配置路由的格式:/router
传递方式 对象中使用query的key作为传递方式
格式:/router?id=123
实现:<router-link :to="{path:'/about', query:{id:123}}">关于</router-link>
//绑定to属性通过对象的方式传递路径和参数
获取:{{$route.query.id}}
代码跳转传递参数
methods: {
homeClick() {params的类型
this.$router.push("/user/" + "111");
},
aboutClick() {query的类型
this.$router.push({ path: "/about", query: { id: 123}});
}
}
导航守卫
路由全局守卫
实现需求 跳转到/home 将页面的title改为首页
{
path: '/home',
meta:{
title:"首页"
},
component: () => import('../components/Home.vue'),
},
设置:通过路由的meta:{} 属性设置信息 meta:{key,value}
获取:通过路由对象的beforeEach方法
router.beforeEach((to, from, next) => {
to:路由到的地方
from:从哪个路由来 从from路由到to路由
next:是方法 必须调用 用来向下执行的 next();可以指定路径可以做登录判断使用 next({path:"/"})
next(false) 可以中断向下执行
to.meta.key的方式获取设置的值
to.matched获取的是当前路由下全部meta 上面如果嵌套路由只能获取到子路由设置的meat中设置的属性
to.matched[0]获取当前路由的第一个meta也就是父路由
document.title = ;
next();
})
路由独享守卫
{
path: '/about',
meta: {
title: "关于"
},
component: () => import('../components/About.vue'),
beforeEnter(to,from,next){
console.log();
next();
}
},
组件内守卫
export default {
name: "App",
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
next(vm => {
// 通过 `vm` 访问组件实例
})
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
通过遍历获取router中的内容动态显示内容
router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//导入Login.vue模块
const Login = () => import("./views/Login");
const Home = () => import("./views/Home");
const Test1 = () => import("./views/Test1");
const Test2 = () => import("./views/Test2");
const routes = [
//Login
{
path: "/",
name: "Login",
component: Login,
hidden:true
},
//Home
{
path: "/home",
name: '导航一',
component: Home,
children: [
//Test1
{
path: "/test1",
name: '选项一',
component: Test1
},
//Test2
{
path: "/test2",
name: '选项二',
component: Test2
},
]
},
]
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes
})
Home.vue
<el-menu router> //router 开启路由模式 开启路由模式后不需要设置点击事件只需要绑定index 就会自动跳转到index设置的路径中去
<el-submenu index="1"
v-for="(item,index) in this.$router.options.routes" <!--this.$router.options.routes 获取全部的路由 进行遍历-->
:key="index"
v-if="!item.hidden"> <!--item.hidden hiden自定义的属性 来控制那个不显示-->
<template slot="title">
<i class="el-icon-location"></i>
{{item.name}} <!--item.name 获取路由中设置的name-->
</template>
<el-menu-item-group>
<el-menu-item v-for="(children,indexj) in item.children" <!--item.children 获取路由中的子路由-->
:index="children.path" <!--child ren.path获取路由设置的路径 给index进行绑定 --> index 在这设置的
:key="indexj">
{{children.name}} <!--children.name获取路由设置的名字-->
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
将对象转化成路由对象
两种方式都是路由懒加载的方式 通常第二种常用 第一种可以在对象中直接进行判断 第二种需要在对象中判断在加入进去
方式一
let fmRouter = {
path: routers.path,
name: routers.name,
icoCls: routers.icoCls,
children: routers.children,
component(resolve) {
if (routers.component.startsWith("Home")) {
require(['../views/' + routers.component + '.vue'],resolve)
} else if (routers.component.startsWith("Emp")) {
require(['../views/emp/' + routers.component + '.vue'],resolve)
} else if (routers.component.startsWith("Per")) {
require(['../views/per/' + routers.component + '.vue'],resolve)
} else if (routers.component.startsWith("Sal")) {
require(['../views/sal/' + routers.component + '.vue'],resolve)
} else if (routers.component.startsWith("Sta")) {
require(['../views/sta/' + routers.component + '.vue'],resolve)
} else if (routers.component.startsWith("Sys")) {
require(['../views/sys/' + routers.component + '.vue'],resolve)
}
}
}
方式二
function msyformateRouter(myformateRouter) {
let res = [];
for (let i = 0; i < myformateRouter.length; i++) {
let routers = myformateRouter[i]
if (routers.children && routers.children != null) {
routers.children = msyformateRouter(routers.children)
}
let fmRouter = {
path: routers.path,
name: routers.name,
icoCls: routers.icoCls,
children: routers.children,
component: null
}
if (routers.component.startsWith("Home")) {
fmRouter.component = () => import('../views/' + routers.component + '.vue')
} else if (routers.component.startsWith("Emp")) {
fmRouter.component = () => import('../views/emp/' + routers.component + '.vue')
} else if (routers.component.startsWith("Per")) {
fmRouter.component = () => import('../views/per/' + routers.component + '.vue')
} else if (routers.component.startsWith("Sal")) {
fmRouter.component = () => import('../views/sal/' + routers.component + '.vue')
} else if (routers.component.startsWith("Sta")) {
fmRouter.component = () => import('../views/sta/' + routers.component + '.vue')
} else if (routers.component.startsWith("Sys")) {
fmRouter.component = () => import('../views/sys/' + routers.component + '.vue')
}
res.push(fmRouter);
}
return res;
}
keep-alive
keep-alive是Vue内部定义的组件 可以使被包含的组件保留状态 或避免重新渲染
<keep-alive inclue=""></keep-alive>
include="组件的name" 字符串或正则 只有匹配的组件才会被缓存 多个通过,隔开
exclude="组件的name" 字符串或正则 匹配到的组件不会被缓存