使用vite + vue3 + ant-design-vue + vue-router + vuex 创建一个管理应用
使用vite + vue3 + ant-design-vue + vue-router + vuex 创建一个管理应用的记录
使用vite 创建项目
我创建的node 版本是 v16.17.1
- 使用NPM 或者 YARN 安装中选择模板和定义项目名称
npm init vite@latest my-vue-app -- --template vue
yarn create vite my-vue-app -- --template vue
- 下载过程中会需要自己选择使用的语言和版本
- 下载完项目后,可以启动项目
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
- 启动后能看到一个hello vue3 的模板。项目引用的插件基本没有。后面需要用到的自己来安装
安装项目中用到的插件
- 这里我简单安装了如下插件
"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 的配置和使用
- 首先下载vuex ,在开始的时候 已经将用到的依赖插件下载好了,版本是 4.1.0
- 创建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
- 在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')
- 使用中可以使用 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);
- 组件中使用存储的数据
import {useStore} from 'vuex'
const store = useStore()
let menu = store.state.allRoutes
vue-router 的基本使用,和动态路由的添加
在应用中 vue-router 帮助开发者实现了前端路由,[参考文档]https://router.vuejs.org/zh/
- 基本的路由配置也比较简单,参考如下
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 创建一个管理应用的更多相关文章
- 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 ...
- Vue.js高效前端开发 • 【Ant Design of Vue框架进阶】
全部章节 >>>> 文章目录 一.栅格组件 1.栅格组件介绍 2.栅格组件使用 3.实践练习 二.输入组件 1.输入框组件使用 2.选择器组件使用 3.单选框组件使用 4.实践 ...
- Vue.js高效前端开发 • 【Ant Design of Vue框架基础】
全部章节 >>>> 文章目录 一.Ant Design of Vue框架 1.Ant Design介绍 2.Ant Design of Vue安装 3.Ant Design o ...
- Ant design在vue,react的引入
文章地址: https://www.cnblogs.com/sandraryan/ 最近由于 一些不可描述的原因 要研究一下Ant design这个前端框架. 祭上官网: https://ant.de ...
- vue3官网介绍,安装,创建一个vue实例
前言:这一章主要是vue的介绍.安装.以及如何创建一个vue实例. 一.vue介绍 vue3中文官网:建议先自己看官网. https://v3.cn.vuejs.org/ vue是渐进式框架,渐进式指 ...
- Vue.js 3 Step 创建一个组件
Step1:Vue.extend()创建组件 Step2:Vue.component()注册组件,注册的标签一定要用小写 Step3:挂载点使用组件 <!doctype html> < ...
- Ant Design Pro Vue 时间段查询 问题
<a-form-item label="起止日期" :labelCol="{lg: {span: 7}, sm: {span: 7}}" :wrapper ...
- ant design for vue 刷新页面,根据当前路由选中相应菜单
<a-menu theme="dark" mode="horizontal" class="menu__a" @select=&quo ...
- ant design for vue 关于table的一些问题
1.为table添加分页: :pagination="pagination" pagination: { defaultPageSize: 10, showTotal: (tota ...
- ant design for vue select 数据回显问题
例如: 想要回显id为1的温度, 结果直接在select框中显示了1,而不是选中了温度, 此时因为select中的value是string类型, 而我们设置的id是number类型, 对应不上, 所以 ...
随机推荐
- Windows平台真实时毫秒级4K H264/H265直播技术方案
背景 在刚提出4K视频的时候,大多数人都觉得没有必要,4K的出现,意味着更高的硬件规格和传输要求,1080P看的很爽.很清晰,完全满足了日常的需求.随着电视的尺寸越来越大,原本1080P成像已经无法满 ...
- KingbaseES V8R6集群维护之--修改数据库服务端口案例
案例说明: 对于KingbaseES数据库单实例环境,只需要修改kingbase.conf文件的'port'参数即可,但是对于KingbaseES V8R6集群中涉及到多个配置文件的修改,并且在应 ...
- KingbaseES Query Mapping 查询映射功能
有过SQL优化经历的人都知道,对于有些SQL性能问题,可能需要涉及到SQL层面的修改,这不仅麻烦,而且在已上线的系统还存在很大的风险.KingbaseES V8R6 提供了query mapping功 ...
- C#,使用NPOI,导出excel文件
/// <summary> /// 导出excel文件 /// </summary> /// <param name="dt">Table表数据 ...
- Gitea 与 Jenkins 的集成实践,打造你的专属 CI/CD 系统
前言 Gitea 是一个用于代码托管的轻量级单体程序,它能与现有的经典应用集成,诸如代码分析工具 SonarQube.持续集成工具 Drone.Jenkins 以及用于工单管理的客户端插件(VSCod ...
- 使用mbr2gpt将MBR磁盘转换为GPT磁盘
随着越来越多的新PC的到来,UEFI启动渐渐的取代了BIOS启动方式.不过UEFI需要从GPT磁盘启动,原来的MBR磁盘不行.如果你更换了硬件,只想把磁盘拿到新平台上用又不想重装系统的话就麻烦了.以前 ...
- Kubernetes DevOps: Gitlab
Gitlab 官方提供了 Helm 的方式在 Kubernetes 集群中来快速安装,但是在使用的过程中发现 Helm 提供的 Chart 包中有很多其他额外的配置,所以我们这里使用自定义的方式来安装 ...
- Kubernetes 版本升级之路
把一个集群从1.22版升级到1.23版. 前提条件 确保备份所有重要组件,例如存储在数据库中的应用状态.Kubernetes 升级不涉及正常的工作负载,只涉及与 Kubernetes 相关的组件,但备 ...
- Ceph 有关知识简介
Ceph 存储集群至少需要一个 Ceph Monitor 和两个 OSD 守护进程.而运行 Ceph 文件系统客户端时,则必须要有元数据服务器( Metadata Server ). Ceph OSD ...
- 大华海康NVR录像JAVA下载及WEB播放
近期在处理一个将NVR录像机上的录像下载到服务器并通过浏览器播放的需求. 梳理记录下过程,做个备忘,同时遇到的一些细节问题解决,也供需要的同学参考. 需求比较简单,就是把指定时间段的录像上传到服务器保 ...