官网: https://router.vuejs.org/zh/
①vue-router是Vue的路由插件,专门实现SPA 。单页面应用指的是只有一个网页,点击网页中的链接进行路由跳转,页面只会局部更新组件,组件数据需要通过AJAX请求。
②安装vue-router并引入。注意Vue2.0搭配vue-router3.0,Vue3.0搭配vue-router4.0。
npm i vue-router@3
③只有安装了vue-router,创建vm的时候才可以传入router配置参数。
// main.js文件
import router from './router';
new Vue({
router,
});
①路由组件单独存放于src/pages文件夹中,在src/router/index.js文件配置路由,引入所有路由组件。
②mode
属性设置路由工作模式hash或history。
③routes
属性设置匹配的路由地址path
与路由组件component
。路由组件可以进行懒加载,优化效率。
④name
属性给每个路由设置名字,跳转时可以直接用路由名,代替长串的路由地址。
⑤children
属性给每个路由配置下一级路由。多级路由path
属性不加/
。
⑥redirect
属性设置路由重定向,默认展示某个路由组件。
⑦meta
属性给每个路由设置元信息,方便路由的判断。
⑧scrollBehavior
设置路由跳转时,页面滚动条的位置。
// router/index.js文件
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import Page1 from 'src/pages/Page1';
import Page2 from 'src/pages/Page2';
export default new VueRouter({
mode: 'hash',
routes: [
{
name: 'page1',
path: '/page1',
component: Page1,
meta: { showFooter: true, },
},
{
name: 'page2',
path: '/page2',
component: Page2,
children: [
{
name: 'page3',
path: 'page3',
// 路由懒加载
component: () => import('src/pages/Page3'),
meta: { showFooter: true, },
},
],
},
{
path: '*',
redirect: '/page1',
}
],
scrollBehavior(to, from, savedPosition) {
return {x: 0, y: 0};
}
});
// .vue文件
<template>
<div>
<router-link active-class="active" :to="{name: 'page1'}">Page1</router-link>
<router-link replace to="/page2/page3">Page3</router-link>
</div>
<keep-alive :include="['Page1']">
<route-view><route-view>
</keep-alive>
</template>
①所有路由组件vm/vc都可访问$route
和$router
两个属性。$route
存放当前路由的配置信息和参数等。$router
是路由器,可设置路由的跳转等,所有路由组件的$router
都相同。
②$router.push()
和$router.replace()
方法可以跳转到指定路由,可以传入字符串路由地址,也可以传入跳转路由的配置对象。
③$router.back()
和$router.forward()
方法可以控制路由的前进后退,类似浏览器的前进后退。$router.go()
方法传入一个数字,表示前进(+)或后退(-)指定步数。
④路由生命周期函数activated()
与deactivated()
,类似mounted()
与beforeDestroy()
,在路由组件被展示与失去展示时调用,可以控制关闭和开启定时器等。
// .vue文件
<button @click="fun"></button>
export default {
method: {
fun() {
this.$router.push({
name: 'page1'
params: {},
query: {},
});
},
fun() {
this.$router.replace('/page2');
},
fun() {this.$router.back();},
fun() {this.$router.forward();},
fun() {this.$router.go();},
},
activated() {},
deactivated() {},
}
①$router.push()
和$router.replace()
方法执行后会返回一个Promise对象表示操作是否成功。当路由跳转到自己本身时,会报错。重写方法可以解决。
// 重写VueRouter原型上的push|replace方法,因为往同一个路由传参会报错
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
VueRouter.prototype.push = function (location) {
return originPush.call(this, location).catch(err => err);
};
VueRouter.prototype.replace = function (location) {
return originReplace.call(this, location).catch(err => err);
};
http://localhost:8080/api?arg1=1&arg2=2
中?
后面可以携带query参数。路径可以用模板字符串写。$route.query
属性保存跳转路由时传入的query参数。<router-link :to="{path: '/page1/page3', query: {arg1: 'arg1', arg2: [1,2,3],}}"></router-link>
<router-link :to="`/page1/page3?arg1=${arg1}&arg2=${arg2}`"></router-link>
<div>{{$route.query.arg1}}</div>
path
用:
预占位。当参数可传可不传时在后面添加?
,当传入的参数可能是空字符串时,需要在传入的变量后面加上|| undefined
。否则,跳转路径会发生错误。name
一起使用。$route.params
属性保存跳转路由时传入的params参数。<router-link :to="{name: 'page1', params: {arg1: '' || undefinded}}"></router-link>
<router-link :to="`/page1/page3/${arg1}`"></router-link>
<div>{{$route.pramas.arg1}}</div>
props
值为true
,params参数会作为路由组件的属性,可以用props
接受,但是不能接受query参数。props
值为对象,额外给路由组件传递参数,可以用props
接受。props
值为函数,可以传递params参数和query参数,函数的参数1是$route
,返回一个参数对象。(最常用写法)// router/index.js文件
export default new VueRouter({
routes: [
{
path: '/page1/:arg1?',
props($route) => ({arg1: $route.params.arg1, arg2: $route.query.arg2})
},
],
});
// .vue文件
<div>{{arg1}}{{arg2}}</div>
export default {
props: ['arg1', 'arg2'],
}
①路由守卫的功能就是在次路由切换时进行拦截并校验,决定是否切换到指定路由。
②beforeEach()
全局前置守卫在初始化和每次路由切换前执行回调函数。函数的参数1to
表示切换到的路由,参数2from
表示当前路由,参数3next
只有在执行后,路由切换才通行。
③afterEach()
全局后置守卫初始化和每次路由切换后执行回调函数。函数没有next
参数,其他同全局前置守卫。可以在路由切换后修改页面上的一些展示信息,用的很少。
④beforeEnter()
独享路由守卫在某一个路由的配置对象中进行配置。
// router/index.js文件
const router = new VueRouter({
routes: [
{
name: 'page1',
path: '/page1',
component: Page1,
// 独享路由守卫
beforeEnter: (to, from, next) => {},
}
]
});
// 全局前置守卫
router.beforeEach((to, from, next) => {
if(to.meta.data) next();
});
// 全局后置守卫
router.afterEach((to, from) => {
if (to.path || from.name) document.title='网页标题';
});
export default router;
⑤路由组件内的守卫beforeRouteEnter()
、beforeRouteUpdate()
和beforeRouteLeave()
方法类似生命周期函数,在通过路由规则进入、更新或离开组件前被调用。
// .vue文件
export default {
beforeRouteEnter(to, from, next) {next();},
beforeRouteUpdate(to, from, next) {next();},
beforeRouteLeave(to, from, next) {next();},
}
①hash工作模式的路由地址上有/#/
,其后面的内容(哈希值)不会通过HTTP发送给后端服务器,有些时候会因为第三方校验不合格而标记不合法。
②history工作模式的路由地址不会出现/#/
,整个路由地址被发送给服务器请求,需要配合后端配合。前端也可以通过nginx,connect-history-api-fallback第三方库等方法进行解决。