当前位置:   article > 正文

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

element弹出表单

不知道怎么描述这个东西了。。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. <template>
  2. <div>
  3. <el-form
  4. size="small"
  5. :model="inputForm"
  6. ref="inputForm"
  7. v-loading="loading"
  8. :disabled="formReadOnly"
  9. label-width="120px"
  10. >
  11. <el-row :gutter="15">
  12. <el-col :span="12">
  13. <el-form-item label="关联合同" prop="associatedContracts" :rules="[]">
  14. <ContractSelect
  15. :value="inputForm.associatedContracts"
  16. @getInfo="getContranct"
  17. />
  18. </el-form-item>
  19. </el-col>
  20. </el-row>
  21. </el-form>
  22. </div>
  23. </template>
  24. <script>
  25. import ContractSelect from '@/components/contractSelect/index.vue'
  26. export default {
  27. data() {
  28. return {
  29. title: '',
  30. method: '',
  31. visible: false,
  32. loading: false,
  33. inputForm: {
  34. id: '',
  35. associatedContracts: '', // 关联合同
  36. },
  37. }
  38. },
  39. components: { ContractSelect },
  40. methods: {
  41. // 关联合同
  42. getContranct(selections) {
  43. this.inputForm.associatedContracts = selections.map(item => item.id).join(',')
  44. }
  45. }
  46. }
  47. </script>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/104838
推荐阅读
相关标签
  

闽ICP备14008679号