使用vite + vue3 + ant-design-vue + vue-router + vuex 创建一个管理应用的记录

使用vite 创建项目

我创建的node 版本是 v16.17.1

  1. 使用NPM 或者 YARN 安装中选择模板和定义项目名称
npm init vite@latest my-vue-app -- --template vue
yarn create vite my-vue-app -- --template vue
  1. 下载过程中会需要自己选择使用的语言和版本
  2. 下载完项目后,可以启动项目
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
  1. 启动后能看到一个hello vue3 的模板。项目引用的插件基本没有。后面需要用到的自己来安装

安装项目中用到的插件

  1. 这里我简单安装了如下插件
"ant-design-vue": "^3.2.13",
"axios": "^1.1.3",
"c-scrollbar": "^1.0.2",
"vue": "^3.2.41",
"vue-router": "4",
"vuex": "^4.1.0" "less": "^4.1.3",
"unplugin-vue-components": "^0.22.9",

项目使用了 ant-design-vue 先来说下UI 组件的配置

[文档] https://www.antdv.com/docs/vue/getting-started-cn

这里我介绍下 我使用的按需加载的配置。 在vite.congig.js 中

import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [
AntDesignVueResolver()
]
})
],
})

设置完,在组件中就可以直接使用框架提供的UI 组件, 写法上比较方便了。

项目请求服务端的跨域配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [
AntDesignVueResolver()
]
})
],
server: {
proxy: {
"/api": {
target: "要请求的地址",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
})

配置axios 统一请求拦截器添加的参数,和配置响应的分类

一般在发送服务请求的时候,会在请求头中添加验证的token ,配置请求地址中识别需要跨域处理的关键字端。

响应中根据返回的结果,按统一的结构返回到请求的API中

import axios from 'axios'
import store from '@/store'
import router from '@/route/index.js'
axios.defaults.timeout = 30000
// 返回其他状态吗
axios.defaults.validateStatus = function (status) {
return status >= 200 && status <= 500 // 默认的
}
// 跨域请求,允许保存cookie
axios.defaults.withCredentials = true axios.interceptors.request.use(config => {
config.url = '/api' + config.url
const token = store.state.token
const TENANT_ID = 1
if (token) {
config.headers['Authorization'] = 'Bearer ' + token// token
}
if (TENANT_ID) {
config.headers['TENANT-ID'] = TENANT_ID // 租户ID
}
return config
}, error => {
return Promise.reject(error)
}) axios.interceptors.response.use(res => {
const httpStatus = res.status
if (httpStatus === 200) {
const code = res.data.code
if (code === 0) {
return res.data.data
}else{
return Promise.reject(new Error(res.data.msg))
}
}else{
router.push({
path: '/login'
})
return Promise.reject(new Error(res.statusText))
} }, error => {
// 处理 503 网络异常
if (error.response.status === 503) { }
return Promise.reject(new Error(error))
}) export default axios

vuex 在项目中的配置,使用

[文档地址]https://vuex.vuejs.org/zh/guide/

上面的请求拦截器中我们使用到了token, token保存在了vuex 的store 中。

下面介绍下 vuex 的配置和使用

  1. 首先下载vuex ,在开始的时候 已经将用到的依赖插件下载好了,版本是 4.1.0
  2. 创建store.js 包含state, mutatins, actions, getter
import {createStore} from 'vuex'
const state = {
allRoutes: [],
token: '',
};
const mutations = {
set_allRoutes(state,payload){
state.allRoutes = payload
},
set_token(state, token) {
state.token = token
}
}
const actions = {
set_access_token(context, token) {
return new Promise(resolve => {
context.commit('set_token', token)
resolve()
})
}
}
const getter = {
allRoutes(state) {
return state.allRoutes
}
}
const options = {
state,
mutations,
actions,
getter
}
const store = createStore(options)
export default store
  1. 在main.js中
import { createApp } from 'vue'
import App from './App.vue'
import store from '@/store/index'
const app = createApp(App)
app.use(router).use(store).mount('#app')
  1. 使用中可以使用 commit, dispatch 来调用mutations, commit 中修改数据的方法

    4.1 使用dispatch 异步修改数据
import { defineComponent, reactive } from 'vue';
import { useStore } from 'vuex'
import {useRouter} from 'vue-router'
export default defineComponent({
setup() {
const store = useStore()
const route = useRouter()
const onFinish = values => {
let token = '12b02935-e967-4ef6-9276-6207f4fff6e8'
store.dispatch('set_access_token', token).then(() => {
route.push({
path: '/'
})
})
};
return {
onFinish,
};
}, });

4.2 使用commit 同步修改数据

const store = useStore()
store.commit('set_allRoutes', res);
  1. 组件中使用存储的数据
import {useStore} from 'vuex'
const store = useStore()
let menu = store.state.allRoutes

vue-router 的基本使用,和动态路由的添加

在应用中 vue-router 帮助开发者实现了前端路由,[参考文档]https://router.vuejs.org/zh/

  1. 基本的路由配置也比较简单,参考如下
route/index.js
import {createRouter,createWebHashHistory} from 'vue-router'
import Home from '../page/Home.vue'
import Login from '@/page/login/index.vue'
const routes = [
{
path: '/',
redirect: '/index/hello'
},
{
path: '/login',
name: 'login',
component:Login
},
{
path: '/index',
component: Home,
children: [
{ path: 'hello',name: 'hello', component: () => import ('../components/HelloWorld.vue') }, ],
}
]
const router = createRouter({
// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
history: createWebHashHistory(),
routes, // `routes: routes` 的缩写
})
export default router

根据上面的写法很容易实现路由和子路由的添加

2. 项目中,一般会有根据用户请求,返回自己拥有的路由权限来动态添加路由

在这里 我做了个简单的示例,

这里选用动态添加路由的方式为 router.addRoute

import router from './index'
import Home from '../page/Home.vue'
import {fetchMenuList} from '@/api/main.js'
const modules = import.meta.glob("../**/**/**.vue")
function addRoute (list) {
list.forEach(item => {
if (item.path === '/admin') {
let routelist = []
item.children.forEach(child => {
let path = child.path.slice(0)
let r = {path: path, name: child.name, component: modules[`../view${child.path}.vue`]}
routelist.push(r)
}) router.addRoute(
{
path: item.path,
component: Home,
children: routelist
}
)
}
}) }

上面代码中 fetchMenuList 是获取用户路由权限的接口,

Home 是要添加的二级路由的 父组件, 接口中获取的数据比较多, 这里只添加了 amdin 一级路由下的二级路由, 如果有多个,也是这个思路

在这需要注意的是 子路由的引用方式,观察代码和 最初简单的添加方式,路由地址引用的模式发生了变化, 这个是因为使用 vite 来编译代码,需要做的处理。 这里不做具体介绍。

下面是权限代码中 添加动态路由的代码

import router from './index'
import Home from '../page/Home.vue'
import store from '@/store'
import {fetchMenuList} from '@/api/main.js'
const modules = import.meta.glob("../**/**/**.vue")
function addRoute (list) {
list.forEach(item => {
if (item.path === '/admin') {
let routelist = []
item.children.forEach(child => {
let path = child.path.slice(0)
let r = {path: path, name: child.name, component: modules[`../view${child.path}.vue`]}
routelist.push(r)
}) router.addRoute(
{
path: item.path,
component: Home,
children: routelist
}
)
}
}) }
const getRouteInfo = () => {
const allRoutes = store.state.allRoutes
return new Promise(resolve => {
if (allRoutes.length === 0) { fetchMenuList().then(res => {
addRoute(res)
store.commit('set_allRoutes', res);
resolve()
})
}else {
addRoute(allRoutes)
resolve()
}
})
}
let menuRouter = false
router.beforeEach((to, from , next) => {
if (store.state.token) {
if (!menuRouter) { getRouteInfo().then(() => {
menuRouter = true
next({...to, replace: true});
})
}else{
next()
}
}else {
if (to.path == '/login') {
next()
}else{ next('/login')
}
}
})

后面的文章,会接着介绍 项目其他相关内容, 欢迎点赞加关注

这里介绍下本人做的头像,壁纸小程序,欢迎大家体验,

热门头像|个性头像|高清头像|性感壁纸|美女壁纸|炫酷壁纸|省电壁纸|唯美壁纸


使用vite + vue3 + ant-design-vue + vue-router + vuex 创建一个管理应用的更多相关文章

  1. ant design for vue 解决 vue.esm.js?c5de:628 [Vue warn]: Invalid prop: custom validator check failed for prop "defaultValue". 的错误

    错误重现: 在使用ant design for vue 的选择器插件的时候, 设置默认为为id(为数字) 报错: 解决办法: id为数字, 而defaultValue 的key 值必须为字符串, 将i ...

  2. Vue.js高效前端开发 • 【Ant Design of Vue框架进阶】

    全部章节 >>>> 文章目录 一.栅格组件 1.栅格组件介绍 2.栅格组件使用 3.实践练习 二.输入组件 1.输入框组件使用 2.选择器组件使用 3.单选框组件使用 4.实践 ...

  3. Vue.js高效前端开发 • 【Ant Design of Vue框架基础】

    全部章节 >>>> 文章目录 一.Ant Design of Vue框架 1.Ant Design介绍 2.Ant Design of Vue安装 3.Ant Design o ...

  4. Ant design在vue,react的引入

    文章地址: https://www.cnblogs.com/sandraryan/ 最近由于 一些不可描述的原因 要研究一下Ant design这个前端框架. 祭上官网: https://ant.de ...

  5. vue3官网介绍,安装,创建一个vue实例

    前言:这一章主要是vue的介绍.安装.以及如何创建一个vue实例. 一.vue介绍 vue3中文官网:建议先自己看官网. https://v3.cn.vuejs.org/ vue是渐进式框架,渐进式指 ...

  6. Vue.js 3 Step 创建一个组件

    Step1:Vue.extend()创建组件 Step2:Vue.component()注册组件,注册的标签一定要用小写 Step3:挂载点使用组件 <!doctype html> < ...

  7. Ant Design Pro Vue 时间段查询 问题

    <a-form-item label="起止日期" :labelCol="{lg: {span: 7}, sm: {span: 7}}" :wrapper ...

  8. ant design for vue 刷新页面,根据当前路由选中相应菜单

    <a-menu theme="dark" mode="horizontal" class="menu__a" @select=&quo ...

  9. ant design for vue 关于table的一些问题

    1.为table添加分页: :pagination="pagination" pagination: { defaultPageSize: 10, showTotal: (tota ...

  10. ant design for vue select 数据回显问题

    例如: 想要回显id为1的温度, 结果直接在select框中显示了1,而不是选中了温度, 此时因为select中的value是string类型, 而我们设置的id是number类型, 对应不上, 所以 ...

随机推荐

  1. Windows平台真实时毫秒级4K H264/H265直播技术方案

    背景 在刚提出4K视频的时候,大多数人都觉得没有必要,4K的出现,意味着更高的硬件规格和传输要求,1080P看的很爽.很清晰,完全满足了日常的需求.随着电视的尺寸越来越大,原本1080P成像已经无法满 ...

  2. KingbaseES V8R6集群维护之--修改数据库服务端口案例

    ​ 案例说明: 对于KingbaseES数据库单实例环境,只需要修改kingbase.conf文件的'port'参数即可,但是对于KingbaseES V8R6集群中涉及到多个配置文件的修改,并且在应 ...

  3. KingbaseES Query Mapping 查询映射功能

    有过SQL优化经历的人都知道,对于有些SQL性能问题,可能需要涉及到SQL层面的修改,这不仅麻烦,而且在已上线的系统还存在很大的风险.KingbaseES V8R6 提供了query mapping功 ...

  4. C#,使用NPOI,导出excel文件

    /// <summary> /// 导出excel文件 /// </summary> /// <param name="dt">Table表数据 ...

  5. Gitea 与 Jenkins 的集成实践,打造你的专属 CI/CD 系统

    前言 Gitea 是一个用于代码托管的轻量级单体程序,它能与现有的经典应用集成,诸如代码分析工具 SonarQube.持续集成工具 Drone.Jenkins 以及用于工单管理的客户端插件(VSCod ...

  6. 使用mbr2gpt将MBR磁盘转换为GPT磁盘

    随着越来越多的新PC的到来,UEFI启动渐渐的取代了BIOS启动方式.不过UEFI需要从GPT磁盘启动,原来的MBR磁盘不行.如果你更换了硬件,只想把磁盘拿到新平台上用又不想重装系统的话就麻烦了.以前 ...

  7. Kubernetes DevOps: Gitlab

    Gitlab 官方提供了 Helm 的方式在 Kubernetes 集群中来快速安装,但是在使用的过程中发现 Helm 提供的 Chart 包中有很多其他额外的配置,所以我们这里使用自定义的方式来安装 ...

  8. Kubernetes 版本升级之路

    把一个集群从1.22版升级到1.23版. 前提条件 确保备份所有重要组件,例如存储在数据库中的应用状态.Kubernetes 升级不涉及正常的工作负载,只涉及与 Kubernetes 相关的组件,但备 ...

  9. Ceph 有关知识简介

    Ceph 存储集群至少需要一个 Ceph Monitor 和两个 OSD 守护进程.而运行 Ceph 文件系统客户端时,则必须要有元数据服务器( Metadata Server ). Ceph OSD ...

  10. 大华海康NVR录像JAVA下载及WEB播放

    近期在处理一个将NVR录像机上的录像下载到服务器并通过浏览器播放的需求. 梳理记录下过程,做个备忘,同时遇到的一些细节问题解决,也供需要的同学参考. 需求比较简单,就是把指定时间段的录像上传到服务器保 ...