# 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 |
**示例**
```
```
### UEditor 富文本编辑器
| 参数名称 | 说明 | 类型 | 是否必填 | 默认值 | 可选值 |
| :------: | :--------: | :----: | :------: | :----: | ------ |
| detail | 初始值 | String | false | | |
| url | 服务器地址 | String | false | | |
**自定义事件**
| 事件名称 | 说明 |
| :------: | :----------------: |
| input | 内容发现改变时触发 |
**示例**
```
methods: {
input(val) {
console.log(val);
this.content = val;
},
},
```