一、路由的基本使用
1、安装vue-router,命令:npm i vue-router
2、应用插件:Vue.use(VueRouter)
3、编写router配置项:
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../components/About'
import Home from '../components/Home'
//创建并暴露一个路由器
export default new VueRouter({
routes: [
{
path: '/about',
component:About
},
{
path: '/home',
component:Home
}
]
})
4、main.js中需要引入Router和使用vue-router插件和在vm中应用router
//引入vue
import Vue from 'vue';
//引入App
import App from './App.vue';
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router/index.js'
//停止生产提示
Vue.config.productionTip = false;
//使用vue-router插件
Vue.use(VueRouter)
//创建一个vm
new Vue({
render: h => h(App),
router:router
}).$mount('#app');
4、app.vue中要配置active-class
实现切换和<router-view></router-view>
实现指定展示位置
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demo</h2></div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始html中我们使用a标签实现页面的跳转 -->
<!-- <a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a> -->
<!-- 组件中借助router-link实现页面的跳转 -->
<!-- active-class :该元素被激活时的样式 -->
<router-link class="list-group-item" active-class="active" to="/about"
>About</router-link
>
<router-link class="list-group-item" active-class="active" to="/home"
>Home</router-link
>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
5、几个使用的注意要点
1) 路由组件通常存放在pages文件夹,一般组件通常存放在commponents文件夹中
2) 通过切换,'隐藏’了的路由组件,默认是被销毁掉的,需要时候再去挂载
3) 每个租价都有自己的$route
属性,里面存储着自己的路由信息。
4) 整个应用只有一个router
,可以通过组件的$router
属性获取到。
路由的query参数
- query参数的两种写法
(下面这个组件中配置好的参数会传递给后面那个接收参数的组件)
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<!-- 感想:遇到字符串和js代码要混写请第一时间想到模板字符串 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{
m.title
}}</router-link>
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link
:to="{
path: '/home/message/detail',
query: {
id: m.id,
title: m.title,
},
}"
>{{ m.title }}</router-link
>
</li>
</ul>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Message",
data() {
return {
messageList: [
{ id: "001", title: "消息001" },
{ id: "002", title: "消息002" },
{ id: "003", title: "消息003" },
],
};
},
};
</script>
<style>
</style>
2. 接收参数:(在接收参数的组件中进行配置)
<template>
<div>
<ul>
<li>消息详情:{{ $route.query.id }}</li>
<li>消息列表: {{ $route.query.title }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Detail",
};
</script>
<style>
</style>
路由命名
-
作用:简化路由跳转时path参数的编写
-
使用:
第一步命名一个路由
第二步,把path改为name来写路径
路由的params参数
- 其实模板的params参数和query参数是一样效果的
- 第一步:在路由中指定占位符
2. 第二步:在指定了占位符的组件中更改接收器的配置(改成关于params读取数据的)
3. 第三步:修改params形式对应路径读取形式
- 或者
路由的props配置
作用:让路由组件更方便的收到参数
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'
import Detail from '../pages/Detail'
//创建并暴露一个路由器
export default new VueRouter({
routes: [
{
path: '/about',
component:About
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component:News,
},
{
path: 'message',
component: Message,
children: [
{
name: 'xiangqin',
path: 'detail/:id/:title',
component: Detail,
//props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给detail组件
//这种方法会把数据写死不太好
// props: { a: 1, b: 'hello' },
//props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props形式传给Detail组件
// 但是query传参方法不能这样用
// props: true,
//props第三种写法,值为函数(这个方法既不会写死又两个方法都可以用)
// 函数的方法中props是一个回调函数,其中可以接收参数
props($route) {
return{id:$route.params.id,title:$route.params.title}
},
//对第三个方法解构赋值写法:
// props(query) {
// return{id:query.id,title:query.title}
// }
}
]
}
]
}
]
})
- 图解:
2. 第二部对应的Detail组件中需要如下配置
router-link的replace模式
- 作用:控制路由跳转时操作浏览器历史记录的模式
- 浏览器的历史记录又两种方式:分别为push和replace,push时追加历史记录,replace是替换当前记录(当前之前的记录是不影响的)。路由跳转的时候默认为push
- 如何开启replace模式:
<router-link replace .....>xxx</router-link>
编程式路由导航
1.作用:不借助<router-link>
实现路由添砖,让路由跳转更加灵活
2. 具体编码:
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{
m.title
}}</router-link> -->
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link
replace
:to="{
name: 'xiangqin',
params: {
id: m.id,
title: m.title,
},
}"
>{{ m.title }}</router-link
>
<button @click="push(m)">push</button>
<button @click="replace(m)">replace</button>
</li>
</ul>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Message",
data() {
return {
messageList: [
{ id: "001", title: "消息001" },
{ id: "002", title: "消息002" },
{ id: "003", title: "消息003" },
],
};
},
methods: {
push(m) {
this.$router.push({
name: "xiangqin",
params: {
id: m.id,
title: m.title,
},
});
},
replace(m) {
this.$router.replace({
name: "xiangqin",
params: {
id: m.id,
title: m.title,
},
});
},
},
};
</script>
<style>
</style>
2. 几个router中的api
缓存路由组件
- 作用:让不展示的路由组件保持挂载,不被销毁
- 具体编码:
两个新的生命周期钩子
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
- 具体代码:
路由的守卫
-
路由前置守卫
①路由中配置:
//全局前置路由守卫---初始化的时候被调用、每一次切换之前被调用
router.beforeEach((to,from,next) => {
console.log(to, from)
if (to.meta.isAuth) {
if (localStorage.getItem('school') === 'atguigu') {
next()
} else {
alert('学校名不对,无权限查看!')
}
} else {
next()
}
})
export default router
②在需要守卫的路由里添加meta属性
-
后置路由守卫(我们用的最多的就是他的看门狗功能,在最后为title改个名字)
①路由中配置:
//全局后置路由守卫,初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
console.log('后置路由守卫',to,from)
document.title = to.meta.title || '系统'
})
②在需要守卫的路由里添加meta属性
- 得到的效果(看门狗功能)
独享路由守卫
- 独享路由守卫只有一个前置的,可以和全局后置路由守卫搭配使用
对应代码:
beforeEnter(to, from, next) {
console.log('beforeEnter', to, from)
if (to.meta.isAuth) {
if (localStorage.getItem('school') === 'atguigu') {
next()
} else {
alert('暂无限权查看')
}
} else {
next()
}
}
组件内守卫
// 进入守卫通过路由规则,进入该组件时被调用
//(是指从一个路由到我们这个路由会调用这个进入守卫)
beforeRouteEnter(to, from, next) {
console.log(to, from, "我是beforeRouteEnter守卫");
next();
},
//离开守卫,通过路由规则,离开该组件时被调用
//(从我们这个路由到别的路由会调离开守卫)
beforeRouteLeave(to, from, next) {
console.log(to, from, "我是beforeRouterleave守卫");
next();
},
history和hash模式
- 对于一个url来说,什么时hash值? # 及其后面的内容就是hash值。
- hash值不会包含在HTTP请求中,即:hash值不会带给服务器。
- hash模式:
1) 地址中永远带着 # 号,不美观。
2) 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
3) 兼容性较好。 - history模式:
1)地址干净,美观
2) 兼容性和hash模式相比略差。
3)应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
- 如下它是写在router中的mode中的