vue antd 使用小结
- 写在前面
- 开发基础
- 问题集锦及解决办法
- 写在后面
写在前面
从六月底开始,到现在这个项目告一段落,两月有余,从刚开始的一无所知,到现在稍有了解,还是想对这段过程做一个总结,不仅仅是这个组件库的应用,也是对自己这段时间的成长做一个总结回顾。
开发基础
结合Ant Design Vue,基于 vue antd admin进行开发。
问题集锦及解决办法
序号 | 问题 | 解决办法 |
1 | 调整表格间距 | 使用表格的 |
2 | 添加按钮背景颜色 | 使用按钮的 |
3 | 分页 控制显示 | 自定义分页配置 |
4 | 显示序号 | 使用表格插槽,添加序号表头 |
5 | 批量删除 | 给表格加上 |
6 | 单选修改状态 | 可以使用 |
7 | 树结构默认选中 | 找到双向绑定的选中值进行赋值就可以 |
8 | 分页切换loading | 表格 |
9 | admin设置无法选中 | 获取当前行的值使用判断语句控制 |
10 | 表单验证 | 使用表单自定义验证方式,配置对应的正则表达式 |
11 | 接口文档 | 找到封装的axios文件,根据格式,写网络请求api文档 |
12 | 输入长度限制 | input输入框的maxLength属性,动态绑定长度,限制输入 |
13 | 错误状态处理 | 捕获错误之后,有的数组要进行清空,不能在失败的时候显示之前的数据 |
14 | 模态框复用 | 使用枚举,判断类型 |
15 | 代码逻辑 | 初始化的时候,不要写太多方法,尽量将逻辑处理部分写在外面,例如 |
16 | 逻辑处理 | 尽量用一个方法处理,见名之意,调用方法返回结果 |
17 | 组件通信 | 订阅者模式,也可以用在非兄弟组件之间,通过 |
18 | 知识点补充 | js的事件循环、箭头函数中 |
19 | v-if的使用 |
|
20 | 空状态的使用 | 当页面数据为空的时候显示,通过 |
21 | 分页变化控制 | 操作分页之后要把当前页面数据条数和页面传给后台,重新查询,成功后将数据总条数赋值给对应的分页配置总数变量 |
22 | 冒泡事件 | 增删查改的时候,不能改变选中状态,阻止事件的冒泡,使用vue修饰符 |
23 | 隐藏/置灰一行的某个按钮 | 使用 |
24 | 回车提交 | 搜索框可以添加 |
25 | 点击模态框旁边不允许关闭 | 添加属性 |
26 | input清空历史记录 | 不记住浏览器的密码,使用属性 |
27 | 下拉框回显 | 下拉框(单选框)使用的时候注意需要的是什么类型的数据,要给相应的数据才能显示,选中的数据一定是整个数据源数组里的东西,但是要跟选择框需要的数据类型对应才能正确显示。树形结构数据从子级找父级数据的时候,先把数据打平,再遍历,就能拿到对应的父级id,存session会存在误差,操作同步但是数据并不同步 |
28 | 对象转换为数组 |
|
29 | 搜索框加防抖 | 传入对应的网络请求方法名,和延迟时间,回调此方法时加上延时 |
30 | 数据长度溢出 | 使用 |
31 | 悬浮提示 | 气泡提示 |
32 | 模块分割 | 加上分割线 |
33 | 树选择CheckBox和文字同步 | 改变属性 |
34 | 删完当前页数据页面跳转 | 删除之后判断当前页面是否还有数据,如果没有就默认跳转回第一页,如果有就留在当前页面(总数减一或者批量选中的数量,对pagesize进行取余,为零就跳转回上一页,不为零就留在当前页) |
35 | 序号要按总数据排序 | 按当前页码-1查询之后,也要给当前页码重新赋值, |
36 | 对话框关闭其中的元素没有销毁,显示历史记录 | 使用 |
37 | checkgroup绑定key要唯一 | 设置 |
38 | 验证不通过按钮置灰 | 打印 |
39 | 样式调整 | 调试的时候,先定位,先取到什么值,按部就班。二分法,不要只会用定位,先确定外层容器,然后二分之后用浮动 |
40 | 箴言总结 | 1、今日事今日毕,需求出来的时候就先解决这件事,不能一直拖着到后面,否则会越积越多 2、思路要清晰,要专心解决3、下次面对突发状况之前,先把当前页面改到一种不出错的状态再去做新任务,或者记一下先,回头继续 |
- 显示序号代码
<span slot="num" slot-scope="text,record,index">
{{ (myPagination.current-1)*myPagination.pageSize+parseInt(index)+1 }}
</span>
- 搜索框加防抖 代码
export function debounce (fn, delay) {
let t = null;
return () => {
if (t !== null) {
clearTimeout(t)
}
t = setTimeout(() => {
fn.call(this)
}, delay);
}
}
// 页面中引用,input属性,或者change属性
<a-input-search @input="debounce" />
export default {
name: 'PlantingCost',
components: {},
// 全局注入
inject: ['debounces'],
data() {
return {
// 引用
debounce: this.debounces(
() => this.getPlantingCostData(this.keyword),
500
),
}
}
}
- 验证不通过按钮置灰 代码
export function putAsh (form, ModalType) {
let arr = [];
let hass = false;
if (form) {
form.$children.forEach(e => {
if (e.isRequired) {
arr.push(e)
}
})
if (modelLength(ModalType, arr) === arr.length && modelError(form.$children) === 0) {
hass = false
} else {
hass = true
}
} else {
hass = modelType(ModalType)
}
return hass;
}
export function modelError (allarr) {
return allarr.filter((v) => v.validateState == "error").length
}
export function modelLength (type, arr) {
switch (type) {
case 0:
return arr.filter((v) => v.validateState === "success").length
case 1:
return arr.filter((v) => (v.initialValue && (v.validateState != "error" || v.validateState === undefined)) || v.validateState === "success").length
case 2:
return arr.filter((v) => (v.initialValue && v.validateState != "error") || v.validateState === "success").length
}
}
export function modelType (type) {
switch (type) {
case 0:
return true
case 1:
return false
case 2:
return true
}
}
export function getProps (arr) {
let newArr = [];
for (const key in arr) {
newArr.push(key);
}
return newArr
}
//通过一个数组过滤一个对象
export function filterProps (props, fieldsError) {
let selectNewList = {}; //组装过后的对象
selectNewList = Object.keys(fieldsError).filter(val =>
props.includes(val)
).reduce((obj, key) => {
obj[key] = fieldsError[key];
return obj;
}, {});
return selectNewList
}
export function isAllEqual (array) {
if (array.length > 0) {
return !array.some(function (value) {
return value !== array[0];
});
} else {
return true;
}
}
export default { putAsh };
// 页面中引用,input属性,或者change属性
<a-form-model ref="ruleForm" :model="formChange" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-model />
<template slot="footer">
<a-button key="back" @click="handleCancel(ModalType)"> 取消 </a-button>
<a-button type="primary" :disabled="putAsh($refs.ruleForm,ModalType)" @click="handleOk(ModalType)">确定</a-button>
</template>
// 导入
import { putAsh } from '@/utils/putAsh';
export default {
name: 'PlantingCost',
components: {},
data() {
return {
// 引用
putAsh: putAsh,,
}
}
}
补充:文档的上传和下载代码
//download 方法
export function download (data, type, title) {
let blob = new Blob([data], { type: 'application/vnd.ms-excel' });
let objectUrl = URL.createObjectURL(blob);
let link = document.createElement("a");
//let cs=res.headers["content-disposition"].split(";")[2].split("filename=")[1]
//cs = cs.replace(/\"/g,"");//去掉双引号
link.href = objectUrl;
//let time = new Date().getFullYear() +'-'+ (new Date().getMonth()+1) +'-'+ new Date().getDate()
let time = Date.parse(new Date())
if (type === 1) {
link.setAttribute("download", title + time + '.xls');
} else {
link.setAttribute("download", title + time + '.pdf');
}
document.body.appendChild(link);
link.click();
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(blob)
}
<template slot="operation" slot-scope="text, record">
<div class="btns">
<a-tooltip placement="topLeft" title="下载PDF">
<a-button type="primary" :disabled="record.status!='已上传'" @click="downloadFile(record,2)">
<a-icon type="download" />
</a-button>
</a-tooltip>
<a-tooltip placement="topLeft" title="上传PDF">
<a-upload class="avatar-uploader" :show-upload-list="false" :customRequest="uploadFile" :data="{ id: record.classifyId }" :before-upload="beforeUpload" @change="handleChange">
<a-button type="primary">
<a-icon type="cloud-upload" />
</a-button>
</a-upload>
</a-tooltip>
</div>
</template>
//引用
inject: ['downloads'],
// 方法
downloadFile(record, type) {
if (record.status != '未上传') {
sortFileDownload(record.classifyId)
.then(res => {
if (res.status == 200) {
this.downloads(res.data, type, record.classifyName);
this.query(
this.myPagination.pageSize,
this.myPagination.current
);
}
})
.catch(err => {
console.log(err);
});
} else {
this.$notification['error']({
message: '操作失败,分类文档尚未上传!',
});
}
},
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true;
return;
}
},
beforeUpload(file) {
const isPDF = file.type === 'application/pdf';
// ||file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
// file.type === 'application/vnd.ms-excel';
if (!isPDF) {
this.$message.error('只能上传PDF文件!');
}
const isLt100M = file.size / 1024 / 1024 < 100;
if (!isLt100M) {
this.$message.error('文件最大不能超过100M');
}
return isPDF && isLt100M;
},
uploadFile(file) {
if (this.classifyId != '') {
const formData = new FormData();
formData.append('file', file.file);
sortFileUpload(this.classifyId, formData)
.then(res => {
if (res.data.success) {
this.query(
this.myPagination.pageSize,
this.myPagination.current
);
}
})
.catch(err => {
console.log('上传失败', err);
});
}
},
写在后面
简短的一个总结回顾。大部分来源于平常遇到问题的随手记,问题描述不是很详细,解决办法也不是很详细,下次做项目的也应该要记得改变一下这个习惯,之后再进行回顾的时候也会更加细致一些,还有很多地方需要学习。
路漫漫其修远兮。