vue3+TS+vueX的记录

要求:在页面中使用输入框输入回车后将数据保存到vuex中的数组list中

list为一个数组 内部三个属性为 id  value  status

id为时间戳

value为string 输入的字符串

status为定义的三种状态 待办  在办 完成

 1、创建仓库  将 仓库拆分

import { createStore } from 'vuex'
import state from './state'
import actions from './actions'
import mutations from './mutations'
export default createStore({
  state,
  mutations,
  actions
})

使用action调用mutation中的方法修改state的list

2、定义数据类型

全局定义SET_TODO

export const SET_TODO:string='SET_TODO'

state的总体类型 后续有什么字段就添加什么类型
interface IState{
  list:ITodo[]
}
添加的对象类型
interface ITodo {
  id:number,
  content:string,
  status:TODO_STATUS
}
枚举类型
enum TODO_STATUS{
  WILLDO='willdo',
  DOING='doing',
  FINISHEN='finshing'

}
export {
  ITodo,
  IState,
  TODO_STATUS

}

3、调用

 定义数据的增删改查所有方法合集

举例  调用setTodo方法  将输入框的value传值写入todo数据中

调用SET_TODO 方法

import { SET_TODO } from "@/store/actionsTypes";
import { ITodo, TODO_STATUS } from "@/typings";
import { useStore } from "vuex";


interface IUseTodo{
    setTodo:(value:string)=>void;
    setTodoList:()=>void;
    removeTodo:()=>void;
    setStatus:()=>void;
    setDoing:()=>void;
}
function useTodo() :IUseTodo{
const store=useStore()
  function setTodo(value:string):void {
      const todo:ITodo={
        id:new Date().getTime()
        ,content:value,
        status:TODO_STATUS.WILLDO
      }
     store.dispatch(SET_TODO, todo)
  }
  function setTodoList() {

  }
  function removeTodo() {

  }
  function setStatus() {

  }
  function setDoing() {

  }
  return {
    setTodo,
    setTodoList,
    removeTodo,
    setStatus,
    setDoing,
  };
}
export  {useTodo};

 获取到需要添加上的数据调用mutation方法

import { ITodo, IState } from "@/typings";
import { SET_TODO } from "./actionsTypes";
import { Commit } from "vuex";

interface ICtx {
  commit: Commit;
  state: IState;
}
export default {
   action 去调用mutation的方法
   这定义了stetodo的字符串 等同于 settodo(){}
   action 有两个传入值  ctx 也就是{commit  state}  还有传入值 ITodo 定义过了id之类的相关值

  [SET_TODO]({ commit, state }: ICtx, todo: ITodo): void {
    调用mutation内的方法
    commit(SET_TODO, todo);
  },
};

 将类型为ITodo数据添加到state中的list最后一位

import { IState, ITodo } from "@/typings";

export default{
  // 使用【SET_TODO】是一样的  因为定义的是字符串的SET_TODO
  SET_TODO(state:IState,todo:ITodo):void{
      state.list.unshift(todo)
      console.log(state.list);
      
  }
}

调用  输入框输入 点击回车后调用hooks中的setTodo方法

setTodo是hooks中结构出来的

const getValue=(e:KeyboardEvent)=>{
  if (e.keyCode==13&&inputValue.value.length>0) {
    setTodo(inputValue.value)
    inputValue.value=''
  }
}

<think> 我们正在处理一个关于Vue3和TypeScript动态生成路由的问题。根据引用内容,我们可以看到一些相关的代码片段和概念。动态路由通常指的是根据用户权限或从服务器获取的数据来生成路由。下面我们将结合引用内容,整理出动态生成路由的实现方案。 关键点: 1. 引用[1]中提到了静态路由和动态路由的概念,并展示了如何创建路由实例。 2. 引用[2]展示了基本的路由配置,包括引入组件和创建路由。 3. 引用[3]提到了TypeScript配置,确保类型支持。 4. 引用[4]展示了在Vue应用中使用路由和状态管理,并有一个刷新路由的示例(通过`ReloadData`函数)。 动态路由的实现通常包括以下步骤: a. 定义静态路由(如登录页、404页等) b. 定义动态路由(需要根据条件动态添加的路由) c. 在路由守卫中根据用户权限或其他条件动态添加路由 但是,根据用户的问题,我们主要关注如何动态生成路由(即动态添加路由到路由器实例)。 在Vue Router中,我们可以使用`router.addRoute()`方法来动态添加路由。在Vue3中,由于使用了TypeScript,我们需要确保类型的正确性。 步骤: 1. 创建路由器实例时,只配置静态路由。 2. 在获取到用户权限或菜单数据后,动态构造路由配置,并使用`addRoute`方法添加。 注意:动态路由需要匹配对应的组件,因此我们通常需要提前准备好组件或者使用动态导入(懒加载)。 示例代码: 首先,我们定义一个静态路由数组和一个动态路由数组(初始为空)。然后创建路由器。 接着,在适当的时机(比如用户登录后),我们获取到用户的路由权限数据,然后根据这个数据生成路由配置,并逐一添加到路由器中。 由于使用了TypeScript,我们需要定义路由的类型。Vue Router提供了`RouteRecordRaw`类型。 下面是一个示例: ```typescript // src/router/index.ts import { createRouter, createWebHistory, RouteRecordRaw } from &#39;vue-router&#39; // 静态路由 const constantRoutes: RouteRecordRaw[] = [ { path: &#39;/login&#39;, name: &#39;Login&#39;, component: () => import(&#39;@/views/Login.vue&#39;) }, { path: &#39;/404&#39;, name: &#39;NotFound&#39;, component: () => import(&#39;@/views/404.vue&#39;) }, // ...其他静态路由 ] // 创建路由器,暂时只包含静态路由 const router = createRouter({ history: createWebHistory(), routes: constantRoutes }) // 动态添加路由的函数 export function addDynamicRoutes(routes: RouteRecordRaw[]) { routes.forEach(route => { // 避免重复添加 if (!router.hasRoute(route.name as string)) { router.addRoute(route) } }) // 最后,确保添加一个404路由,如果动态路由没有匹配到,可能会跳转到404 // 注意:这里我们已经在静态路由中定义了404,所以不需要重复添加 // 但如果没有,可以在这里添加一个通配符路由 } export default router ``` 然后,在用户登录后,我们获取到用户可访问的路由列表(可能是从后端API获取的),然后转换成`RouteRecordRaw[]`格式,再调用`addDynamicRoutes`函数添加。 注意:动态路由的组件导入可以使用动态导入(例如`() => import(&#39;@/views/...&#39;)`),这样可以利用代码分割。 另外,由于权限控制的需要,我们可能还需要在路由守卫中处理。例如,在全局前置守卫中,判断用户是否登录,以及是否已经添加了动态路由。 例如: ```typescript // 在main.ts或一个专门的权限控制模块中 import router, { addDynamicRoutes } from &#39;./router&#39; import { getRoutes } from &#39;./api/menu&#39; // 假设有获取动态路由的API router.beforeEach(async (to, from, next) => { if (to.path === &#39;/login&#39;) { next() } else { // 检查用户是否登录(这里假设用token判断) const token = localStorage.getItem(&#39;token&#39;) if (!token) { next(&#39;/login&#39;) } else { // 如果已经登录,检查是否已经添加动态路由 if (!store.state.user.hasRoutes) { // 假设用一个状态记录是否已经添加了动态路由 // 获取动态路由 const dynRoutes = await getRoutes() // 这个函数返回一个RouteRecordRaw[]格式的路由 addDynamicRoutes(dynRoutes) // 标记已经添加了动态路由 store.commit(&#39;user/setHasRoutes&#39;, true) // 由于动态添加了路由,需要重定向到目标路由 next({ ...to, replace: true }) } else { next() } } } }) ``` 注意:上面的代码中,我们假设使用了一个状态管理(比如Pinia或Vuex)来存储是否已经添加了动态路由的状态。 另外,关于动态路由的数据结构,通常需要和后端约定。后端返回的数据可能是一个树状结构,我们需要将其转换成路由配置。 例如,后端返回的数据可能是这样的: ```json [ { "path": "/home", "name": "Home", "component": "Home.vue", // 这里需要映射到实际的组件路径 "children": [] } ] ``` 在转换时,需要将字符串形式的组件路径转换为动态导入的组件函数。 例如: ```typescript // 将后端返回的路由数据转换为RouteRecordRaw[] function transformRoutes(routes: any[]): RouteRecordRaw[] { return routes.map(route => { return { path: route.path, name: route.name, component: () => import(`@/views/${route.component}`), // 注意:这里路径要正确 children: route.children ? transformRoutes(route.children) : [] } }) } ``` 注意:上面的`import`使用了模板字符串,这要求你的构建工具(如Vite)支持动态导入。另外,要注意安全,避免用户恶意构造组件路径。 最后,在TypeScript中,我们还需要确保类型。我们可以定义一个接口来描述后端返回的路由对象结构。 另外,引用[4]中提到了刷新路由,这可能是当用户刷新页面时需要重新加载动态路由。因此,在应用初始化时,如果用户已经登录,我们也需要调用动态路由添加函数。 总结: 动态生成路由的核心是使用`router.addRoute`方法,并在适当的时机(登录后或刷新页面后)获取路由数据并添加。 由于用户要求使用Vue3和TypeScript,我们需要在定义路由时使用`RouteRecordRaw`类型,并确保组件的正确导入。 我们还需要注意,在动态添加路由后,如果当前路由不存在,可能需要重定向到当前路由(使用`next({...to, replace: true})`)。 以上就是一个基本的动态生成路由的方法。 生成相关问题: 1. 动态路由和静态路由有什么区别? 2.Vue Router中如何实现路由守卫来控制动态路由添加? 3. 如何处理刷新页面后动态路由丢失的问题? 4. 如何优化动态路由的加载性能? </think> 在 Vue3 + TypeScript 环境中动态生成路由的核心实现步骤如下,结合引用内容中的关键实践: ### 1. **静态路由与动态路由分离** ```typescript // src/router/index.ts import { createRouter, createWebHistory, RouteRecordRaw } from &#39;vue-router&#39; // 静态路由(基础路由) const constantRoutes: RouteRecordRaw[] = [ { path: &#39;/login&#39;, component: () => import(&#39;@/views/Login.vue&#39;) }, { path: &#39;/404&#39;, component: () => import(&#39;@/views/404.vue&#39;) } ] // 创建路由实例(初始仅包含静态路由) const router = createRouter({ history: createWebHistory(), routes: constantRoutes }) ``` ### 2. **动态路由类型定义** ```typescript // 定义动态路由类型 type DynamicRoute = Omit<RouteRecordRaw, &#39;children&#39;> & { meta: { roles: string[] // 权限标识 }, children?: DynamicRoute[] } ``` ### 3. **路由添加方法** ```typescript // 动态添加路由的核心函数 export const addDynamicRoutes = (routes: DynamicRoute[]) => { routes.forEach(route => { // 避免重复添加 if (!router.hasRoute(route.name!)) { router.addRoute(route) } }) // 添加404通配路由(必须放在最后) router.addRoute({ path: &#39;/:catchAll(.*)&#39;, redirect: &#39;/404&#39; }) } ``` ### 4. **路由数据获取与注入** ```typescript // 在登录后或应用初始化时调用 const setupDynamicRoutes = async () => { try { // 从API获取动态路由配置(示例) const res = await fetch(&#39;/api/user/routes&#39;) const dynamicRoutes: DynamicRoute[] = await res.json() // 注入动态路由 addDynamicRoutes(dynamicRoutes) // 初始化后重定向到首页 router.replace(&#39;/home&#39;) } catch (err) { console.error(&#39;路由加载失败&#39;, err) } } ``` ### 5. **路由守卫控制(关键)** ```typescript router.beforeEach(async (to, from) => { // 1. 已登录且未初始化动态路由 if (isAuthenticated() && !store.state.routeInited) { await setupDynamicRoutes() return to.fullPath // 重定向到目标页 } // 2. 检查动态路由权限 if (to.meta.roles && !hasPermission(to.meta.roles)) { return &#39;/403&#39; // 无权限跳转 } }) ``` ### 6. **刷新路由处理(引用[4]实践)** ```typescript // 在应用入口文件(main.ts)初始化 import { ReloadData } from &#39;@/stores&#39; // 状态管理 import router from &#39;./router&#39; const initApp = () => { ReloadData() // 恢复Pinia状态 setupDynamicRoutes() // 刷新时重新注入路由 } // 挂载应用前初始化 initApp() app.use(router).mount(&#39;#app&#39;) ``` ### 注意事项 1. **组件懒加载**:动态路由组件必须使用 `() => import(&#39;@/views/...&#39;)` 语法 2. **类型安全**:在 `tsconfig.json` 配置路径别名: ```json { "compilerOptions": { "paths": { "@/*": ["src/*"] } } } ``` 3. **路由重置**:退出登录时需要调用 `router.removeRoute()` 清理动态路由 --- ### 动态路由工作流程 ```mermaid graph TD A[用户登录] --> B[获取权限路由数据] B --> C[转换为DynamicRoute格式] C --> D[router.addRoute注入] D --> E[路由守卫权限校验] E --> F[渲染对应组件] ``` ### 相关问题 1. 如何在 Vue3 中实现路由权限的动态验证? 2. 动态路由场景下如何处理页面刷新时的路由丢失问题? 3. TypeScript 如何为动态路由的 meta 字段定义复杂类型? 4. Vue Router 4 的 `addRoute` 方法有哪些使用限制? 5. 如何优化大型动态路由项目的加载性能? [^1]: Vue3+TypeScript 动态路由实现方案 [^2]: 尚硅谷 Vue3 实战教程路由配置示例 [^3]: Vite 项目中 TypeScript 路径别名配置方法 [^4]: 刷新路由的状态管理实现方案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值