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

这篇具有很好参考价值的文章主要介绍了基于Element-ui 表单弹窗列表选择封装。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

大致的效果图就是: 

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

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

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

这里我们要考虑的就是:

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

使用: 

组件默认是多选,可以传入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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于element-ui的年份范围选择器

    下载对应的代码到本地 文件地址,以下是我的目录结构,我将下载的文件放到了src/components下。 全局引入或者局部引入使用 全局引入 局部引入 调用方法,下面的参数和element-ui原有el-date-picker的api保持不变 日期限制处理(禁用),下面我以我这边的需求为例, 选择的年份需等

    2024年02月07日
    浏览(52)
  • 基于element-ui封装上传图片到腾讯云Cos组件

    组件需求 上传图片到腾讯云Cos服务器 可以显示传入的图片地址 可以删除传入的图片地址 可以上传图片到云服务器 上传到腾讯云之后,可以返回图片地址,显示 上传成功之后,可以回调成功函数 需要使用借助一个插件,帮助我们上传图片资源到腾讯云Cos 使用element的el-upl

    2023年04月17日
    浏览(91)
  • uniapp 微信小程序 自定义弹框+picker下拉选择列表+输入表单:拒绝-选择理由弹窗

    效果: 1、template 2、data: 3、methods: 4、style

    2024年01月20日
    浏览(63)
  • 基于Vue和Element-UI自定义分组以及分组全选Select 选择器

    上一篇博文我们已经实现了基于Vue和Element-UI中Select 选择器的分组全选以及样式修改问题, 但是在分组方面我们是用了element-ui 自带的 使用el-option-group对备选项进行分组,它的label属性为分组名 的功能,但是出来的效果样式很难自定义,就算是魔改element的样式也有一些改不了

    2023年04月08日
    浏览(51)
  • 基于Vue+Element-Ui开发的月日组件,可以选择月份和天数小插件(新版本)

    最近有粉丝在使用的过程中发现不能满足自己项目上的需求,评论说不支持 placeholder 以及更改输入框大小 size ,所以又赶紧更新了一个版本,之前是1.0.7,现在新版本为1.1.0,点击查看之前的老版本 本组件是基于Vue和Element-ui,因Element官方组件库没有可以选择月份和天数的组

    2023年04月19日
    浏览(75)
  • 关闭element UI的弹窗,再次打开显示表单验证提示

    打开弹窗,没有填写任何信息,点击保存按钮,触发了表单的验证提示,没有进行任何操作,点击【关闭按钮】或者【取消按钮】关闭弹窗,再次打开弹窗,仍然显示表单的验证提示信息,   解决方法: 给el-dialog添加@close事件,给取消按钮添加点击事件,在事件中对表单进

    2024年02月15日
    浏览(42)
  • element-ui 动态表单

    背景:朋友入职新公司,做项目重构,根据后端返回表单内容,动态生成表单,于是自己实现了下,哪里写的不好,欢迎各位提建议: 因为开关和多选框默认值是非空字符串,所以在created生命周期单独处理了下

    2024年02月11日
    浏览(85)
  • element-ui 表单校验・大全

    element-ui 官网 element-ui 表单校验的规则如下:

    2024年02月08日
    浏览(60)
  • 基于vue element-ui 封装上传图片组件 功能:上传,删除,预览,上传图片水印,拖拽排序,上传进度条等

    我们在开发后台时肯定避免不了上传图片的功能 例如: 上传图片回显 上传完成 : 预览查看 , 删除等 如果是图片列表,还可能让你拖动图片排序 有的后台项目可能要给图片添加水印,添加标记 有的后台可能要炫酷一点 添加进度条功能 现在我们要完成上面的一系列功能,这里我

    2024年02月16日
    浏览(60)
  • element-ui表单自定义校验

    1.问题描述 项目开发过程中,遇到表单校验,这次的校验规则比较严,element-ui表单自带的校验完全解决不了问题。 2.解决方法 使用elementui表单校验中的自定义校验,validUsername是自定义的校验方法名称 2.1 定义表单校验: 2.2 自定义校验方法: 注意:方法中一定义要返回call

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包