• vue3+Composition 组合式API+TypeScript+vuex+vue-router根据返回数据动态添加控制路由


    首先 你需要有一个vue3的项目
    如果您还在用vue2 环境 可以参考我的文章
    将vue2项目升级成vue3项目

    如果您不太了解vue继承TypeScript 可以参考我的文章
    vue3项目集成TypeScript

    如果你不熟悉vue+TypeScript中使用vuex 可以参考我的文章
    Vue3 Composition 组合式API+TypeScript使用Vuex

    然后我们就直接拿出三者结合好的一个vue项目作为开始

    然后我们引入vue路由 注意一下@版本号

    npm install vue-router@
    
    • 1

    然后我们在src目录下创建一个router.ts
    router.ts参考代码 如下

    import { createRouter,createWebHistory } from "vue-router";
    const router = createRouter({
        history:createWebHistory(),
        routes:[
            {
                path: "/",
                component: ()=>import(`@/components/HelloWorld.vue`),
                meta: {
                    title: "首页",
                    icon: "dashboard"
                }
            }
        ]
    })
    
    export default router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    src下store.ts参考代码如下

    import { ComponentCustomProperties } from "vue";
    import { createStore,Store } from "vuex";
    import router from "./router";
    
    declare module "@vue/runtime-core" {
        interface State {
            aggregate: Array<any>
        }
        interface ComponentCustomProperties {
            $store: Store<State>;
        }
    }
    
    const store = createStore({
        state() {
            return {
                aggregate: []
            }
        },
        mutations: {
        },
        actions: {
            filterAsyncRouter (state:any, routerData) {
                return new Promise(resolve=> {
                    state.aggregate = [];
                    routerData.map((item:any)=> {
                        state.aggregate.push(item)
                        router.addRoute({
                            path: item.path,
                            component: ()=>import(`@/components/${item.component}`),
                            meta: {
                                title: item.meta.title,
                                icon: item.meta.icon
                            }
                        })
                    })
                    resolve(routerData)
                })
            }
        }
    })
    
    export default store;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    filterAsyncRouter 方法接受需要添加的路由 通过 addRoute 动态添加路由
    添加的路由会被存在aggregate 里

    这里需要注意一个点 component: ()=>import(@/components/${item.component}), 中 字符串必须是有一定内容的 不能直接

    `${item.component}`
    
    • 1

    这样就会直接报错
    你的字符串前面必须要有一点内容
    比如我这里就有
    @/components/

    src下 main.ts参考代码如下

    import { createApp } from 'vue'
    import App from './App.vue'
    import store from './store'
    import router from './router'
    
    createApp(App).use(router).use(store).mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    src下App.vue参考代码如下

    <template>
      <div id="app">
       <router-view/>
      div>
    template>
    
    <script lang="ts">
    import { defineComponent } from 'vue';
    export default defineComponent({
     setup(){
        return {
        }
     }
    });
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    App.vue中就是挂载路由的区域

    我们找到src下的目录components
    如下图 创建
    在这里插入图片描述
    components下创建enterprise.vue
    enterprise.vue参考代码如下

    <template>
      <div>
        enterprise
      div>
    template>
    
    <script lang="ts">
    import { defineComponent } from 'vue';
    export default defineComponent({
     setup(){
        return {
        }
     }
    });
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    创建mint文件夹目录
    mint下面创建一个text.vue
    text.vue参考代码如下

    <template>
      <div>
        text
      div>
    template>
    
    <script lang="ts">
    import { defineComponent } from 'vue';
    export default defineComponent({
     setup(){
        return {
        }
     }
    });
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    components下创建HelloWorld.vue
    HelloWorld.vue参考代码如下

    <template>
      <div>
         <button @click = "onCountData">添加路由button>
         <button @click = "enterprise">跳转enterprisebutton>
         <button @click = "textputt">跳转textbutton>
         <button @click = "reloadsty">清空路由button>
      div>
    template>
    
    <script lang="ts">
    import {useStore} from "vuex";
    import { defineComponent } from 'vue';
    import { useRouter } from 'vue-router'
    export default defineComponent({
     setup(){
        const router = useRouter()
        const {dispatch,commit} = useStore();
        let data = [
          {
            path: "/enterprise",
            component: "enterprise.vue",
            meta: {
                title: "部门详情",
                icon: "dashboard"
            }
          },{
            path: "/text",
            component: "mint/text.vue",
            meta: {
                title: "测试路由",
                icon: "dashboard"
            }
          }
        ]
        const onCountData = function():void{
          dispatch('filterAsyncRouter', data).then((routerList) => {
              console.log(routerList);
          })
        }
        const enterprise = function():void{
          router.push('/enterprise')
        }
        const textputt = function():void{
          router.push('/text')
        }
        const reloadsty = function():void{
          commit('tuiminaggregate');
          location.reload();
        }
        return {
          onCountData,
          enterprise,
          textputt,
          reloadsty
        }
     }
    });
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    HelloWorld.vue主要就是添加路由和清除路由的地方 他也是第一个访问的路由

    然后我们把项目运行起来
    在这里插入图片描述

    然后我们直接点击 跳转enterprise
    在这里插入图片描述
    会发现什么都没有 因为我们暂时还没有这个路由
    我们现在点击跳转text也是一样的

    然后我们点击添加路由onCountData就会调用vuex中的 filterAsyncRouter传递的就是上面 通过 let定义的data 其中就是两条路由数据
    然后filterAsyncRouter就会处理数据 然后用addRoute将他们添加进我们的路由

    点击完后 我们在点击跳转enterprise
    在这里插入图片描述
    这时我们就有这个路由了

    然后我们点击跳转text
    在这里插入图片描述
    也没有任何问题
    然后我们点击
    清空路由
    这里因为vue路由没有定义明确的清空方法
    所以我直接调用了location.reload(); 强行重置了路由

    点击完清空路由之后
    我们的路由就又没拉
    在这里插入图片描述

  • 相关阅读:
    为什么使用前端框架
    Java面向对象编程
    Kotlin中类型转换
    科目三:超车
    java基于springboot+vue的宠物商店领养挂失管理系统 element 前后端分离
    JAVA+Node/JavaScript 前后端通讯 RSA 加解密实现
    c#设计模式-结构型模式 之适配器模式
    负载均衡架构设计技巧
    Module not found: Error: Can‘t resolve ‘core-js/modules/es.promise.js‘
    C语言char与short取反以及符号判断问题
  • 原文地址:https://blog.csdn.net/weixin_45966674/article/details/126824527