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@

然后我们在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;

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;

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

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

`${item.component}`

这样就会直接报错
你的字符串前面必须要有一点内容
比如我这里就有
@/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')

src下App.vue参考代码如下

<template>
  <div id="app">
   <router-view/>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
 setup(){
    return {
    }
 }
});
</script>

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>

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

<template>
  <div>
    text
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
 setup(){
    return {
    }
 }
});
</script>

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

<template>
  <div>
     <button @click = "onCountData">添加路由</button>
     <button @click = "enterprise">跳转enterprise</button>
     <button @click = "textputt">跳转text</button>
     <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>

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

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

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

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值