使用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. JVM之HotSpot虚拟机是如何发起内存回收的? 转载

    1.背景 在上一节中,我们掌握了垃圾收集的一些算法,也弄明白了分代回收的原理, 那么HotSpot虚拟机是如何发起内存回收的? 2.如何找到GC Roots根节点(枚举根节点) 从可达性分析中GC R ...

  2. KingbaseES 中select distinct on 语句

    用法 SELECT DISTINCT ON ( expression [, ...] ) 把记录根据[, -]的值进行分组,分组之后仅返回每一组的第一行. 需要注意的是,如果不指定ORDER BY子句 ...

  3. Redis变慢?深入浅出Redis性能诊断系列文章(一)

    (本文首发于"数据库架构师"公号,订阅"数据库架构师"公号,一起学习数据库技术)   Redis 作为一款业内使用率最高的内存数据库,其拥有非常高的性能,单节点 ...

  4. 《Win10——常用快捷键》

    Win10--常用快捷键       Ctrl+C:复制 Ctrl+V:粘贴 Ctrl+A:全选 Ctrl+X:剪切 Ctrl+D:删除 Ctrl+Z:撤销 Ctrl+Y:反撤销 Ctrl+Shift ...

  5. ProxySQL 防火墙白名单

    ProxySQL 2.0.9 引入了防火墙功能. 在从早期版本版本中,可以通过设置查询规则来创建要阻止的黑名单,或者定义通用规则,实现白名单功能. 但是,如果面对的系统有非常多而且操作内容也不同,这时 ...

  6. docker bridge 到 k8s pod 跨节点网络通信机制演进

  7. logstash 读取MySQL数据到elasticsearch 相差8小时解决办法

    logstash和elasticsearch是按照UTC时间的,kibana却是按照正常你所在的时区显示的,是因为kibana中可以配置时区信息. 具体看这个: logstash 的配置文件添加 fi ...

  8. CentOS yum如何安装php7.4

    centos系统下使用yum安装php7.4正式版,当前基于WLNMP提供的一键安装包来安装 1.添加epel源 yum install epel-release 2.添加WLNMP一键安装包源 rp ...

  9. 在 Fedora 中使用 Cockpit 创建虚拟机

    本文向你展示如何在 Fedora 31 上使用安装 Cockpit 所需软件来创建和管理虚拟机.Cockpit 是一个交互式管理界面,可让你在任何受支持的 Web 浏览器上访问和管理系统.随着 vir ...

  10. 跳转控制语句break

    执行某些循环时,当满足了某个条件,使其提早退出循环,便可以使用break跳出循环 流程图如下: 其他循环均可以以此类推 例子: