不知道怎么描述这个东西了。。el-select下拉框大家都知道,但是下拉框只能选择一个,而且如果数据太多的话也不太容易选择,所以这里就是封装了组件包含对应的弹窗,就是能实现多选,而且列表也是分页展示的,选择完之后将对应的名称展示在文本框中,传给后端对应的用逗号隔开(用什么隔开都可以,跟后端商量)的id
大致的效果图就是:
这个关联合同就是我们封装的,输入框添加了disabled,不可编辑的,只能通过点击右侧弹窗来进行选择。点击弹窗之后的效果图:
这里我们要考虑的就是:
- 点击弹窗要展示出列表,进行选择,选择完之后点击确定要将对应的名称展示出来,多个就用逗号隔开,然后拿到对应id对应赋值。
- 第二就是回显的问题,当我们选择完之后再次点击弹窗,这时候要将我们已选择数据在列表上进行回显勾选,后台返回数据的时候,我们要根据id依次查询对应的数据,将对应的名称展示出来,然后点击弹窗的时候同样的进行数据回显勾选
这里直接附上代码:
index.vue
<template>
<div>
<el-input placeholder="请选择" :size="size" :disabled="inpDisabled" style="line-hight:40px" v-model="name" class="input-with-select">
<el-button slot="append" :disabled="btnDisabled" @click="showUserSelect" icon="el-icon-search"></el-button>
</el-input>
<!-- 合同列表 -->
<ContractSelectDialog
ref="contractSelect"
@doSubmit="selectionsToInput"
:selectData="selectData"
:single="single"
/>
</div>
</template>
<script>
import ContractSelectDialog from './contractSelectDialog'
import ContractService from '@/api/contract/ContractService'
export default {
data () {
return {
name: '',
selectData: [],
contractService: null
}
},
props: {
size: {
type: String,
default: 'small'
},
value: {
type: String,
default: ''
},
btnDisabled: {
type: Boolean,
default: false
},
inpDisabled: {
type: Boolean,
default: true
},
single: { // 是否启用单选
type: Boolean,
default: false
}
},
components: {
ContractSelectDialog
},
created () {
this.contractService = new ContractService()
},
watch: {
value: {
handler (newVal) {
this.selectData = []
if (newVal) {
newVal.split(',').forEach((id) => { // 回显拿数据
this.contractService.queryById(id).then(({data}) => {
if (data && data.id !== '') {
this.selectData.push(data)
}
})
})
}
},
immediate: true,
deep: false
},
selectData: {
handler (newVal) {
this.name = newVal.map(contract => contract.contractName).join(',')
},
immediate: false,
deep: false
}
},
methods: {
// 设置选中
selectionsToInput (selections) {
this.selectData = selections
this.$emit('getInfo', this.selectData)
},
// 显示列表
showUserSelect () {
this.$refs.contractSelect.init()
}
}
}
</script>
<style>
.el-form-item__content .el-input-group {
vertical-align: middle;
}
.el-tag + .el-tag {
margin-left: 5px;
margin-bottom: 5px;
}
</style>
对应的弹窗组件
<template>
<div>
<el-dialog
title="合同选择"
width="1000px"
:close-on-click-modal="false"
:append-to-body="true"
v-dialogDrag
class="userDialog"
:visible.sync="visible"
>
<el-container style="height: 500px">
<el-container>
<el-header style="text-align: left; font-size: 12px; height: 30px">
<el-form
size="small"
:inline="true"
ref="searchForm"
:model="searchForm"
@keyup.enter.native="refreshList()"
@submit.native.prevent
>
<el-form-item prop="contractNo">
<el-input
size="small"
v-model="searchForm.contractNo"
placeholder="合同编号"
clearable
></el-input>
</el-form-item>
<el-form-item prop="contracntName">
<el-input
size="small"
v-model="searchForm.contracntName"
placeholder="合同名称"
clearable
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="refreshList()"
size="small"
icon="el-icon-search"
>查询</el-button
>
<el-button
@click="resetSearch()"
size="small"
icon="el-icon-refresh-right"
>重置</el-button>
</el-form-item>
</el-form>
</el-header>
<el-main>
<el-table
:data="dataList"
v-loading="loading"
size="small"
border
ref="contractTable"
@select="handleSelectionChange"
height="calc(100% - 40px)"
style="width: 100%"
>
<el-table-column
type="selection"
header-align="center"
align="center"
width="50"
>
</el-table-column>
<el-table-column
prop="contractNo"
header-align="center"
align="left"
sortable="custom"
min-width="90"
label="合同编号"
>
</el-table-column>
<el-table-column
prop="contractName"
header-align="center"
align="left"
sortable="custom"
min-width="90"
label="合同名称"
>
</el-table-column>
<el-table-column
prop="contractAmount"
header-align="center"
align="left"
sortable="custom"
min-width="110"
label="合同金额"
>
</el-table-column>
<el-table-column
prop="oppositeCompany"
header-align="center"
align="center"
sortable="custom"
min-width="110"
label="对方单位"
>
</el-table-column>
<el-table-column
prop="signDate"
header-align="center"
align="left"
sortable="custom"
min-width="110"
label="签订时间"
>
</el-table-column>
</el-table>
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageNo"
:page-sizes="[5, 10, 50, 100]"
:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
>
</el-pagination>
</el-main>
</el-container>
</el-container>
<span slot="footer" class="dialog-footer">
<el-button
size="small"
@click="visible = false"
icon="el-icon-circle-close"
>关闭</el-button
>
<el-button
size="small"
type="primary"
icon="el-icon-circle-check"
@click="doSubmit()"
>确定</el-button
>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
searchForm: {
contractNo: '',
contracntName: ''
},
dataListAllSelections: [], // 所有选中的数据包含跨页数据
idKey: "id", // 标识列表数据中每一行的唯一键的名称(需要按自己的数据改一下)
dataList: [],
pageNo: 1,
pageSize: 10,
total: 0,
orders: [],
loading: false,
visible: false,
};
},
props: {
selectData: {
type: Array,
default: () => {
return [];
},
},
// 是否启用单选
single: {
type: Boolean,
default: false
}
},
methods: {
init() {
this.visible = true;
this.$nextTick(() => {
this.dataListAllSelections = JSON.parse(JSON.stringify(this.selectData));
this.resetSearch();
});
},
// 获取数据列表
refreshList() {
this.loading = true;
this.$http({
url: "/contract/list", // 自己的接口路径
method: "get",
params: {
current: this.pageNo,
size: this.pageSize,
orders: this.orders,
...this.searchForm,
},
}).then(({ data }) => {
this.dataList = data.records;
this.total = data.total;
this.pageNo = data.current;
this.loading = false;
this.$nextTick(() => {
this.setSelectRow();
});
});
},
// 每页数
sizeChangeHandle(val) {
this.pageSize = val;
this.pageNo = 1;
this.refreshList();
},
// 当前页
currentChangeHandle(val) {
this.pageNo = val;
this.refreshList();
},
// 排序
resetSearch() {
this.$refs.searchForm.resetFields();
this.refreshList();
},
// 选中数据
handleSelectionChange(selection, row) {
if (this.single && selection.length > 1) {
this.$refs.contractTable.clearSelection();
this.$refs.contractTable.toggleRowSelection(row);
}
this.dataListAllSelections = this.single ? [row] : selection
},
// 设置选中的方法
setSelectRow() {
this.$refs.contractTable.clearSelection();
if (!this.dataListAllSelections || this.dataListAllSelections.length <= 0) {
return;
}
for (let i = 0; i < this.dataList.length; i++) {
if (this.dataListAllSelections.some(item => item[this.idKey] == this.dataList[i][this.idKey])) {
// 设置选中,记住table组件需要使用ref="table"
this.$refs.contractTable.toggleRowSelection(this.dataList[i], true);
}
}
},
doSubmit() {
this.visible = false;
this.$emit("doSubmit", this.dataListAllSelections);
},
},
};
</script>
<style lang="scss">
.userDialog {
.el-dialog__body {
padding: 10px 0px 0px 10px;
color: #606266;
font-size: 14px;
word-break: break-all;
}
.el-main {
padding: 20px 20px 5px 20px;
.el-pagination {
margin-top: 5px;
}
}
}
</style>
使用: 文章来源:https://www.toymoban.com/news/detail-509827.html
组件默认是多选,可以传入single为true来启用单选文章来源地址https://www.toymoban.com/news/detail-509827.html
<template>
<div>
<el-form
size="small"
:model="inputForm"
ref="inputForm"
v-loading="loading"
:disabled="formReadOnly"
label-width="120px"
>
<el-row :gutter="15">
<el-col :span="12">
<el-form-item label="关联合同" prop="associatedContracts" :rules="[]">
<ContractSelect
:value="inputForm.associatedContracts"
@getInfo="getContranct"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import ContractSelect from '@/components/contractSelect/index.vue'
export default {
data() {
return {
title: '',
method: '',
visible: false,
loading: false,
inputForm: {
id: '',
associatedContracts: '', // 关联合同
},
}
},
components: { ContractSelect },
methods: {
// 关联合同
getContranct(selections) {
this.inputForm.associatedContracts = selections.map(item => item.id).join(',')
}
}
}
</script>
到了这里,关于基于Element-ui 表单弹窗列表选择封装的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!