vue3 + vite + ts + setup , 第十九练 vue3 中使用vue-router(三),动态路由

2023-05-16

动态路由

我们在做页面菜单权限的时候回用到动态路由来处理权限,使用动态路由都是后台会返回一个路由表前端通过调接口拿到后处理(后端处理路由)

动态路由主要通过两个函数实现。router.addRoute() 和 router.removeRoute()。它们注册一个新的路由,也就是说,如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。

添加路由

router.addRoute({ path: '/about', component: About })

删除路由

有几个不同的方法来删除现有的路由:

  • 通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:
    router.addRoute({ path: '/about', name: 'about', component: About })
    // 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
    router.addRoute({ path: '/other', name: 'about', component: Other })
    
  • 通过调用 router.addRoute() 返回的回调:
    const removeRoute = router.addRoute(routeRecord)
    removeRoute() // 删除路由如果存在的话
    
    当路由没有名称时,这很有用。
  • 通过使用 router.removeRoute() 按名称删除路由:
    router.addRoute({ path: '/about', name: 'about', component: About })
    // 删除路由
    router.removeRoute('about')
    
    需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。

当路由被删除时,所有的别名和子路由也会被同时删除

添加嵌套路由

要将嵌套路由添加到现有的路由中,可以将路由的 name 作为第一个参数传递给 router.addRoute(),这将有效地添加路由,就像通过 children 添加的一样

router.addRoute({ name: 'admin', path: '/admin', component: Admin })
router.addRoute('admin', { path: 'settings', component: AdminSettings })

这等效于:

router.addRoute({
  name: 'admin',
  path: '/admin',
  component: Admin,
  children: [{ path: 'settings', component: AdminSettings }],
})

查看现有路由

Vue Router 提供了两个功能来查看现有的路由:

  • router.hasRoute():检查路由是否存在。
  • router.getRoutes():获取一个包含所有路由记录的数组。

实例:

需要注意vite中无法使用别名@ ,必须使用相对路径  ../../

 router.js

//引入路由对象
import {
  createRouter,
  createWebHistory,
  createWebHashHistory,
  createMemoryHistory,
  RouteRecordRaw,
} from "vue-router";
import { createVNode, render } from 'vue'
import loadingBar from "../components/loadingBar.vue"

const Loading = createVNode(loadingBar)
render(Loading, document.body)
//vue2 mode history vue3 createWebHistory
//vue2 mode  hash  vue3  createWebHashHistory
//vue2 mode abstact vue3  createMemoryHistory  ssr服务端渲染

//路由数组的类型 RouteRecordRaw
// 定义一些路由
// 每个路由都需要映射到一个组件。



const routes: Array<RouteRecordRaw> = [
  {
    path: "/login",
    name: "Login",
    component: () => import('../components/login.vue'),
    meta: {
      title: "登录",
      transition: "animate__fadeInUp"
    }
  },
  {
    //动态路由参数
    path: "/",
    name: "Reg",
    component: () => import('../components/reg.vue'),
    alias: ['/root', '/roots', '/home'],
    redirect: () => {
      return {
        path: "/tab1"
      }
    },
    children: [
      {
        path: "/tab1",
        name: "tab1",
        component: () => import('../components/tab1.vue'),
        meta: {
          title: "测试tab1",
          transition: "animate__fadeInUp"
        }
      },
      {
        path: "tab2",
        name: "/tab2",
        components: {
          default: () => import('../components/tab2.vue'),
          two: () => import('../components/login.vue')
        },
        meta: {
          title: "测试tab222",
          transition: "animate__fadeInUp"

        }
      }
    ]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  // scrollBehavior: (to, from, savePosition) => {
  //   console.log(to, '==============>', savePosition);
  //   return new Promise((r) => {
  //     setTimeout(() => {
  //       r({
  //         top: 100
  //       })
  //     }, 2000);
  //   })
  // },

  scrollBehavior: (to, from, savePosition) => {
    console.log("滚动距离", savePosition)
    if (savePosition) {
      return savePosition
    } else {
      return {
        top: 300
      }
    }
  },
  routes: routes,
});

router.beforeEach((to, form, next) => {
  console.log('beforeEach', Loading);
  Loading.component?.exposed?.startLoading()
  let token = localStorage.getItem('token')
  if (token && to.name != 'Login') {
    next()
  } else {
    to.name == 'Login' ? next() : next('/login')
  }

})

router.afterEach((to, from) => {
  Loading.component?.exposed?.endLoading()
})

//导出router
export default router;

login.vue组件,登录后根据账号动态添加路由

<template>
  <div class="login">
    我是登录
    <p>账号<input type="text" v-model="route.params.name" /></p>
    <p>密码<input type="text" v-model="route.params.pwd" /></p>
    <p><button @click="loginIn">登录</button></p>
  </div>


</template>

<script setup lang="ts">
import { createVNode, h, nextTick, render } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute()
const router = useRouter()


let routeA = [
  {
    name: "AAA",
    path: "/aaa",
    component: () => import('../components/AAA.vue'),
    meta: {
      title: "AAAAAA",
      transition: "animate__fadeInUp"
    }
  },
  {
    name: "BBB",
    path: "/bbb",
    component: () => import('../components/BBB.vue'),
    meta: {
      title: "BBBBB",
      transition: "animate__fadeInUp"
    }
  },
  {
    name: "CCC",
    path: "/ccc",
    component: () => import('../components/CCC.vue'),
    meta: {
      title: "CCCCCCC",
      transition: "animate__fadeInUp"
    }
  },

]

let routeB = [
  {
    name: "AAA",
    path: "/aaa",
    component: () => import('../components/AAA.vue'),
    meta: {
      title: "AAAAAAA",
      transition: "animate__fadeInUp"
    }
  },
  {
    name: "BBB",
    path: "/bbb",
    component: () => import('../components/BBB.vue'),
    meta: {
      title: "CCCCCCCC",
      transition: "animate__fadeInUp"
    }
  }

]
// 登录
const loginIn = () => {
  let odata = {
    name: route.params.name,
    pwd: route.params.pwd
  }
  console.log("登录", routeA, odata)
  localStorage.setItem('token', JSON.stringify(odata))
  routeA.forEach(item => {
    router.removeRoute(item.name)
  })
  if (odata.name == 'admin') {
    routeA.forEach(item => {
      router.addRoute(item)
    })
  } else {
    routeB.forEach(item => {
      router.addRoute(item)
    })
  }
  console.log("路由传参", router)

  router.push("/")
}

</script>

<style scoped>
.login {
  width: 600px;
  height: 600px;
  background: #eee;
}

.set-vnode {
  width: 200px;
  height: 300px;
  border: 1px solid;
}
</style>

实战项目中我们会把路由列表 维护后端,通过不同的用户去获取不同的路由权限列表,动态添加

vue3.x+ts+vite+vue-router@4.x demo下载

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3 + vite + ts + setup , 第十九练 vue3 中使用vue-router(三),动态路由 的相关文章

随机推荐