• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Element-ui 表单弹窗列表选择封装

武飞扬头像
会说法语的猪
帮助1

不知道怎么描述这个东西了。。el-select下拉框大家都知道,但是下拉框只能选择一个,而且如果数据太多的话也不太容易选择,所以这里就是封装了组件包含对应的弹窗,就是能实现多选,而且列表也是分页展示的,选择完之后将对应的名称展示在文本框中,传给后端对应的用逗号隔开(用什么隔开都可以,跟后端商量)的id

大致的效果图就是: 

学新通 

这个关联合同就是我们封装的,输入框添加了disabled,不可编辑的,只能通过点击右侧弹窗来进行选择。点击弹窗之后的效果图: 

学新通

这里我们要考虑的就是:

  1. 点击弹窗要展示出列表,进行选择,选择完之后点击确定要将对应的名称展示出来,多个就用逗号隔开,然后拿到对应id对应赋值。
  2. 第二就是回显的问题,当我们选择完之后再次点击弹窗,这时候要将我们已选择数据在列表上进行回显勾选,后台返回数据的时候,我们要根据id依次查询对应的数据,将对应的名称展示出来,然后点击弹窗的时候同样的进行数据回显勾选 

这里直接附上代码: 

index.vue 

  1.  
    <template>
  2.  
    <div>
  3.  
    <el-input placeholder="请选择" :size="size" :disabled="inpDisabled" style="line-hight:40px" v-model="name" class="input-with-select">
  4.  
    <el-button slot="append" :disabled="btnDisabled" @click="showUserSelect" icon="el-icon-search"></el-button>
  5.  
    </el-input>
  6.  
    <!-- 合同列表 -->
  7.  
    <ContractSelectDialog
  8.  
    ref="contractSelect"
  9.  
    @doSubmit="selectionsToInput"
  10.  
    :selectData="selectData"
  11.  
    :single="single"
  12.  
    />
  13.  
    </div>
  14.  
    </template>
  15.  
    <script>
  16.  
    import ContractSelectDialog from './contractSelectDialog'
  17.  
    import ContractService from '@/api/contract/ContractService'
  18.  
    export default {
  19.  
    data () {
  20.  
    return {
  21.  
    name: '',
  22.  
    selectData: [],
  23.  
    contractService: null
  24.  
    }
  25.  
    },
  26.  
    props: {
  27.  
    size: {
  28.  
    type: String,
  29.  
    default: 'small'
  30.  
    },
  31.  
    value: {
  32.  
    type: String,
  33.  
    default: ''
  34.  
    },
  35.  
    btnDisabled: {
  36.  
    type: Boolean,
  37.  
    default: false
  38.  
    },
  39.  
    inpDisabled: {
  40.  
    type: Boolean,
  41.  
    default: true
  42.  
    },
  43.  
    single: { // 是否启用单选
  44.  
    type: Boolean,
  45.  
    default: false
  46.  
    }
  47.  
    },
  48.  
    components: {
  49.  
    ContractSelectDialog
  50.  
    },
  51.  
    created () {
  52.  
    this.contractService = new ContractService()
  53.  
    },
  54.  
    watch: {
  55.  
    value: {
  56.  
    handler (newVal) {
  57.  
    this.selectData = []
  58.  
    if (newVal) {
  59.  
    newVal.split(',').forEach((id) => { // 回显拿数据
  60.  
    this.contractService.queryById(id).then(({data}) => {
  61.  
    if (data && data.id !== '') {
  62.  
    this.selectData.push(data)
  63.  
    }
  64.  
    })
  65.  
    })
  66.  
    }
  67.  
    },
  68.  
    immediate: true,
  69.  
    deep: false
  70.  
    },
  71.  
    selectData: {
  72.  
    handler (newVal) {
  73.  
    this.name = newVal.map(contract => contract.contractName).join(',')
  74.  
    },
  75.  
    immediate: false,
  76.  
    deep: false
  77.  
    }
  78.  
    },
  79.  
    methods: {
  80.  
    // 设置选中
  81.  
    selectionsToInput (selections) {
  82.  
    this.selectData = selections
  83.  
    this.$emit('getInfo', this.selectData)
  84.  
    },
  85.  
    // 显示列表
  86.  
    showUserSelect () {
  87.  
    this.$refs.contractSelect.init()
  88.  
    }
  89.  
    }
  90.  
    }
  91.  
    </script>
  92.  
    <style>
  93.  
    .el-form-item__content .el-input-group {
  94.  
    vertical-align: middle;
  95.  
    }
  96.  
    .el-tag .el-tag {
  97.  
    margin-left: 5px;
  98.  
    margin-bottom: 5px;
  99.  
    }
  100.  
    </style>
学新通

对应的弹窗组件 

  1.  
    <template>
  2.  
    <div>
  3.  
    <el-dialog
  4.  
    title="合同选择"
  5.  
    width="1000px"
  6.  
    :close-on-click-modal="false"
  7.  
    :append-to-body="true"
  8.  
    v-dialogDrag
  9.  
    class="userDialog"
  10.  
    :visible.sync="visible"
  11.  
    >
  12.  
    <el-container style="height: 500px">
  13.  
    <el-container>
  14.  
    <el-header style="text-align: left; font-size: 12px; height: 30px">
  15.  
    <el-form
  16.  
    size="small"
  17.  
    :inline="true"
  18.  
    ref="searchForm"
  19.  
    :model="searchForm"
  20.  
    @keyup.enter.native="refreshList()"
  21.  
    @submit.native.prevent
  22.  
    >
  23.  
    <el-form-item prop="contractNo">
  24.  
    <el-input
  25.  
    size="small"
  26.  
    v-model="searchForm.contractNo"
  27.  
    placeholder="合同编号"
  28.  
    clearable
  29.  
    ></el-input>
  30.  
    </el-form-item>
  31.  
    <el-form-item prop="contracntName">
  32.  
    <el-input
  33.  
    size="small"
  34.  
    v-model="searchForm.contracntName"
  35.  
    placeholder="合同名称"
  36.  
    clearable
  37.  
    ></el-input>
  38.  
    </el-form-item>
  39.  
    <el-form-item>
  40.  
    <el-button
  41.  
    type="primary"
  42.  
    @click="refreshList()"
  43.  
    size="small"
  44.  
    icon="el-icon-search"
  45.  
    >查询</el-button
  46.  
    >
  47.  
    <el-button
  48.  
    @click="resetSearch()"
  49.  
    size="small"
  50.  
    icon="el-icon-refresh-right"
  51.  
    >重置</el-button>
  52.  
    </el-form-item>
  53.  
    </el-form>
  54.  
    </el-header>
  55.  
    <el-main>
  56.  
    <el-table
  57.  
    :data="dataList"
  58.  
    v-loading="loading"
  59.  
    size="small"
  60.  
    border
  61.  
    ref="contractTable"
  62.  
    @select="handleSelectionChange"
  63.  
    height="calc(100% - 40px)"
  64.  
    style="width: 100%"
  65.  
    >
  66.  
    <el-table-column
  67.  
    type="selection"
  68.  
    header-align="center"
  69.  
    align="center"
  70.  
    width="50"
  71.  
    >
  72.  
    </el-table-column>
  73.  
    <el-table-column
  74.  
    prop="contractNo"
  75.  
    header-align="center"
  76.  
    align="left"
  77.  
    sortable="custom"
  78.  
    min-width="90"
  79.  
    label="合同编号"
  80.  
    >
  81.  
    </el-table-column>
  82.  
    <el-table-column
  83.  
    prop="contractName"
  84.  
    header-align="center"
  85.  
    align="left"
  86.  
    sortable="custom"
  87.  
    min-width="90"
  88.  
    label="合同名称"
  89.  
    >
  90.  
    </el-table-column>
  91.  
    <el-table-column
  92.  
    prop="contractAmount"
  93.  
    header-align="center"
  94.  
    align="left"
  95.  
    sortable="custom"
  96.  
    min-width="110"
  97.  
    label="合同金额"
  98.  
    >
  99.  
    </el-table-column>
  100.  
    <el-table-column
  101.  
    prop="oppositeCompany"
  102.  
    header-align="center"
  103.  
    align="center"
  104.  
    sortable="custom"
  105.  
    min-width="110"
  106.  
    label="对方单位"
  107.  
    >
  108.  
    </el-table-column>
  109.  
    <el-table-column
  110.  
    prop="signDate"
  111.  
    header-align="center"
  112.  
    align="left"
  113.  
    sortable="custom"
  114.  
    min-width="110"
  115.  
    label="签订时间"
  116.  
    >
  117.  
    </el-table-column>
  118.  
    </el-table>
  119.  
    <el-pagination
  120.  
    @size-change="sizeChangeHandle"
  121.  
    @current-change="currentChangeHandle"
  122.  
    :current-page="pageNo"
  123.  
    :page-sizes="[5, 10, 50, 100]"
  124.  
    :page-size="pageSize"
  125.  
    :total="total"
  126.  
    layout="total, sizes, prev, pager, next, jumper"
  127.  
    >
  128.  
    </el-pagination>
  129.  
    </el-main>
  130.  
    </el-container>
  131.  
    </el-container>
  132.  
    <span slot="footer" class="dialog-footer">
  133.  
    <el-button
  134.  
    size="small"
  135.  
    @click="visible = false"
  136.  
    icon="el-icon-circle-close"
  137.  
    >关闭</el-button
  138.  
    >
  139.  
    <el-button
  140.  
    size="small"
  141.  
    type="primary"
  142.  
    icon="el-icon-circle-check"
  143.  
    @click="doSubmit()"
  144.  
    >确定</el-button
  145.  
    >
  146.  
    </span>
  147.  
    </el-dialog>
  148.  
    </div>
  149.  
    </template>
  150.  
    <script>
  151.  
    export default {
  152.  
    data() {
  153.  
    return {
  154.  
    searchForm: {
  155.  
    contractNo: '',
  156.  
    contracntName: ''
  157.  
    },
  158.  
    dataListAllSelections: [], // 所有选中的数据包含跨页数据
  159.  
    idKey: "id", // 标识列表数据中每一行的唯一键的名称(需要按自己的数据改一下)
  160.  
    dataList: [],
  161.  
    pageNo: 1,
  162.  
    pageSize: 10,
  163.  
    total: 0,
  164.  
    orders: [],
  165.  
    loading: false,
  166.  
    visible: false,
  167.  
    };
  168.  
    },
  169.  
    props: {
  170.  
    selectData: {
  171.  
    type: Array,
  172.  
    default: () => {
  173.  
    return [];
  174.  
    },
  175.  
    },
  176.  
    // 是否启用单选
  177.  
    single: {
  178.  
    type: Boolean,
  179.  
    default: false
  180.  
    }
  181.  
    },
  182.  
    methods: {
  183.  
    init() {
  184.  
    this.visible = true;
  185.  
    this.$nextTick(() => {
  186.  
    this.dataListAllSelections = JSON.parse(JSON.stringify(this.selectData));
  187.  
    this.resetSearch();
  188.  
    });
  189.  
    },
  190.  
    // 获取数据列表
  191.  
    refreshList() {
  192.  
    this.loading = true;
  193.  
    this.$http({
  194.  
    url: "/contract/list", // 自己的接口路径
  195.  
    method: "get",
  196.  
    params: {
  197.  
    current: this.pageNo,
  198.  
    size: this.pageSize,
  199.  
    orders: this.orders,
  200.  
    ...this.searchForm,
  201.  
    },
  202.  
    }).then(({ data }) => {
  203.  
    this.dataList = data.records;
  204.  
    this.total = data.total;
  205.  
    this.pageNo = data.current;
  206.  
    this.loading = false;
  207.  
    this.$nextTick(() => {
  208.  
    this.setSelectRow();
  209.  
    });
  210.  
    });
  211.  
    },
  212.  
    // 每页数
  213.  
    sizeChangeHandle(val) {
  214.  
    this.pageSize = val;
  215.  
    this.pageNo = 1;
  216.  
    this.refreshList();
  217.  
    },
  218.  
    // 当前页
  219.  
    currentChangeHandle(val) {
  220.  
    this.pageNo = val;
  221.  
    this.refreshList();
  222.  
    },
  223.  
    // 排序
  224.  
    resetSearch() {
  225.  
    this.$refs.searchForm.resetFields();
  226.  
    this.refreshList();
  227.  
    },
  228.  
    // 选中数据
  229.  
    handleSelectionChange(selection, row) {
  230.  
    if (this.single && selection.length > 1) {
  231.  
    this.$refs.contractTable.clearSelection();
  232.  
    this.$refs.contractTable.toggleRowSelection(row);
  233.  
    }
  234.  
    this.dataListAllSelections = this.single ? [row] : selection
  235.  
    },
  236.  
    // 设置选中的方法
  237.  
    setSelectRow() {
  238.  
    this.$refs.contractTable.clearSelection();
  239.  
    if (!this.dataListAllSelections || this.dataListAllSelections.length <= 0) {
  240.  
    return;
  241.  
    }
  242.  
    for (let i = 0; i < this.dataList.length; i ) {
  243.  
    if (this.dataListAllSelections.some(item => item[this.idKey] == this.dataList[i][this.idKey])) {
  244.  
    // 设置选中,记住table组件需要使用ref="table"
  245.  
    this.$refs.contractTable.toggleRowSelection(this.dataList[i], true);
  246.  
    }
  247.  
    }
  248.  
    },
  249.  
    doSubmit() {
  250.  
    this.visible = false;
  251.  
    this.$emit("doSubmit", this.dataListAllSelections);
  252.  
    },
  253.  
    },
  254.  
    };
  255.  
    </script>
  256.  
    <style lang="scss">
  257.  
    .userDialog {
  258.  
    .el-dialog__body {
  259.  
    padding: 10px 0px 0px 10px;
  260.  
    color: #606266;
  261.  
    font-size: 14px;
  262.  
    word-break: break-all;
  263.  
    }
  264.  
    .el-main {
  265.  
    padding: 20px 20px 5px 20px;
  266.  
    .el-pagination {
  267.  
    margin-top: 5px;
  268.  
    }
  269.  
    }
  270.  
    }
  271.  
    </style>
学新通

使用: 

组件默认是多选,可以传入single为true来启用单选

  1.  
  2.  
    <template>
  3.  
    <div>
  4.  
    <el-form
  5.  
    size="small"
  6.  
    :model="inputForm"
  7.  
    ref="inputForm"
  8.  
    v-loading="loading"
  9.  
    :disabled="formReadOnly"
  10.  
    label-width="120px"
  11.  
    >
  12.  
    <el-row :gutter="15">
  13.  
    <el-col :span="12">
  14.  
    <el-form-item label="关联合同" prop="associatedContracts" :rules="[]">
  15.  
    <ContractSelect
  16.  
    :value="inputForm.associatedContracts"
  17.  
    @getInfo="getContranct"
  18.  
    />
  19.  
    </el-form-item>
  20.  
    </el-col>
  21.  
    </el-row>
  22.  
    </el-form>
  23.  
    </div>
  24.  
    </template>
  25.  
    <script>
  26.  
    import ContractSelect from '@/components/contractSelect/index.vue'
  27.  
    export default {
  28.  
    data() {
  29.  
    return {
  30.  
    title: '',
  31.  
    method: '',
  32.  
    visible: false,
  33.  
    loading: false,
  34.  
    inputForm: {
  35.  
    id: '',
  36.  
    associatedContracts: '', // 关联合同
  37.  
    },
  38.  
    }
  39.  
    },
  40.  
    components: { ContractSelect },
  41.  
    methods: {
  42.  
    // 关联合同
  43.  
    getContranct(selections) {
  44.  
    this.inputForm.associatedContracts = selections.map(item => item.id).join(',')
  45.  
    }
  46.  
    }
  47.  
    }
  48.  
    </script>
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggijef
系列文章
更多 icon
同类精品
更多 icon
继续加载