【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内表单校验
相关推荐
空中海19 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
空中海19 小时前
02 状态、Hooks、副作用与数据流
开发语言·javascript·ecmascript
abcnull20 小时前
传统的JavaWeb项目Demo快速学习!
java·servlet·elementui·vue·javaweb
空中海20 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js
杨超凡20 小时前
豆包收费了?我特么自己用“意念”搓了一个!
javascript
threelab21 小时前
Three.js 咖啡杯烟雾效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能
Heo21 小时前
14_React 中的更新队列 updateQueue
前端·javascript·面试
前端 贾公子21 小时前
解决浏览器端 globalThis is not defined 报错
前端·javascript·vue.js
之歆1 天前
DAY12_CSS3选择器全攻略 + 盒子新特性完全指南(下)
前端·javascript·css3