Element+Vue实现动态表单(多个下拉框组件)
使用Vue+Element实现动态表单,可以下拉框进行增删(其他组件同理);元素嵌套,可以为某个下拉框元素设置子内容,支持可编辑表格,以及表格项目的排序和增减
·
需求
表单的内容为巡检计划,巡检计划可以选择多个巡检点位,每个巡检点位可以选择多个设备和对应操作。
最终效果图
- 点击加号图标增加一个下拉框
- 减号图标删除对应下拉框
- 下拉框备选项目相同
- 点击设置动作按钮,弹出可编辑表格,可以为该巡检点位设置多个动作
- 表格每行内容可编
- 设别名称下拉框和设备动作下拉框联动
- 操作按钮可对选项进行上下排序
代码实现
- 定义表单结构
<el-dialog :title="dialogTitle" :visible.sync="addDialogOpen" width="650px">
<div class="dialogForm">
<el-form :rules="rules" :model="addForm" ref="addForm" label-width="80px">
精简了无关代码
<el-form-item label="巡检内容" prop="patrolContent">
<div class="patrol-content">
<div class="point">
patrolContent元素个数控制下拉框的个数
循环渲染
每个div中包含一个下拉框、三个按钮
<div class="point-item"
v-for="(item,index) in addForm.patrolContent"
:key="index">
<div class="point-select">
<el-select v-model="item.point" class="selectItem" placeholder="请选择巡检点位(先选择地图)">
<el-option v-for="(item,index) in pointOptions"
:key="index"
:label="item.point_name"
:value="item.point_name">
</el-option>
</el-select>
<el-button size="mini" icon="el-icon-circle-plus" type="primary"
@click="addPointSelectItem(index)"/>
<el-button size="mini" icon="el-icon-remove" type="info"
@click="removePointSelectItem(index)"/>
<el-button size="mini" type="success"
@click="addDeviceAction(index)">设置动作
</el-button>
</div>
</div>
</div>
</div>
</el-form-item>
</el-form>
</div>
</el-dialog>
- 在data()中定义需要绑定的模板变量
addForm: {
patrolContent: [ //有多少个元素就渲染多少个下拉框
{
point: '', //点位
children: [], //对应每个点位的具体动作
}
]
}
- 定义增减下拉框的方法,实现动态增减
// 增加一个巡检点下拉框
addPointSelectItem(index) {
this.addForm.patrolContent.splice(index + 1, 0,
{
point: '',
children: [] //为空表示该点还未设置动作
}
)
},
// 删除一个巡检点下拉框
removePointSelectItem(index) {
if (this.addForm.patrolContent.length > 1) {
this.addForm.patrolContent.splice(index, 1)
}
},
至此,已经实现了下拉框的动态增减,且下拉框的选项之间互不影响。
接下来继续实现每个点位可以配置不同的动作。
- 定义打开动作弹窗的函数
这里在打开弹窗时,首先获取到所点击的下拉框索引值index,index代表了该元素在patrolContent中的位置,通过index获取表格要绑定的变量(该元素中的children)。
// 在该点位添加动作:打开弹窗
addDeviceAction(index) {
this.dialogTableData = this.addForm.patrolContent[index].children
this.deviceDialogOpen = true
}
- 定义动作弹窗
在弹窗打开时,表格会根据children中的元素进行渲染。
表格借助v-if
实现了编辑和确认编辑逻辑。
实现表格项的增删较为简单,增删children列表中的元素即可。
<el-dialog title="选择动作" :visible.sync="deviceDialogOpen" width="800px">
<div class="device-dialog">
<el-table :data="dialogTableData" border>
<el-table-column align="center" label="序号" type="index" width="50"/>
<el-table-column align="center" label="设备名称" prop="device">
<template v-slot="scope">
<el-select v-show="scope.row.edit" v-model="scope.row.device"
class="selectItem"
placeholder="选择设备"
@change="deviceSelectChange">
<el-option value="机械臂" label="机械臂"/>
<el-option value="升降台" label="升降台"/>
<el-option value="摄像头" label="摄像头"/>
</el-select>
<span v-show="!scope.row.edit">
{{ scope.row.device }}
</span>
</template>
</el-table-column>
<el-table-column align="center" label="设备动作" prop="action">
<template v-slot="scope">
<el-select v-show="scope.row.edit"
value-key="id"
v-model="scope.row.action"
class="selectItem"
placeholder="选择动作">
<el-option v-for="item in actionOptions"
:key="item.label"
:value="item.value"
:label="item.label">
</el-option>
</el-select>
<span v-show="!scope.row.edit">
{{ scope.row.action['action_name'] }}
</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="300">
<template v-slot="scope">
<el-button size="mini" type="primary" v-show="!scope.row.edit" @click="editAction(scope.row)">编辑
</el-button>
<el-button size="mini" type="success" v-show="scope.row.edit" @click="scope.row.edit=!scope.row.edit">
确定
</el-button>
<el-button size="mini" type="danger" @click="delAction(scope.$index)">删除</el-button>
<el-button size="mini" type="primary" plain @click="upMoveItem(scope.$index)"
icon="el-icon-caret-top"></el-button>
<el-button size="mini" type="warning" plain @click="downMoveItem(scope.$index)"
icon="el-icon-caret-bottom"></el-button>
</template>
</el-table-column>
</el-table>
<div class="footer">
<el-button type="warning" @click="addAction">添加</el-button>
<el-button type="primary" @click="deviceDialogOpen=false">确定</el-button>
</div>
</div>
</el-dialog>
- 实现表格项增减方法以及排序方法
// 弹窗-表格中增加一条数据
addAction() {
this.dialogTableData.push({
device: '', //绑定设备选项
action: '', //绑定设备动作选项
edit: true, // 默认可编辑
})
},
// 弹窗-删除表格中的一条数据
delAction(index) {
this.dialogTableData.splice(index, 1)
},
// 上移元素
upMoveItem(index) {
let table = this.dialogTableData
if (index !== 0) {
table[index] = table.splice(index - 1, 1, table[index])[0]
} else {
table.push(table.shift())
}
},
// 下移元素
downMoveItem(index) {
let table = this.dialogTableData
if (index !== table.length - 1) {
table[index] = table.splice(index + 1, 1, table[index])[0];
} else {
table.unshift(table.splice(index, 1)[0]);
}
},
总结
- 需要明确嵌套层级,vue组件要绑定到正确的变量上
- 为某个选项增加具体动作时,要获取到索引,这样才能根据索引获取该选项下的数据
- 选项的增删和排序都利用了
splice()
函数
更多推荐
已为社区贡献2条内容
所有评论(0)