小结"/>
vue antd 使用小结
vue antd 使用小结
- 写在前面
- 开发基础
- 问题集锦及解决办法
- 写在后面
写在前面
从六月底开始,到现在这个项目告一段落,两月有余,从刚开始的一无所知,到现在稍有了解,还是想对这段过程做一个总结,不仅仅是这个组件库的应用,也是对自己这段时间的成长做一个总结回顾。
开发基础
结合Ant Design Vue,基于 vue antd admin进行开发。
问题集锦及解决办法
序号 | 问题 | 解决办法 |
---|---|---|
1 | 调整表格间距 | 使用表格的size 属性,设置表格间距 |
2 | 添加按钮背景颜色 | 使用按钮的type 属性,设置背景颜色 |
3 | 分页 控制显示 | 自定义分页配置pagination |
4 | 显示序号 | 使用表格插槽,添加序号表头 |
5 | 批量删除 | 给表格加上checkable 属性,就会显示多选框,再拿到选中的值进行删除 |
6 | 单选修改状态 | 可以使用switch 开关 |
7 | 树结构默认选中 | 找到双向绑定的选中值进行赋值就可以 |
8 | 分页切换loading | 表格loading 属性,在查询的时候控制loading 属性的值 |
9 | admin设置无法选中 | 获取当前行的值使用判断语句控制disabled 属性的值 |
10 | 表单验证 | 使用表单自定义验证方式,配置对应的正则表达式 |
11 | 接口文档 | 找到封装的axios文件,根据格式,写网络请求api文档 |
12 | 输入长度限制 | input输入框的maxLength属性,动态绑定长度,限制输入 |
13 | 错误状态处理 | 捕获错误之后,有的数组要进行清空,不能在失败的时候显示之前的数据 |
14 | 模态框复用 | 使用枚举,判断类型 |
15 | 代码逻辑 | 初始化的时候,不要写太多方法,尽量将逻辑处理部分写在外面,例如methods 中 |
16 | 逻辑处理 | 尽量用一个方法处理,见名之意,调用方法返回结果 |
17 | 组件通信 | 订阅者模式,也可以用在非兄弟组件之间,通过EventBus 进行兄弟间组件通讯,一定要在生命周期结束的时候进行销毁 |
18 | 知识点补充 | js的事件循环、箭头函数中this 的使用、return 的使用 |
19 | v-if的使用 | v-if 使用的时候,如果不满足条件,就会销毁v-if所在的元素,可以用来清空表单验证 |
20 | 空状态的使用 | 当页面数据为空的时候显示,通过v-if、v-else 控制 |
21 | 分页变化控制 | 操作分页之后要把当前页面数据条数和页面传给后台,重新查询,成功后将数据总条数赋值给对应的分页配置总数变量 |
22 | 冒泡事件 | 增删查改的时候,不能改变选中状态,阻止事件的冒泡,使用vue修饰符.present |
23 | 隐藏/置灰一行的某个按钮 | 使用v-if 判断是否显示,使用条件判断控制disabled 属性 |
24 | 回车提交 | 搜索框可以添加 enter-button ,输入框和其他的元素可以使用@keydown.enter.native="OK" ,进行提交 |
25 | 点击模态框旁边不允许关闭 | 添加属性 maskClosable:false |
26 | input清空历史记录 | 不记住浏览器的密码,使用属性 autocomplete="off" |
27 | 下拉框回显 | 下拉框(单选框)使用的时候注意需要的是什么类型的数据,要给相应的数据才能显示,选中的数据一定是整个数据源数组里的东西,但是要跟选择框需要的数据类型对应才能正确显示。树形结构数据从子级找父级数据的时候,先把数据打平,再遍历,就能拿到对应的父级id,存session会存在误差,操作同步但是数据并不同步 |
28 | 对象转换为数组 | Object.keys(obj) |
29 | 搜索框加防抖 | 传入对应的网络请求方法名,和延迟时间,回调此方法时加上延时 |
30 | 数据长度溢出 | 使用css 样式控制,数据只显示一行还是两行,表格中有ellipsis 属性,设置表头宽度,其他的使用插槽,在插槽上加类去控制样式,搜css省略号,就有对应的代码,还可以定义行间距 |
31 | 悬浮提示 | 气泡提示 a-tooltip 组件,还可以控制卡片显示效果 |
32 | 模块分割 | 加上分割线<a-divider dashed /> |
33 | 树选择CheckBox和文字同步 | 改变属性:selectable="false" |
34 | 删完当前页数据页面跳转 | 删除之后判断当前页面是否还有数据,如果没有就默认跳转回第一页,如果有就留在当前页面(总数减一或者批量选中的数量,对pagesize进行取余,为零就跳转回上一页,不为零就留在当前页) |
35 | 序号要按总数据排序 | 按当前页码-1查询之后,也要给当前页码重新赋值,this.myPagination.current = this.myPagination.current - 1 |
36 | 对话框关闭其中的元素没有销毁,显示历史记录 | 使用v-if |
37 | checkgroup绑定key要唯一 | 设置value 和label ,value是选中的值,label是显示出来的值,一般绑定key 使用id ,不会重复 |
38 | 验证不通过按钮置灰 | 打印this.$refs 和this.form 看看,里面可用的,传入表单和对话框类型,拿到当前表单,找到每一项的验证状态,加上非空判定,控制按钮样式 |
39 | 样式调整 | 调试的时候,先定位,先取到什么值,按部就班。二分法,不要只会用定位,先确定外层容器,然后二分之后用浮动float ,用了浮动之后,overflow 的部分要调整,hidden modal labelCol ,和wrapperCol 都可以设置,每一个表单项都可以设置,尽量选靠近底层的组件,越接近底层,可使用的方法就越多 |
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").lengthcase 1:return arr.filter((v) => (v.initialValue && (v.validateState != "error" || v.validateState === undefined)) || v.validateState === "success").lengthcase 2:return arr.filter((v) => (v.initialValue && v.validateState != "error") || v.validateState === "success").length}}export function modelType (type) {switch (type) {case 0:return truecase 1:return falsecase 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);});}},
写在后面
简短的一个总结回顾。大部分来源于平常遇到问题的随手记,问题描述不是很详细,解决办法也不是很详细,下次做项目的也应该要记得改变一下这个习惯,之后再进行回顾的时候也会更加细致一些,还有很多地方需要学习。
路漫漫其修远兮。
更多推荐
vue antd 使用小结
发布评论