# h-vue-element-admin **Repository Path**: han-zai/h-vue-element-admin ## Basic Information - **Project Name**: h-vue-element-admin - **Description**: 基于vue-admin-template开发的后模板,对element一些常用组件进行了二次封装 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-02-29 - **Last Updated**: 2024-09-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # h-vue-element-admin ## 介绍 这是基于vue-admin-template开发的一个 vue admin 管理后台。它在vue-admin-template基础上添加了动态路由、权限验证,对element的一些组件进行了二次开发。 - vue-admin-template ## 准备 node版本:14.15 ``` # 克隆项目 git clone https://gitee.com/han-zai/h-vue-element-admin.git # 进入项目目录 cd h-vue-element-admin # 安装依赖 npm install # 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 npm install --registry=https://registry.npm.taobao.org # 启动服务 npm run dev ``` ## 发布 ``` # 构建测试环境 npm run build:stage # 构建生产环境 npm run build:prod ``` ## 其它 ``` # 预览发布环境效果 npm run preview # 预览发布环境效果 + 静态资源分析 npm run preview -- --report # 代码格式检查 npm run lint # 代码格式检查并自动修复 npm run lint -- --fix ``` ## Axios二次封装及使用 @/src/http/MyAxios.js //二次封装Axios,可以根据自己喜好替换 @/src/http/BaseUrl.js //封装请求前缀,可以使用evn环境变量代替 @/src/http/index.js //http目录的主js导出所有Api接口模块对象 @/src/http/api //该文件夹下存放所有接口模块对象 **使用** ``` import httpApi from "@/http"; httpApi.LoginApi.login({ username: username.trim(), password: password, }) .then((res) => { //成功处理 }) .catch((error) => { // 错误处理 }); ``` ## 权限处理 ### 一、登录 @/views/login/index.vue 处理登录逻辑 ``` handleLogin() { this.$refs.loginForm.validate((valid) => { if (valid) { this.loading = true this.$store .dispatch('user/login', this.loginForm) .then((res) => { // 根据后端返回的状态码判断一下是否登录成功,如果登录成功则重定向到首页 if (res.data.code === 200) { this.$router.push('/') } // this.$router.push({ path: this.redirect || "/" }); this.loading = false }) .catch(() => { this.loading = false }) } else { // console.log("error submit!!"); return false } }) } ``` ### 二、存储用户信息 @/src/store/modules/user.js 这里的getinfo并没有像vue-element-admin一样发送请求,由于后端是在登录时把所有信息都返回给了前端,所以在这里登录成功后是把信息存到localStorage中,在getinfo中去读取localStorage中的信息。如果需要getinfo去发送请求,请参考vue-element-admin的登录逻辑 ``` login({ commit }, userInfo) { const { username, password } = userInfo return new Promise((resolve, reject) => { httpApi.LoginApi.login({ username: username.trim(), password: password }) .then((res) => { localStorage.setItem('data', JSON.stringify(res.data.data)) commit('SET_TOKEN', res.data.data.token) commit('SET_AVATAR', URL + res.data.data.avatar) commit('SET_NAME', '管理员') setToken(res.data.data.token) // token resolve(res) }) .catch((error) => { reject(error) }) }) }, getInfo({ commit, state }) { try { const dataStr = localStorage.getItem('data') if (!dataStr) { // 处理数据不存在的情况 return null // 或抛出错误,取决于你的需求 } const data = JSON.parse(dataStr) commit('SET_ROLES', data.role) return data } catch (error) { // 处理JSON解析错误或其他错误 console.error('Error fetching data from localStorage:', error) return null // 或抛出错误,取决于你的需求 } }, ``` ### 三、过滤路由信息 @src/store/modules/permission.js ### 四、根据信息生成路由 @src/permission.js 基本上每一行代码都写了注释, 注意“第64行代码` router.options.routes = store.getters.permission_routes` ESLint检查一定会报错error Possible race condition: `router.options.routes` might be reassigned based on an outdated value of `router.options.routes` 暂时还未发现对项目有什么影响,如果有哪位大哥有更好的思路麻烦大哥提个pr ## element二次封装 >
class="box" > style=" > width: 100%; > height: 50px; > background-color: #67c23a; > line-height: 50px; > color: #fff; > text-align: center; > " > > > 已经在 main.js >中注册为全局组件,可以直接使用 >
### 分页组件 父组件中 provide 初始化数据的方法名  this.init 修改所被触发的函数方法名,这里万万不可写括号。不懂从头学一遍js  | 参数名称 | 说明 | 类型 | 必填 | 默认值 | | :-------: | :--------------------: | :------: | :---: | :--------------: | | total | 总条目数 | Number | true | | | page | 当前页数 | Number | false | 1 | | limit | 每页显示条目个数 | Number | false | 10 | | pageSizes | 设置一次展示多少行数据 | Number[] | false | [10, 20, 30, 50] | **示例** ​ 通过.sync实现数据的双向绑定 ``` provide() { return { init: this.init, }; }, data() { return { page: 1, limit: 10, total:100, }; }, methods: { init() { //发送请求 }, } ``` ### button按钮 绑定点击事件必须添加 .native 修饰符 | 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 | | :---------: | :------: | :----: | :------: | :-------------------: | :-------------------: | | type | 类型 | String | false | default | error/default/success | | size | 文字大小 | String | false | mini | mini/big/nomal | | borderColor | 边框颜色 | String | false | 'rgba(255,255,255,0)' | 请选择您喜欢的颜色 | | color | 字体颜色 | String | false | "#fff" | 请选择您喜欢的颜色 | **示例** ``` 点击 methods: { test() { console.log("测试"); }, } ``` ### 日期选择器 修改变量名请同步 @/components/H-element/DatePicker 中修改 | 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 | | :--------------: | :-----------------: | :------: | :------: | :------: | :---------------: | | time | 绑定值 | String[] | false | 空字符串 | | | startPlaceholder | 开始日期的占位内容 | String | false | 开始日期 | | | endPlaceholder | 结束日期的占位内容 | String | false | 结束日期 | | | rangeSeparator | 分隔符 | String | false | "-" | | | align | 对齐方式(同element) | String | false | left | left/center/right | **示例** ``` data() { return { time: "", }; }, ``` ### 对话框 | 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 | | :---------------: | :----------------------------------------------------------: | :-----: | :------: | :----: | :--------: | | show | 是否显示 | Boolean | false | false | true/false | | title | 标题 | String | false | 提示 | | | appendToBody | Dialog 自身是否插入至 body 元素上。嵌套的 Dialog 必须指定该属性并赋值为 true | Boolean | false | true | true/false | | modalAppendToBody | 遮罩层是否插入至 body 元素上,若为 false,则遮罩层会插入至 Dialog 的父元素上 | Boolean | false | true | true/false | | modal | 是否需要遮罩层 | Boolean | false | false | true/false | | fullscreen | 是否全屏 | Boolean | false | false | true/false | | destroyOnClose | 关闭时销毁 Dialog 中的元素 | Boolean | false | true | true/false | | width | 宽度 | String | false | 30% | | **自定义事件** | 事件名称 | 说明 | | :---------: | :------------------------: | | handleClose | Dialog关闭前回调 | | open | Dialog打开的回调 | | opened | Dialog打开动画结束时的回调 | | close | Dialog关闭的回调 | | closed | Dialog关闭动画结束时的回调 | **示例** ``` 你好
这是title
点击关闭弹窗
data() { return { activePopShow: true } }, methods: { close() { this.activePopShow = false } } ``` ### 图片压缩上传 >
class="box" > style=" > width: 100%; > background-color: #67c23a; > line-height: 50px; > color: #fff; > " > > > 很多时候都会遇到图片过大无法上传,前端的作法大部分都是限制图片只有2M,总觉得用户的体验感不是很好,所以搞了个 压缩 >上传。这里有两种图片压缩的方式,第一种是不考虑图片长宽,只考虑图片大小的情况,图片超过?M压缩 。第二种是图片大小超过?M或者宽度超过指定宽度压缩 > 当然,这里只是对小文件的处理。如果是大文件建议还是用 切片 >上传 >
| 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 | | :------: | :----------------------------------------------------------: | :----: | :------: | :----: | :--------: | | imageUrl | 图片路径(同步父组件),可以去组件代码中修改代码,使用自定义事件则不需要此参数 | String | false | | | | action | 上传地址 | String | true | | | | size | 指定的文件压缩大小 | Number | false | 500 | | | maxSize | 指定图片大小,超过此大小则压缩图片 | Number | false | 2 | | | maxWidth | 指定图片宽度,超过此宽度则压缩图片 | Number | false | 200 | | | type | 设置使用那种方式进行压缩 size:按照大小压缩 width:超过大小或者超过宽度 | String | false | size | size/width | ``` data() { return { imageUrl: '', action: '' } }, ``` ### Badge 标记 总觉得`el-badge`有点难看,甚至觉得修改样式有些恶心,于是我一怒之下手写了个badge。。 | 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 | | :------: | :----------------------------------------------------------: | :--------------: | :------: | :----: | -------------- | | num | 显示值,当值为0时则不显示。定义`num`为`String`类型是时可以用于显示自定义文本。 | String\|\|Number | false | 0 | | | max | 最大值,超过最大值会显示 '{max}+',要求` num`是 `Number` 类型 | Number | false | 99 | | | bgColor | 背景色 | String | false | red | | | size | 字体大小,`is-dot`值为`true`时 | String | false | mini | mini/big/nomal | | color | 字体颜色 | String | false | #fff | | | is-dot | 是否显示小圆点 | Boolean | false | false | true/false | **示例** ``` avatarImage ``` ### UEditor 富文本编辑器 | 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 | | :------: | :--------: | :----: | :------: | :----: | ------ | | detail | 初始值 | String | false | | | | url | 服务器地址 | String | false | | | **自定义事件** | 事件名称 | 说明 | | :------: | :----------------: | | input | 内容发现改变时触发 | **示例** ``` methods: { input(val) { console.log(val); this.content = val; }, }, ```