Vue Router的学习与使用

安装

方式一:
直接下载 / 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

重要配置

  1. 在自己的工程的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>

知识四:导航守卫(前面代码中涉及具体使用)

使用场景
个人理解是当路由发生变化时需要使用导航守卫的方法(简单粗暴~~)

根据作用范围不同可分为:

  • 全局的(未使用过)
  • 单个路由独享的(未使用过)
  • 组件级的(使用过)
组件内的守卫
  1. beforeRouteEnter(to, from, next)
    介绍:
    (1)在渲染该组件的对应路由被 confirm 前调用
    (2)不!能!获取组件实例 this因为当守卫执行前,组件实例还没被创建
    (3)使用该守卫时需要注意它的放置位置,当你有父组件和子组件时,且在父组件中点击链接打算跳转到子组件中,此时的beforeRouteEnter方法应该放在子组件中。
    (4)使用next()可实现真正跳转到该组件前需要做的事情
  2. beforeRouteUpdate
    介绍
    (1)在当前路由改变,但是该组件被复用时调用。举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    (2)可以访问组件实例 this
    (3)与watch作用类似,但是beforeRouteUpdate可以在next()里执行一些操作
  3. 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);
                }
            }
        },
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue使用Vue Router可以实现单页面应用的路由功能。首先,我们需要在安装了vue-router后,在src目录下生成一个router文件夹,然后在该文件夹下创建一个index.js文件来配置路由相关的信息。第一步是导入路由对象并调用`Vue.use(VueRouter)`来安装vue-router,我们需要引入路由对象,可以使用`import Router from 'vue-router'`的方式来引入。在main.js文件中,我们需要引入router,并在Vue实例中配置router选项,例如:`new Vue({ ..., router })`。此外,如果遇到相同路由出现问题,可以参考相同路由的解决办法。Vue RouterVue.js官方的路由插件,与Vue.js深度集成,适用于构建单页面富应用。你可以在vue-router的官网上找到更多关于vue-router的信息,官网地址是:https://router.vuejs.org/zh/。在Vue Router中,路由用于设定访问路径,并将路径与组件进行映射,页面路径的改变会导致组件的切换。你可以通过运行`npm install vue-router --save`来安装vue-router。希望对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vue系列 —— vue-route详细使用方法](https://blog.csdn.net/weixin_41319237/article/details/120514401)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [使用vue 项目 使用 vue-router 详细步骤](https://blog.csdn.net/weixin_56297713/article/details/122668888)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值