一般开发都是写静态路由,我们为什么要使用动态路由呢?因为动态路由对权限的划分是一个最有效的解决方法,下面我们就开始搭建一个动态路由的项目,使用技术是vite+ts+vue3+pinia+mock,mock主要用于模拟请求接口之后的处理,更接近实际项目
yarn create vite
创建一个项目之后启动,具体启动过程初始化命令里面都会有提示的这里就不详细讲解了,删除里面的HelloWord.vue文件,这样一个空白项目就有了,下面我们先进行安装需要的插件
需要安装vue-router、pinia、axios和mock,我这边是使用的yarn安装的,如果使用npm安装也是可以的
//安装vue-router和axios、pinia
yarn add vue-router axios pinia
//安装mockjs和vite-plugin-mock。mock主要用途仅为模拟后端数据接口,所以安装为开发依赖,若打包为生产环境则会失效。
yarn add mockjs vite-plugin-mock
安装好插件之后,开始创建文件夹以及需要的文件
src下面新建router/index.ts:import { RouteRecordRaw, createRouter, createWebHistory,createWebHashHistory } from 'vue-router'
// 静态路由表
const routes: Array<RouteRecordRaw> = [
{
// 路由重定向配置
path: '/',
redirect: '/Home'
}, {
path: '/Home',
component: () => import('../views/Home.vue')
}
]
// 路由对象
const router = createRouter({
history: createWebHashHistory(),//hash路由
routes
})
export default router
app.vue文件,改成如下代码:<template>
<router-view></router-view>
</template>
<script setup lang="ts"></script>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router' //引入router
const app=createApp(App)
app.use(router) //使用router
app.mount('#app')
这样就可以看到home页面了

/src/mock/index.ts
// /src/mock/index.ts
import { MockMethod } from "vite-plugin-mock"
const mock: Array<MockMethod> = [
{
url: '/api/test',
method: 'get',
response: () => {
return {
status: 200,
message: 'success',
data: '返回的数据'
}
}
}
]
export default mock
vite.config.ts
要想使用mock,我们还需要在vite.config.ts文件下对mock进行配置,让vite启动的同时启动mock服务。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteMockServe } from 'vite-plugin-mock'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
// mock服务
viteMockServe({
supportTs: false,
logger: false,
mockPath: "./src/mock/",
}),
]
})
axios
/src/utils/request.ts:此文件为axios配置文件,它将创建一个axios全局单例,由于本项目仅做最简单的演示,所以仅配置baseUrl,实际使用时可根据实际情况添加拦截器等功能。
import axios from 'axios'
// axios对象
const service = axios.create({
// axios请求基础URL
baseURL: "http://127.0.0.1:5175", //此处根据自己启动的端口来
timeout: 5000
})
export default service
/src/apis/index.ts:此文件为接口文件,接口统一放到此文件中。
import req from '../utils/request'
/**
* 测试接口
*/
// 测试用Hello World
export const TestApi = () => req({ url: '/api/test', method: 'get' })
home.vue代码修改如下
<template>
<h1>Home</h1>
</template>
<script lang="ts" setup>
import { TestApi } from '../apis'
TestApi().then(res => console.log(res)).catch(err => console.log(err))
</script>
在这里就可以看到网络里面有接口请求成功了。
首先我们先在刚刚创建的mock接口文件/src/mock/index.ts中添加一个返回路由信息的路由接口,如下所示
import { MockMethod } from "vite-plugin-mock"
const mock: Array<MockMethod> = [
{
url: '/api/test',
method: 'get',
response: () => {
return {
status: 200,
message: 'success',
data: 'Hello World'
}
}
},
{
url: '/api/getRoutes',
method: 'get',
response: () => {
const routes = [
{
path: '/Page1',
name: 'Page1',
component: 'Page1/index'
},
{
path: '/Page2',
name: 'Page2',
component: 'Page2/index'
}
]
return {
status: 200,
message: 'success',
data: routes
}
}
}
]
export default mock
/src/api/index.ts
import req from '../utils/request'
export const TestApi = () => req({ url: '/api/test', method: 'get' })
export const GetRoutes = () => req({ url: '/api/getRoutes', method: 'get' })
pinia和vuex都是vue的全局状态管理工具,在前面的步骤已经安装了这个插件,我们就直接使用。
/src/store/index.ts代码如下
// /src/store/index.ts
import { defineStore } from 'pinia'
import { RouteRecordRaw } from 'vue-router'
//引入所有views下.vue文件
let modules = import.meta.glob("../views/**")
// pinia状态管理器
export const useStore = defineStore('myStore', {
state: () => {
return {
// 路由表
routes: [] as Array<RouteRecordRaw>
}
},
getters: {},
actions: {
// 添加动态路由,并同步到状态管理器中,这个地方逻辑是写的最简单的方式,大家可以根据自己的业务需求来改写,本质就是使用addRoute来实现
addRoutes(data: Array<any>, router: any) {
data.forEach(m => {
this.routes.push({
path: m.path,
name: m.name,
// 错误示例:components:()=>import(`../views/Pages/${m.component}`)
// 正确示例如下:
component: modules[`../views/${m.component}.vue`],
})
})
console.log('this.routes',this.routes)
this.routes.forEach(m => router.addRoute(m))
},
}
})
main.ts代码如下
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App)
// 启用路由
app.use(router)
// 启用pinia
app.use(pinia)
app.mount('#app')
/src/views/home.vue代码如下
<template>
<h1>Home</h1>
<div style="display: flex; gap: 20px">
<button v-for="item in routes" @click="handleClick(item.path)">
{{ item.name }}
</button>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "../store";
import { TestApi, GetRoutes } from "../apis";
import { useRouter } from "vue-router";
import { computed } from "@vue/reactivity";
import { onMounted } from "vue";
const router = useRouter();
const store = useStore();
// 动态路由表
const routes = computed(() => store.routes);
// 路由按钮点击事件
const handleClick = (path: string) => {
router.push({ path });
};
onMounted(() => {
if (store.routes.length < 1) {
// 获取动态路由
GetRoutes().then((res) => {
store.addRoutes(res.data.data, router);
});
}
// 测试接口
TestApi()
.then((res) => console.log(res.data))
.catch((err) => console.log(err));
});
</script>
这样就实现了动态路由的跳转,但是这样直接刷新page1页面就会导致页面空白,所以我们是在路由拦截里面进行了处理
import { RouteRecordRaw, createRouter, createWebHashHistory } from 'vue-router'
import { useStore } from "../store";
import { GetRoutes } from '../apis'
// 静态路由表
const routes: Array<RouteRecordRaw> = [
{
// 路由重定向配置
path: '/',
redirect: '/Home'
}, {
path: '/Home',
component: () => import('../views/Home.vue')
}, {
// 404页面配置
path: '/:catchAll(.*)',
component: () => import('../views/404.vue')
}
]
// 路由对象
const router = createRouter({
history: createWebHashHistory(),
routes
})
// 路由守卫
router.beforeEach((to, from, next) => {
if (to.path !== '/Home' && to.path !== '/') {
const store = useStore()
if (store.routes.length < 1) {
GetRoutes().then(res => {
store.addRoutes(res.data.data, router)
next({ path: to.path, replace: true })
}).catch(_ => {
next()
})
} else {
next()
}
} else {
next()
}
})
export default router
这样动态路由就搭建成功了。


Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。
有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.
我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO
首先,我使用的是rails3.1.3和来自master的carrierwavegithub仓库的分支。我使用after_init钩子(Hook)来确定基于属性的字段页面模型实例并为这些字段定义属性访问器将值存储在序列化哈希中(希望它清楚我是什么谈论)。这是我正在做的事情的精简版:classPage省略mount_uploader命令让我可以访问我想要的属性。但是当我安装uploader时出现错误消息说“nil类的未定义新方法”我在源代码中读到有方法read_uploader和扩展模块中的write_uploader。我如何必须覆盖这些来制作mount_uploader命令使用我的“虚拟
我正在尝试动态构建一个多维数组。我想要的基本上是这样的(为简单起见写出来):b=0test=[[]]test[b]这给了我错误:NoMethodError:undefinedmethod`test=[[],[],[]]而且它工作正常,但在我的实际使用中,我不会事先知道需要多少个数组。有一个更好的方法吗?谢谢 最佳答案 不需要像您正在使用的索引变量。只需将每个数组附加到您的test数组:irb>test=[]=>[]irb>test[["a","b","c"]]irb>test[["a","b","c"],["d","e","f"]]