一. 案例
- 校验金额
阐述:校验输入的金额是否正确。如下所示,点击【编辑图标】会变为input输入框当,输入金额。当输入框失去焦点时,若正确则调用接口更新金额且变为不可输入状态,否则返回不合法金额提示
<template>
<el-table v-loading="tableLoading" :data="dataList" row-key="id" @cell-click="cellClick" :row-class-name="tableRowClassName" :cell-class-name="tableCellClassName">
<el-table-column show-overflow-tooltip label="额度(元)">
<template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.amt > 0 ? `已设置无法更改` : `点击输入金额`" placement="top">
<div v-if="scope.row.index === rowIndex && scope.column.index === columnIndex">
<el-input ref='editInput' v-model="scope.row.amt" @blur="inputBlur(scope.row)" size="mini" placeholder="输入额度" clearable></el-input>
</div>
<div v-else>
<span> {{ scope.row.amt| parseFormatNum }} 元 </span>
<span v-show="scope.row.amt== 0"><i style="color:#409eff" class="el-icon-edit"></i></span>
</div>
<el-tooltip>
</template>
</el-table-column>
</el-table>
</template>
<script>
// 此处引入金额转换后的格式,引入的js文件放于文末
import { parseFormatNum } from "@/utils/index";
// 此处引入接口,更新对应金额
import {updateAmt} from "@api/xxx"
export default {
data() {
return {
rowIndex: -1, // 行索引
columnIndex: -1, // 列索引
tableLoading:false,
dataList:[],
query:{
pageSize:10,
pageNum:1
},
totalSize:0,
validAmt:null, // 校验金额:符合 true ; 不符合 false
}
},
mounted() {
this.fetchData()
},
filters: {
parseFormatNum(number) {
return parseFormatNum(number);
},
},
methods: {
/**
*初始化列表数据
/
fetchData(){
this.tableLoading = true
getList(this.query).then(res=>{
this.tableLoading = false
this.dataList = res.data.list
this.totalSize = res.data.total
})
},
/**
* 把每一行的索引加到行数据中
*/
tableRowClassName({ row, rowIndex }) {
row.index = rowIndex
},
/**
* 把每一列的索引加到列数据中
*/
tableCellClassName({ column, columnIndex }) {
column.index = columnIndex
},
/**
* 单元格被点击时会触发该事件
*/
cellClick(row, column) {
if (column.label == '额度(元)' && row.cancelVerificationLimit == 0) {
this.rowIndex = row.index
this.columnIndex = column.index
this.$nextTick(() => {
this.$refs['editInput'].focus()//没有自动聚焦效果的话可能是这里出现问题 需要打印出来看一下
})
}
},
/**
* 修改供应商免核销额度并校验金额
*/
inputBlur(row) {
const reg = /^[0-9,"."]{1,20}$/
this.validAmt = reg.test(row.cancelVerificationLimit)
if (this.validAmt && row.cancelVerificationLimit > 0) {
// 传一个主键id以及输入额度即可
updateAmt(row.id, row.amt).then(res => {
if (res.success) {
this.$notify.success({
title: this.$t("message.success"),
message: res.message
});
this.rowIndex = -1
this.columnIndex = -1
this.validAmt = false
}
})
} else {
this.validAmt = false
row.amt = 0
this.$message.error("请输入正确格式的金额")
return
}
},
},
}
</script>
- 校验时间
阐述:选择的时间是否小于当前时间,若是则选择后立即禁用
<template>
<table v-loading="tableLoading" :data="dataList" row-key="id" >
<el-table-column align="left" prop="time" label="时间">
<template
<el-tooltip class="item" effect="dark" :content="fittleTime(row.time)
? `已经启用 无法更改`
: `点击修改`
" placement="top">
<el-date-picker v-model="row.time" @change="updateTime(row)"
:disabled="fittleTime(row.time)" :picker-options="pickerOptions" value-format="yyyy-MM-dd"
size="mini" style="width: 150px" type="date" placeholder="选择日期时间">
</el-date-picker>
</el-tooltip>
</template>
</el-table-column>
</table>
</template>
<script>
// 引入对应接口
import {updateTime} from "@/api/xxx"
export default{
data(){
return{
tableLoading:false,
dataList:[],
query:{
pageSize:10,
pageNum:1
},
pickerOptions: {
disabledDate(time) {
return time.getTime() < Date.now();
}
},
}
},
mounted() {
this.fetchData()
},
methods: {
/**
*初始化列表数据
/
fetchData(){
this.tableLoading = true
getList(this.query).then(res=>{
this.tableLoading = false
this.dataList = res.data.list
this.totalSize = res.data.total
})
},
/**
* 判断是否禁用虚拟记账薄启用时间
* @param {Date} time
*/
fittleTime(time) {
if (time != null) {
let dbTime = new Date(time);
let nowTime = new Date();
return dbTime <= nowTime;
}
},
/**
* 修改供应商虚拟机账簿启用时间
*/
updateTime(row) {
if (!row.time) return this.$message.error("请选择启用时间");
updateTime(row.id, row.time).then(res => {
this.$message({
type: res.code == 200 ? "success" : "error",
message: res.message
});
});
},
}
}
</script>
- 校验不同层级所输入的内容
阐述:当一级下 无 二级子目录时就可直接添加表,若有允许先添加材料,再通过二级子目录添加表
<template>
<el-card>
// 表头
<el-row class="catelog-header" :gutter="20" :span="24">
<el-col v-for="item in catelogHeaderList" :key="item.id" class="catelog-sub-header" :span="item.span">
{{ item.title }}
</el-col>
</el-row>
<!--表单校验-->
<el-row style="margin-left: -10px; margin-right: -10px">
<el-form
ref="catelogSettingForm"
class="descriptions-form"
inline-message
:model="catelogUserForm"
:rules="catalogCollectionRules"
>
<!-- 一级目录 -->
<el-row
v-for="(item, index) in catelogUserForm.catelogSysList"
:key="item.id"
class="catelog-form-border"
>
<el-row class="catelog-align catelog-border">
<el-col :span="1" style="margin-left: 10px">
{{ (index + 1) | numberFilter }}
</el-col>
<el-col class="catelog-item-font" :span="7">
{{ item.catamanageName }}
// 判断是否添加材料(如图所示的 +)
<el-button
v-show="
(item.code == 'ARCHIVE_PERSON' &&
item.children.length == 0) ||
(item.children.length > 0 &&
item.children[0].code == 'ARCHIVE_TABLE')
"
size="mini"
style="margin-left: 10px"
type="text"
@click="handleAddCatelogUser(item)"
>
<vab-icon
icon="add-circle-fill"
style="font-size: 18px !important"
/>
</el-button>
</el-col>
</el-row>
<!-- 二级目录 -->
<vab-draggable
:data-id="`${item.id}`"
v-bind="dragOptions"
:disabled="disabledDrag"
:group="{
put: false,
}"
:list="item.children"
@end="onEnd"
>
<el-row
v-for="(childrenItem, childrenIndex) in item.children"
:key="childrenIndex"
class="children-item"
>
<el-row
v-if="childrenItem.code == 'ARCHIVE_PERSON'"
class="catelog-align"
:gutter="30"
>
<el-col
:span="1"
style="font-size: xx-small; margin-left: 10px"
>
<div v-if="childrenItem.code == 'ARCHIVE_PERSON'">
{{ index + 1 }} - {{ childrenIndex + 1 }}
</div>
<div v-else>
{{ childrenIndex + 1 }}
</div>
</el-col>
<el-col class="catelog-table-border" :span="7">
<el-form-item>
{{ childrenItem.catamanageName }}
<el-button
size="mini"
style="margin-left: 10px"
type="text"
@click="handleAddCatelogUser(childrenItem)"
>
<vab-icon
icon="add-circle-fill"
style="font-size: 18px !important"
/>
</el-button>
</el-form-item>
</el-col>
</el-row>
<div v-else style="cursor: move">
<el-row class="catelog-align" :gutter="30">
<el-col
:span="1"
style="font-size: xx-small; margin-left: 10px"
>
<div v-if="childrenItem.code == 'ARCHIVE_PERSON'">
{{ index + 1 }} - {{ childrenIndex + 1 }}
</div>
<div v-else>
{{ childrenIndex + 1 }}
</div>
</el-col>
<el-col class="catelog-table-border" :span="5">
<el-form-item>
{{ childrenItem.name }}
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item
:prop="`catelogSysList[${index}].children[${childrenIndex}].catamanageName`"
:rules="{
required: true,
message: '材料名称不能为空',
trigger: 'change',
}"
>
<el-input
v-model="childrenItem.catamanageName"
clearable
placeholder="请输入材料名称"
/>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item
:prop="`catelogSysList[${index}].children[${childrenIndex}].treeFormationTime`"
:rules="{
required: true,
message: '请使用 - 分割年月日分',
pattern:
/(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]$)/,
trigger: 'change',
}"
>
<el-input
v-model="childrenItem.treeFormationTime"
clearable
placeholder="示例:2023-01-01"
/>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item
:prop="`catelogSysList[${index}].children[${childrenIndex}].pagesNum`"
:rules="[
{
required: true,
message: '页数不能为空',
pattern: /^[1-9]\d*$/,
trigger: 'change',
},
]"
>
<el-input
v-model="childrenItem.pagesNum"
clearable
placeholder="页数"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item>
<el-input
v-model="childrenItem.remark"
clearable
placeholder="请输入备注"
/>
</el-form-item>
</el-col>
<el-col :span="2" style="text-align: center">
<el-form-item>
<el-button
icon="el-icon-view"
type="text"
@click="
handleDelete(
index,
childrenItem,
childrenIndex,
'del'
)
"
>
删除
</el-button>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 三级目录 -->
<vab-draggable
v-bind="dragOptions"
:data-id="`${
childrenItem.id + '-' + childrenItem.parentId
}`"
:list="childrenItem.children"
@end="onEnd"
>
<el-row
v-for="(innerItem, innerIndex) in childrenItem.children"
:key="innerItem.id"
class="catelog-align"
:gutter="30"
style="cursor: move; border-top: 1px solid #8eaac6"
>
<el-col
:span="1"
style="font-size: xx-small; margin-left: 10px"
>
<div>{{ innerIndex + 1 }}</div>
</el-col>
<el-col
:span="5"
style="
border-left: 1px solid #8eaac6;
padding-left: 10px !important;
"
>
<el-form-item style="padding-left: 10px !important">
{{ innerItem.name }}
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item
:prop="`catelogSysList[${index}].children[${childrenIndex}].children[${innerIndex}].catamanageName`"
:rules="{
required: true,
message: '材料名称不能为空',
trigger: 'change',
}"
>
<el-input
v-model="innerItem.catamanageName"
clearable
placeholder="请输入材料名称"
/>
</el-form-item>
</el-col>
<el-col :span="3">
<el-form-item
:prop="`catelogSysList[${index}].children[${childrenIndex}].children[${innerIndex}].treeFormationTime`"
:rules="{
required: true,
message: '请使用 - 将年月日分割',
pattern:
/(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]-([1][0-2]|0?[1-9])$)|(^[1-2][0-9][0-9][0-9]$)/,
trigger: 'change',
}"
>
<el-input
v-model="innerItem.treeFormationTime"
clearable
placeholder="示例:2023-01-01"
/>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item
:prop="`catelogSysList[${index}].children[${childrenIndex}].children[${innerIndex}].pagesNum`"
:rules="[
{
required: true,
message: '页数不能为空',
pattern: /^[1-9]\d*$/,
trigger: 'change',
},
]"
>
<el-input
v-model="innerItem.pagesNum"
clearable
placeholder="页数"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item>
<el-input
v-model="innerItem.remark"
clearable
placeholder="请输入备注"
/>
</el-form-item>
</el-col>
<el-col :span="2" style="text-align: center">
<el-form-item>
<el-button
icon="el-icon-view"
type="text"
@click="
handleDelete(
index,
innerItem,
childrenIndex,
innerIndex
)
"
>
删除
</el-button>
</el-form-item>
</el-col>
</el-row>
</vab-draggable>
</el-row>
</vab-draggable>
</el-row>
</el-form>
</el-row>
<ArchiveCatelogUserTable ref="catelogUser"/>
</el-card>
</template>
<script>
// 引入将阿拉伯数字转为中文的js文件
import { numberToChinese } from '@/utils/index'
// 允许同级目录进行拖拽排序
import VabDraggable from 'vuedraggable'
// 将拖拽后的排序重新更新
// 删除
import {updateSortById,remove} from "@/api/xxx"
export default{
props: {
archiveId: {
type: String,
default: '',
require: true,
},
},
filters: {
numberFilter(num) {
return numberToChinese(num)
},
},
components: {
VabDraggable,
},
computed: {
dragOptions() {
return {
animation: 600,
group: 'description',
}
},
},
data(){
return{
catelogHeaderList: [
{ id: 1, title: '类号', span: 1 },
{ id: 2, title: '类别名称', span: 5 },
{ id: 3, title: '材料', span: 5 },
{ id: 4, title: '材料形成时间 年 月 日', span: 3 },
{ id: 5, title: '页数', span: 2 },
{ id: 6, title: '备注', span: 6 },
{ id: 7, title: '操作', span: 2 },
],
catelogUserForm: {
catelogSysList: [],
},
catalogCollectionRules: {},
catelogSysLoading:false,
disabledDrag: false, // 是否禁止同级拖拽
}
},
mounted(){
this.fetchData()
},
methods:{
/**
* 获取catelogUser一级目录列表
*/
fetchData() {
this.catelogSysLoading = true
getMenyByArchiveId(this.archiveId).then((res) => {
this.catelogUserForm.catelogSysList = res.data
this.list = JSON.parse(JSON.stringify(res.data))
this.catelogSysLoading = false
})
},
/**
* 打开添加材料对话框,添加材料(此功能不详细赘述)
*/
handleAddCatelogUser(item) {
// this.$refs.catelogUser.showDetailDialog(item.id,item.catelogSysId,item.catamanageName)
},
/**
* 拖拽排序
* @param {Object} event
*/
onEnd(evt) {
//父级id
let parentId = evt.from.dataset.id
//找到父级所在的索引
let parentIi = this.catelogUserForm.catelogSysList.findIndex((e) => e.id == parentId)
//父级
let nowList = this.catelogUserForm.catelogSysList[parentIi]
let buhui = this.list[parentIi]
//当前拖动对象
// debugger
let nowItemId = evt.item._underlying_vm_.id
let nowIndex = nowList.children.findIndex((e) => e.id == nowItemId)
let flag = nowList.children[nowIndex].id == buhui.children[nowIndex].id
nowList.children.forEach((e, i) => {
e.sort = i + 1
})
if (!flag) {
updateSortById(nowList.children).then((res) => {
this.$baseMessage(res.msg, 'success')
this.fetchData()
})
}
},
/**
* 删除:保存/未保存到数据库()
*/
handleDelete(parentIndex, item, index, flag) {
if (item.id != null) {
this.$baseConfirm('您确定要删除当前项吗?', null, async () => {
const { msg } = await remove(item.id)
this.$baseMessage(msg, 'success')
await this.fetchData()
})
} else {
if (flag == 'del') {
this.catelogUserForm.catelogSysList.map((e) => {
if (e.id == item.parentId) {
this.catelogUserForm.catelogSysList[parentIndex].children.splice(index, 1)
}
})
} else {
this.catelogUserForm.catelogSysList.map((e) => {
e.children.map((r) => {
if (r.id == item.parentId) {
this.catelogUserForm.catelogSysList[parentIndex].children[index].children.splice(flag, 1)
}
})
})
}
}
},
}
}
</script>
数据格式如下
二. 引入文件
- 保留两位小数并且整数部分三位一个逗号分隔符的数字金钱标准表示法
export function parseFormatNum(number) {
let n = 2;
if (n != 0) {
n = n > 0 && n <= 20 ? n : 2;
}
if (number == null) number = 0;
number = parseFloat((number + "").replace(/[^\d\.-]/g, "")).toFixed(n) + "";
const sub_val = number
.split(".")[0]
.split("")
.reverse();
const sub_xs = number.split(".")[1];
let show_html = "";
for (let m = 0; m < sub_val.length; m++) {
show_html +=
sub_val[m] + ((m + 1) % 3 == 0 && m + 1 != sub_val.length ? "," : "");
}
if (n == 0) {
return show_html
.split("")
.reverse()
.join("");
} else {
return (
show_html
.split("")
.reverse()
.join("") +
"." +
sub_xs
);
}
}
- 阿拉伯数字转为汉字
export const numberToChinese = (num) => {
const changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] // changeNum[0] = "零"
const unit = ['', '十', '百']
num = parseInt(num)
const getWan = (temp) => {
const strArr = temp.toString().split('').reverse()
let newNum = ''
for (var i = 0; i < strArr.length; i++) {
newNum =
(i == 0 && strArr[i] == 0
? ''
: i > 0 && strArr[i] == 0 && strArr[i - 1] == 0
? ''
: changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) +
newNum
}
return newNum
}
const overWan = Math.floor(num / 100)
let noWan = num % 100
if (noWan.toString().length < 2) {
noWan = '0' + noWan
}
let strr = overWan ? getWan(overWan) + '百' + getWan(noWan) : getWan(num)
if (strr.split('')[0] == '一') {
if (num < 10) {
return strr.substring(0)
} else {
return strr.substring(1)
}
} else {
return overWan ? getWan(overWan) + '百' + getWan(noWan) : getWan(num)
}
}
三. 参考
- element+vue表格点击变成输入框并获取焦点(可编辑状态)
- el-table内表单校验