使用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 pro (十六)advanced 权限管理

    一.概述 原文地址:https://pro.ant.design/docs/authority-management-cn 权限控制是中后台系统中常见的需求之一,你可以利用我们提供的权限控制组件,实现 ...

  5. Ant design在vue,react的引入

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

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

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

  7. GitHub Vue项目推荐|Vue+Element实现的电商后台管理系统功能丰富

    GitHub Vue项目推荐|mall-admin-web是一个电商后台管理系统的前端项目基于Vue+Element实现 主要包括商品管理.订单管理.会员管理.促销管理.运营管理.内容管理.统计报表. ...

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

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

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

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

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

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

随机推荐

  1. CMU 15-445 Project 0 实现字典树

    原文链接:https://juejin.cn/post/7139572163371073543 项目准备 代码.手册 本文对应 2022 年的课程,Project 0 已经更新为实现字典树了.C++1 ...

  2. Python数据科学手册-机器学习: 决策树与随机森林

    无参数 算法 随机森林 随机森林是一种集成方法,集成多个比较简单的评估器形成累计效果. 导入标准程序库 随机森林的诱因: 决策树 随机森林是建立在决策树 基础上 的集成学习器 建一颗决策树 二叉决策树 ...

  3. 7.第六篇 二进制安装 kube-apiserver

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483812&idx=1&sn=e6773e56 ...

  4. 关于Elasticsearch使用java的说明

    从Elastic 7.0开始,我们可以不安装JAVA.安装包包含一个相匹配的JAVA版本在里面. Elasticsearch包含来自JDK维护者(GPLv2 + CE)的捆绑版OpenJDK. 要使用 ...

  5. 几篇关于MySQL数据同步到Elasticsearch的文章---第二篇:canal 实现Mysql到Elasticsearch实时增量同步

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484377&idx=1&sn=199bc88 ...

  6. MySQL 主从同步延迟监控

    MySQL5.7和8.0支持通过 replication_applier_status 表获同步延迟时间,当从库出现延迟后,该表中的字段 REMAINING_DELAY 记录延迟秒数,当没有延迟时,该 ...

  7. 【.NET 6+Loki+Grafana】实现轻量级日志可视化服务功能

    前言:日志功能是几乎所有程序或系统都必备的一个功能.该文章通过使用Loki+Grafana来实现日志记录与可视化查询,欢迎围观. 有关环境: 操作系统:WIN 10 .NET环境:.NET 6 开发环 ...

  8. 洛谷P1962 斐波那契数列 (矩阵快速幂)

    学了矩阵,练一下手... 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll mod=1e9+7; 4 using n ...

  9. ClickHouse(07)ClickHouse数据库引擎解析

    目录 Atomic 建表语句 特性 Table UUID RENAME TABLES DROP/DETACH TABLES EXCHANGE TABLES ReplicatedMergeTree in ...

  10. Java8新特性之Stream流(含具体案例)

    一.概述   Stream 流是 Java 8 新提供给开发者的一组操作集合的 API,将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选.排序.聚合等.元素 ...