【Vue】可编辑表格与三级联动下拉
需求是给员工分配岗位,设计上是一人多岗的存在...
单位 —— 部门 —— 岗位 这样的层级
功能效果:
因为员工可以在不同的单位下任职岗位,所以这个每一个岗位都是一个独立
查询单位列表是固定的,但是每个单位下的部门不是固定的,每个单位下的部门下的岗位也是不一样的
每一行的下拉列表都是独立维护的
这种表格是和表单在一起的,所以存储逻辑是,直接清空以前的记录,根据提交的这份重新写库保存
可编辑表格的校验还是可以通过Form表单校验,TableData放在form表单对象里面
校验的prop属性是关联TableData的下标元素属性这样实现的,rules校验对象也是单独设置
注意下拉列表引用的集合都是下标元素里的(如果不是这样的联动列表,可以共用...)
<template>
<div>
<el-form :ref="formRef" :model="form" :rules="rules" label-width="135px" :inline="true" label-position="top" size="small">
<div class="location2">
<span style="font-weight: bolder">{{ form.emName + ' ' + form.emPhone }}</span>
<span>
<svg-icon icon-class="tj-icon" class="tj-icon" style="margin-right: 10px" @click="newEditRow" />
<svg-icon icon-class="sc-icon" class="tj-icon" @click="deleteEditRow" />
</span>
</div> <div>
<el-table :ref="editableTableRef" v-loading="loading" size="small" stripe highlight-current-row :data="form.tableData" :row-class-name="rowClassName" :row-style="rowStyle" @row-click="rowClick" @selection-change="handleSelectionChange">
<el-table-column align="center" type="index" width="50px" label="序号" />
<el-table-column prop="sysArCoId" min-width="160px" align="left" label="所属公司">
<template slot-scope="sc">
<el-form-item size="mini" :prop=" `tableData.${sc.$index}.sysArCoId` " :rules="rules.sysArCoId" :style="inputStyle">
<el-select v-model="sc.row.sysArCoId" :style="inputStyle" clearable placeholder="请选择" @change="selectCorpChange(sc.$index, sc.row)">
<el-option v-for="item in sc.row.corpList" :key="item.id" :label="item.coName" :value="item.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="sysArDeId" min-width="160px" align="left" label="所属部门">
<template slot-scope="sc">
<el-form-item size="mini" :prop=" `tableData.${sc.$index}.sysArDeId` " :rules="rules.sysArDeId" :style="inputStyle">
<el-select v-model="sc.row.sysArDeId" :style="inputStyle" clearable placeholder="请先选择所属公司" @change="selectDeptChange(sc.$index, sc.row)">
<el-option v-for="item in sc.row.deptList" :key="item.sysArDeId" :label="item.deName" :value="item.sysArDeId" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="poName" min-width="160px" align="left" label="岗位名称">
<template slot-scope="sc">
<el-form-item size="mini" :prop=" `tableData.${sc.$index}.sysArPoId` " :rules="rules.sysArPoId" :style="inputStyle">
<el-select v-model="sc.row.sysArPoId" :style="inputStyle" clearable placeholder="请先选择所属部门">
<el-option v-for="item in sc.row.postList" :key="item.id" :label="item.poName" :value="item.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
</el-table>
</div>
</el-form> <div class="drawer-bottom-bar">
<el-button type="primary" @click="submit">确定</el-button>
<el-button @click="closeEditDialog">取消</el-button>
</div>
</div>
</template>
Data属性和Prop属性:
查询这个列表的接口还是需要的,直接用翻页接口,就不要翻页组件,size变量直接写死999,足够展示了
单位列表是共用的,加载一次就可以给每一行用
props: {
form: {
type: Object,
required: true,
default() {
return {
tableData: []
}
}
}
},
data() {
return {
/* 列表变量 */
loading: false,
page: {
current: 0,
size: 999,
total: 0
}, /* 表单变量 */
formRef: 'currentRowRefKey',
editableTableRef: 'editableTableRefKey',
rules: {
sysArCoId: [
{ required: true, message: '请选择所属公司', trigger: 'change' }
],
sysArDeId: [
{ required: true, message: '请选择所属部门', trigger: 'change' }
],
sysArPoId: [
{ required: true, message: '请选择岗位名称', trigger: 'change' }
]
},
commonStyle: { width: '47%' },
inputStyle: { width: '100%' },
isUpdate: false,
selectionRow: [],
corpList: []
}
}
Method方法区内容:
一、解决新增操作时的问题
1、newEditRow 创建一条新行时,直接push这个行对象,这里初始化关联的员工ID和单位列表
2、deleteEditRow 删除编辑行,(用Splice方法跟据选中的下标来删除即可)这里用的是非复选框实现的选中方式 参考文章:http://www.javashuo.com/article/p-fbtbpqzn-bc.html
3、selectCorpChange 监听单位下拉事件,清空所有下级列表和选中的值,根据单位ID重新加载部门列表
4、selectDeptChange 监听部门下拉事件,同理
二、解决回显和编辑操作的问题
query 在加载列表的时候,同步阻塞执行加载方法把对应的列表放到行中
这里要注意的问题就是 异步执行顺序,一定要先等待单位列表加载完了,才能加载整个岗位的查询
methods: {
newEditRow() {
const row = {
sysArEmId: this.form.id,
sysArCoId: '',
sysArPoId: '',
sysArDeId: '',
corpList: [... this.corpList],
deptList: [],
postList: []
}
this.form.tableData.push(row)
},
deleteEditRow() {
const selectedLength = this.selectionRow.length
const totalLength = this.form.tableData.length
if (totalLength === 0) return this.$message.error('没有编辑行了')
if (selectedLength > 0) {
for (let i = selectedLength - 1; i >= 0; i--) {
this.form.tableData.splice(this.selectionRow[i].rowIndex, 1)
}
} else {
const lastOne = totalLength - 1
this.form.tableData.splice(lastOne, 1)
}
this.$refs[this.editableTableRef].clearSelection()
this.selectionRow = []
},
selectCorpChange(rowIdx, row) {
this.form.tableData[rowIdx].sysArDeId = ''
this.form.tableData[rowIdx].sysArPoId = ''
if (!row.sysArCoId) {
this.form.tableData[rowIdx].deptList = []
this.form.tableData[rowIdx].postList = []
}
this.loadDeptList(row.sysArCoId, rowIdx)
},
selectDeptChange(rowIdx, row) {
this.form.tableData[rowIdx].sysArPoId = ''
if (!row.sysArDeId) this.form.tableData[rowIdx].postList = []
this.loadPostList(row.sysArDeId, rowIdx)
},
async initialCorpList() {
const param = {}
const { data: res } = await getCompanyList(param)
this.corpList = res
},
async loadDeptList(val, rowIdx) {
const param = { sysArCoId: val }
const { data: res } = await getAllocatedDepartmentList(param)
this.form.tableData[rowIdx].deptList = res
},
async loadPostList(val, rowIdx) {
const param = { sysArDeId: val }
const { data: res } = await getSysArPostList(param)
this.form.tableData[rowIdx].postList = res
},
handleSizeChange(pageSize) {
this.page.size = pageSize
this.query()
},
handleCurrentChange(pageIndex) {
this.page.current = pageIndex
this.query()
},
searchPage() {
this.page.current = 0
this.page.total = 0
this.query()
},
async query() {
this.loading = true
const param = {
sysArEmId: this.form.id,
page: this.page
}
const { data: res, total } = await getEmployeePositionPage(param)
for (let i = 0; i < res.length; i++) {
res[i].corpList = [... this.corpList]
const { data: deptList } = await getAllocatedDepartmentList({ sysArCoId: res[i].sysArCoId })
res[i].deptList = deptList
const { data: postList } = await getSysArPostList({ sysArDeId: res[i].sysArDeId })
res[i].postList = postList
}
this.form.tableData = res
this.page.total = total
this.loading = false
},
closeEditDialog() {
this.$parent.$parent.closePostAssignDialog()
},
submit() {
this.$refs[this.formRef].validate(async valid => {
if (!valid) return
this.form.empoList = this.form.tableData
await assignEmployeePosition(this.form)
this.$message.success('分配任岗成功')
})
}
}
Created的执行:
created() {
this.initialCorpList().then(() => { this.searchPage() })
}
多个表格,拆分校验的问题:
例如下图这样,存在明细表和行程信息表,可以在一个实例的表单对象上面写
如果表格已经是拆分成其他组件来写的话,再花时间合并到一个文件中就很费劲
把可编辑表格按组件引入进来
key用来刷新组件
ref用来获取组件的属性
keyId是传递外键
在提交表单的时候,可以拆分两个Promise对象进行处理
执行每个表单的校验,通过则resolve,反之reject
在最后放入All方法按顺序执行,只有都通过校验,才会进入then方法执行提交
不要忘记把可编辑表格的数据放入提交的表单中
所以,后面存在若干个表格,依次类推实现
submit() {
const part1Validate = new Promise((resolve, reject) => {
this.$refs[this.formRef].validate(async valid => {
if (valid) resolve()
else reject()
})
}) const part2Validate = new Promise((resolve, reject) => {
const formTable = this.$refs['detailList'].$refs['currentRowRefKey']
formTable.validate(valid => {
if (valid) resolve()
else reject()
})
}) Promise.all([part1Validate, part2Validate]).then(async() => {
this.form.detailList = this.$refs['detailList'].form.tableData
if (this.isUpdate) {
await updateFinSpApply(this.form)
this.$message.success('更新成功')
this.$parent.$parent.searchPage()
} else {
const { data: res } = await addFinSpApply(this.form)
this.isUpdate = !!res
if (this.isUpdate) {
this.form.id = res.id
this.freshFlag = new Date().getTime() /* 刷新子组件的key属性,让子组件重新加载 */
this.$message.success('新增成功')
}
this.$parent.$parent.searchPage()
}
})
}
【Vue】可编辑表格与三级联动下拉的更多相关文章
- PHP用ajia代码写三级联动下拉
下面是我做三级联动下拉的步骤以及逻辑 第一步:先做一个省市区表格 第二步:建个PHP页面显示用我是在<body>里放<div>用来接收要显示的省市区表格信息,里面嵌入jquer ...
- 项目总结01:JSP mysql SpringMvc下中国省市县三级联动下拉框
JSP mysql SpringMvc下中国省市县三级联动下拉框 关键词 JSP mysql数据库 SpringMvc ajax Controller层 Service层 中国地区 省 ...
- Android实现三级联动下拉框 下拉列表spinner
Android实现(省.市.县)三级联动下拉框 下拉列表spinner 转载请注明出处: http://www.goteny.com/articles/2013/11/46.html http://w ...
- Web 1三级联动 下拉框 2添加修改删除 弹框
Web 三级联动 下拉框 using System; using System.Collections.Generic; using System.Linq; using System.Web; u ...
- JS年月日三级联动下拉框日期选择代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- jquery+html三级联动下拉框
jquery+html三级联动下拉框及详情页面加载时的select初始化问题 html写的三个下拉框,如下: <select name="ddlQYWZYJ" id=&q ...
- jquery+ligerform三级联动下拉框
如下为ligerform里的三级联动下拉框: var formData=[ {display:,width:,space:,type:"select",group:"区域 ...
- 用jsp实现省市区三级联动下拉
jsp+jquery实现省市区三级联动下拉 不少系统都需要实现省市区三级联动下拉,像人口信息管理.电子商务网站.会员管理等,都需要填写地址相关信息.而用ajax实现的无刷新省市区三级联动下拉则可以改善 ...
- JQ与AJAX 省市区三级联动下拉框
用于初学者学习基本的联动下拉框,废话不多说,见代码 首先看控制器里的3个下拉框对应代码: public ActionResult GetProvinceList() { ProvinceReposit ...
- php+ajax的三级联动下拉菜单
封装一个三级联动,就可以在任何页面进行引用了 先写个页面引用一下这个js <head> <meta http-equiv="Content-Type" conte ...
随机推荐
- Vue3组件通信方式
Vue3组件通信方式 不管是vue2还是vue3,组件通信方式很重要,不管是项目还是面试都是经常用到的知识点. 比如:vue2组件通信方式 props:可以实现父子组件.子父组件.甚至兄弟组件通信 自 ...
- Qt-udp通信
1 简介 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=61 说明:UDP是面向无连接的,客户端并不与服务器不建立连接,直接向服务器发送数据, ...
- react 网络请求 axios
react中通过npm来安装axios扩展 cnpm i -S axios 发起请求 import React, { Component } from 'react' import axios fro ...
- OAuth + Security - 错误收集
Could not decode JSON for additional information: BaseClientDetails 完整的错误输出如下: 2019-12-03 22:18:37.2 ...
- kali更换apt镜像
kali更换apt镜像 vim /etc/apt/sources.list 进来之后按i进入编辑模式,把其他的镜像#注释掉之后,加上新的镜像,然后esc退出编辑,按:输入wq保存并退出! 上面的办法不 ...
- springboot项目编译时,使用自定义注解类找不到符号
springboot项目编译时,使用自定义注解类找不到符号 Java项目编译时,使用自定义注解类找不到符号Spring-boot项目编辑器:idea问题:编译时找不到符号.项目中用到了自定义注解类.编 ...
- 实验一:Wireshark工具的使用
1.0 [实验目的] 了解Wireshark.TCP协议的概念,掌握Wireshark抓包工具的使用.FTP的搭建和登录,学会对Wireshark抓包结果的分析. 2.0[知识点] Wireshark ...
- 《Node.js+Vue.js+MangoDB全栈开发实战》已出版
<Node.js+Vue.js+MangoDB全栈开发实战> 图书购买地址: 京东:<Node.js+Vue.js+MangoDB全栈开发实战> 当当:<Node.js+ ...
- 降维(三)LLE与其他降维技术
LLE 局部线性嵌入,Locally Linear Embedding(LLE)是另一个功能强大的非线性降维(nonlinear dimensional reduction,NLDR)技术.它是一个流 ...
- Linux 内核:I2C子系统分析(1)基于子系统的驱动分析与实现
Linux 内核:I2C子系统分析(1)基于子系统的驱动分析与实现 背景 在学习高通平台的有关知识,看到一篇博客中介绍了GPIO模拟I2C设备,觉得挺有意思的. 看了看有关的实现,发现自己之前学习从L ...