【Vue2 + ElementUI】el-table中校验表单

一. 案例

  1. 校验金额
    阐述:校验输入的金额是否正确。如下所示,点击【编辑图标】会变为input输入框当,输入金额。当输入框失去焦点时,若正确则调用接口更新金额且变为不可输入状态,否则返回不合法金额提示
bash 复制代码
<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>
  1. 校验时间
    阐述:选择的时间是否小于当前时间,若是则选择后立即禁用
bash 复制代码
<template>
	<table v-loading="tableLoading" :data="dataList" row-key="id" >
		  <el-table-column align="left" prop="time" label="时间">
            <template #default="{ row }">
              <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>
  1. 校验不同层级所输入的内容
    阐述:当一级下 无 二级子目录时就可直接添加表,若有允许先添加材料,再通过二级子目录添加表
bash 复制代码
<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>

数据格式如下

二. 引入文件

  1. 保留两位小数并且整数部分三位一个逗号分隔符的数字金钱标准表示法
bash 复制代码
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
    );
  }
}
  1. 阿拉伯数字转为汉字
bash 复制代码
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)
  }
}

三. 参考

  1. element+vue表格点击变成输入框并获取焦点(可编辑状态)
  2. el-table内表单校验
相关推荐
香蕉可乐荷包蛋3 小时前
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
前端·javascript·es6
未来之窗软件服务3 小时前
资源管理器必要性———仙盟创梦IDE
前端·javascript·ide·仙盟创梦ide
西哥写代码5 小时前
基于cornerstone3D的dicom影像浏览器 第十八章 自定义序列自动播放条
前端·javascript·vue
清风细雨_林木木5 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js
雪芽蓝域zzs5 小时前
JavaScript splice() 方法
开发语言·javascript·ecmascript
森叶6 小时前
Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
前端·javascript·electron
霸王蟹6 小时前
React 19 中的useRef得到了进一步加强。
前端·javascript·笔记·学习·react.js·ts
霸王蟹6 小时前
React 19版本refs也支持清理函数了。
前端·javascript·笔记·react.js·前端框架·ts
繁依Fanyi6 小时前
ColorAid —— 一个面向设计师的色盲模拟工具开发记
开发语言·前端·vue.js·编辑器·codebuddy首席试玩官
codelxy6 小时前
vue引用cesium,解决“Not allowed to load local resource”报错
javascript·vue.js