安装
方式一:
直接下载 / CDN
https://unpkg.com/vue-router/dist/vue-router.js
Unpkg.com 提供了基于 NPM 的 CDN 链接。上面的链接会一直指向在 NPM 发布的最新版本。你也可以像 https://unpkg.com/vue-router@2.0.0/dist/vue-router.js 这样指定 版本号 或者 Tag。
在 Vue 后面加载 vue-router,它会自动安装的:
<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>
方式二:
使用npm安装
npm install vue-router
重要配置
- 在自己的工程的src路径下新建一个router文件夹,接着在该文件夹下新建一个index.js
index.js
import Vue from "vue";
//1. 导入vue-router包
import VueRouter from "vue-router";
import BusinessGrouping from "../components/umeapi/BusinessGrouping"
import ProjectsOfBusinessGrouping from "../components/umeapi/ProjectsOfBusinessGrouping"
import DetailsOfAPI from "../components/umeapi/DetailsOfAPI"
//2. 手动安装VueRouter
Vue.use(VueRouter);
const routes = [
{
path: '/',
redirect: '/groups',
component: BusinessGrouping
},
{
path: "/groups",
component: BusinessGrouping
},
{
path: "/groups/:groupName",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: ProjectsOfBusinessGrouping,
// children代表嵌套路由
children: [
{
path: 'projects/:projectName',
component: DetailsOfAPI
},
]
}
];
const router = new VueRouter({
//选择路由的模式,默认是hash模式
mode: 'history',
routes
});
export default router;
知识一:路由使用标签
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->'
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<!-- <router-view></router-view>-->
例子:<router-link to="/foo">Go to Foo</router-link>
知识二:动态路由匹配
使用场景举例
我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染
注:在路径配置的index.js文件中,所需使用的组件要提前导入进来(import)
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
知识三:嵌套路由
使用场景举例
父组件中包含子组件,在子组件中又包含一个子子组件。。。
以下是自己项目中涉及路由嵌套的部分,结合前面的index.js文件,即可理解路由嵌套的使用场景和使用规则;核心是在配置中增加children属性
父组件:BusinessGrouping.vue
<template>
<div>
<a-breadcrumb style="text-align: left" :span="2">
<a-breadcrumb-item>分组页</a-breadcrumb-item>
</a-breadcrumb>
<div v-for="(item, i) in groupsList" v-bind:key="i">
<a-col :span="4" style="padding: 5px;">
<a-card :bordered="true" :headStyle="{color:'#0785fd'}">
<router-link :to="'/groups/'+item">{{item}}</router-link>
<template class="ant-card-actions" slot="actions">
<a-icon type="setting" />
<a-icon type="edit" />
<a-icon type="ellipsis" />
</template>
</a-card>
</a-col>
</div>
<router-view v-if="flag"></router-view>
</div>
</template>
<script>
export default {
name: "BusinessGrouping",
data(){
return {
groupsList:[],
groupName: '',
flag: false
}
},
created(){
this.getAllGroupName()
},
watch: {
// 如果路由有变化,会再次执行该方法
'$route' (to, from){
console.log("groups from, to", from, to)
if(to.path !== "/" && to.path !== "/groups"){
console.log("to.path="+to.path)
this.showRouterView();
}
}
},
beforeRouteEnter (to, from, next) {
console.log("groups beforeRouteEnter=>"+to.params.groupName)
next(
vm => vm.getAllGroupName()
)
},
methods: {
getAllGroupName(){
var _this = this;
_this.flag = false
_this.axios
.get('/api/umeapi/getGroupNames',{
})
.then(function (response) {
console.log("航旅纵横App业务分组的名称:"+response.data)
_this.groupsList = response.data;
})
},
showRouterView(){
console.log("分组页的showRouterView方法")
this.flag = true
}
}
}
</script>
<style scoped>
</style>
子组件:ProjectsOfBusinessGrouping.vue
<template>
<a-drawer title="" :placement="placement" :closable="false" @close="onClose" :visible="true" width="100%">
<a-breadcrumb>
<a-breadcrumb-item><a href="/">分组页</a></a-breadcrumb-item>
<a-breadcrumb-item>{{$route.params.groupName}}</a-breadcrumb-item>
</a-breadcrumb>
<div v-for="(item, i) in projectsList" v-bind:key="i">
<a-col :span="4" style="padding: 5px;">
<a-card :bordered="true" :headStyle="{color:'#0785fd'}">
<router-link :to="'projects/'+item" append>{{item}}</router-link>
</a-card>
</a-col>
</div>
<router-view></router-view>
</a-drawer>
</template>
<script>
export default {
name: "ProjectsOfBusinessGrouping",
// components: {DetailsOfAPI},
data(){
return {
projectsList: [],
visible: false,
placement: 'right',
groupName: ''
}
},
watch: {
// 如果路由有变化,会再次执行该方法
'$route' (to, from){
console.log("projects from, to", from, to)
if(from.params.projectName && !Object.prototype.hasOwnProperty.call(to.params, 'projectName')){
console.log("从详情页回来点击面包屑回来的")
this.getAllProjectsOfGroup(to.params.groupName);
}
}
},
beforeRouteEnter (to, from, next) {
console.log("project beforeRouteEnter=>"+to.params.groupName, from, to)
if(from.path === "/"){
next("/groups")
}else {
next(
vm => vm.getAllProjectsOfGroup(to.params.groupName)
)
}
},
methods: {
onClose() {
this.visible = false;
},
handleEachProject(projectName){
console.log("214:"+projectName)
this.$store.commit('editProjectName', projectName)
this.$refs.apiDetailObj.showDrawer();
},
getAllProjectsOfGroup(group){
this.$store.commit('editGroupName', group);
var _this = this;
_this.axios
.get('/api/umeapi/getProjectsByGroupName', {
params: {group_name: group}
})
.then(function (response) {
console.log("按不同业务分组得到的所有项目:"+response.data)
_this.projectsList = response.data
})
},
}
}
</script>
<style scoped>
</style>
子子组件:DetailsOfAPI.vue
<template>
<a-drawer
:placement="placement"
:closable="false"
@close="onClose"
:visible="visible"
width="100%"
>
<a-breadcrumb :routes="routes" style="font-size: 5px">
<template slot="itemRender" slot-scope="{route, params, routes, paths}">
<span v-if="routes.indexOf(route) === routes.length - 1">{{route.breadcrumbName}}</span>
<router-link v-else :to="`/${paths.join('/')}`">{{route.breadcrumbName}}</router-link>
</template>
</a-breadcrumb>
<a-row :gutter="16">
<a-col :md="6" :sm="24">
<a-pi-tree-left/>
</a-col>
<a-col :md="24-6" :sm="24">
<api-details-right/>
</a-col>
</a-row>
</a-drawer>
</template>
<script>
import APiTreeLeft from "./ApiTreeLeft.vue"
import ApiDetailsRight from "./ApiDetailsRight";
export default {
name: "DetailsOfAPI",
components:{
ApiDetailsRight,
APiTreeLeft,
},
data(){
return{
visible: false,
placement: 'right',
groupHref:"",
projectHref:"",
routes: [],
basePath: ``,
}
},
beforeRouteEnter (to, from, next) {
console.log("api beforeRouteEnter=>"+to.params.projectName,from, to)
if(from.path === "/"){
next("/groups")
}else {
next(
vm => vm.showDrawer(to.params.projectName)
)
}
},
methods:{
showDrawer(project){
this.$store.commit('editProjectName', project)
var home = '/'
this.groupHref = '/groups/'+this.$route.params.groupName
this.projectHref = '/groups/'+this.$route.params.groupName+'/projects/'+this.$route.params.projectName
console.log("groupHref="+this.groupHref, "projectHref="+this.projectHref)
this.routes = [{
path: home,
breadcrumbName: '分组页'
}, {
path: this.groupHref,
breadcrumbName: this.$route.params.groupName
}, {
path: this.projectHref,
breadcrumbName: this.$route.params.projectName
},
{
path: "",
breadcrumbName: '详情页'
}
],
this.visible = true;
},
onClose() {
this.visible = false;
},
}
}
</script>
<style scoped>
</style>
知识四:导航守卫(前面代码中涉及具体使用)
使用场景
个人理解是当路由发生变化时需要使用导航守卫的方法(简单粗暴~~)
根据作用范围不同可分为:
- 全局的(未使用过)
- 单个路由独享的(未使用过)
- 组件级的(使用过)
组件内的守卫
- beforeRouteEnter(to, from, next)
介绍:
(1)在渲染该组件的对应路由被 confirm 前调用
(2)不!能!获取组件实例this
因为当守卫执行前,组件实例还没被创建
(3)使用该守卫时需要注意它的放置位置,当你有父组件和子组件时,且在父组件中点击链接打算跳转到子组件中,此时的beforeRouteEnter方法应该放在子组件中。
(4)使用next()可实现真正跳转到该组件前需要做的事情 - beforeRouteUpdate
介绍
(1)在当前路由改变,但是该组件被复用时调用。举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
(2)可以访问组件实例this
(3)与watch作用类似,但是beforeRouteUpdate可以在next()里执行一些操作 - beforeRouteLeave
介绍
(1)导航离开该组件的对应路由时调用,与beforeRouteEnter作用相反
(2)可以访问组件实例this
知识五:watch的使用
使用场景
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象
注:当路由参数变化情况如从/use/123导航到/user/456时,原来的组件实例会被复用(即渲染了同一个组件)。这种情况下,意味着组件的生命周期钩子不会被再次调用
使用介绍
方法一:
export default {
data () {
return {
loading: false,
post: null,
error: null
}
},
created () {
// 组件创建完后获取数据,
// 此时 data 已经被 observed 了
this.fetchData()
},
watch: {
// 如果路由有变化,会再次执行该方法
'$route': 'fetchData'
},
methods: {
fetchData () {
this.error = this.post = null
this.loading = true
}
}
}
方法二:
watch: {
// 如果路由有变化,会再次执行该方法
'$route' (to, from){
console.log("projects from, to", from, to)
if(from.params.projectName && !Object.prototype.hasOwnProperty.call(to.params, 'projectName')){
console.log("从详情页回来点击面包屑回来的")
this.getAllProjectsOfGroup(to.params.groupName);
}
}
},