main.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. <template>
  2. <div :class="b()">
  3. <el-card :class="b('box')">
  4. <div slot="header"
  5. :class="b('title')"
  6. v-if="vaildData(tableOption.title,false) || vaildData(tableOption.dateBtn,config.dateBtn)">
  7. <span>{{tableOption.title}}</span>
  8. <date-select @change="dateChange"
  9. v-if="vaildData(tableOption.dateBtn,config.dateBtn)"
  10. :default="vaildData(tableOption.dateDefault,config.dateDefault)"
  11. :size="vaildData(tableOption.dateSize,config.dateBtnSize)">
  12. </date-select>
  13. </div>
  14. <div :class="b('header')">
  15. <el-collapse-transition>
  16. <el-form :model="searchForm"
  17. :inline="true"
  18. ref="searchForm"
  19. v-if="searchShow && searchFlag">
  20. <!-- 循环列搜索框 -->
  21. <el-form-item :prop="column.prop"
  22. :label="column.label"
  23. v-for="(column,index) in columnOption"
  24. :key="index"
  25. v-if="column.search">
  26. <component :size="vaildData(tableOption.searchSize,config.searchComponentSize)"
  27. :is="getSearchType(column.type)"
  28. v-model="searchForm[column.prop]"
  29. :type="getType(column)"
  30. :props="column.props || tableOption.props"
  31. :format="column.format"
  32. :filterable="column.searchFilterable"
  33. :filter-method="column.searchFilterMethod"
  34. :value-format="column.valueFormat"
  35. :multiple="config.searchMultiple.includes(column.type) && vaildData(column.searchMmultiple,false)"
  36. clearable
  37. :placeholder="column.label"
  38. :dic="setDic(column.dicData,DIC[column.dicData])"></component>
  39. </el-form-item>
  40. <slot name="search"></slot>
  41. <el-form-item>
  42. <el-button type="primary"
  43. @click="searchChange"
  44. :icon="config.searchBtnIcon"
  45. :size="vaildData(tableOption.searchSize,config.searchBtnSize)">{{config.searchBtnTitle}}</el-button>
  46. <el-button @click="searchReset"
  47. :icon="config.emptyBtnIcon"
  48. :size="vaildData(tableOption.searchSize,config.emptyBtnSize)">{{config.emptyBtnTitle}}</el-button>
  49. <slot name="searchMenu"></slot>
  50. </el-form-item>
  51. </el-form>
  52. </el-collapse-transition>
  53. </div>
  54. <!-- 表格功能列 -->
  55. <div :class="b('menu')">
  56. <div :class="b('left')">
  57. <el-button type="primary"
  58. @click="rowAdd"
  59. :icon="config.addBtnIcon"
  60. :size="config.addBtnSize"
  61. v-if="vaildData(tableOption.addBtn,config.addBtn)">{{config.addBtnTitle}}</el-button>
  62. <slot name="menuLeft"></slot>
  63. </div>
  64. <div :class="b('right')">
  65. <slot name="menuRight"></slot>
  66. <el-button :icon="config.refreshBtnIcon"
  67. circle
  68. :size="config.refreshBtnSize"
  69. @click="refreshChange"
  70. v-if="vaildData(tableOption.refreshBtn,config.refreshBtn)"></el-button>
  71. <el-button :icon="config.columnBtnIcon"
  72. circle
  73. :size="config.columnBtnSize"
  74. @click="columnBox=true"
  75. v-if="vaildData(tableOption.columnBtn,config.columnBtn)"></el-button>
  76. <el-button :icon="config.searchboxBtnIcon"
  77. circle
  78. :size="config.searchboxBtnSize"
  79. @click="searchShow=!searchShow"
  80. v-if="searchFlag && vaildData(tableOption.searchBtn,config.searchBtn)"></el-button>
  81. </div>
  82. </div>
  83. <el-tag class="avue-tip"
  84. v-if="vaildData(tableOption.tip,config.tip) && tableOption.selection">
  85. <i class="el-icon-info avue-tip__icon">&nbsp;</i>
  86. <span class="avue-tip__name">
  87. {{config.tipStartTitle}}
  88. <span class="avue-tip__name--bold">{{selectLen}}</span> {{config.tipEndTitle}}
  89. </span>
  90. <span class="avue-tip__btn"
  91. @click="selectClear"
  92. v-if="vaildData(tableOption.selectClearBtn,config.selectClearBtn) && tableOption.selection">
  93. {{config.tipBtnTitle}}
  94. </span>
  95. </el-tag>
  96. <el-table :data="list"
  97. :highlight-current-row="tableOption.highlightCurrentRow"
  98. @current-change="currentRowChange"
  99. :stripe="tableOption.stripe"
  100. :show-header="tableOption.showHeader"
  101. :default-sort="tableOption.defaultSort"
  102. @row-click="rowClick"
  103. @row-dblclick="rowDblclick"
  104. :row-class-name="rowClassName"
  105. :max-height="tableOption.maxHeight"
  106. :height="tableOption.height=='auto'?(clientHeight - vaildData(tableOption.calcHeight,config.calcHeight)):tableOption.height"
  107. ref="table"
  108. :width="setPx(tableOption.width,config.width)"
  109. :border="tableOption.border"
  110. v-loading="tableLoading"
  111. @selection-change="selectionChange"
  112. @sort-change="sortChange">
  113. <!-- 折叠面板 -->
  114. <el-table-column type="expand"
  115. width="50"
  116. fixed="left"
  117. align="center"
  118. v-if="tableOption.expand">
  119. <template slot-scope="props">
  120. <slot :row="props.row"
  121. name="expand"></slot>
  122. </template>
  123. </el-table-column>
  124. <!-- 选择框 -->
  125. <el-table-column v-if="tableOption.selection"
  126. type="selection"
  127. width="50"
  128. fixed="left"
  129. align="center">
  130. </el-table-column>
  131. <!-- 序号 -->
  132. <el-table-column v-if="tableOption.index"
  133. :label="vaildData(tableOption.indexLabel,config.indexLabel)"
  134. type="index"
  135. width="50"
  136. :index="indexMethod"
  137. fixed="left"
  138. align="center">
  139. </el-table-column>
  140. <!-- 循环列 -->
  141. <el-table-column v-if="columnIndex.indexOf(column.prop)!=-1"
  142. v-for="(column,index) in columnOption"
  143. :prop="column.prop"
  144. :key="index"
  145. filter-placement="bottom-end"
  146. :filters="column.filters"
  147. :filter-method="column.filterMethod"
  148. :filter-multiple="vaildData(column.filterMultiple,config.filterMultiple)"
  149. :show-overflow-tooltip="column.overHidden"
  150. :min-width="column.minWidth"
  151. :sortable="column.sortable"
  152. :align="vaildData(column.align,tableOption.align)"
  153. :header-align="vaildData(column.headerAlign,tableOption.headerAlign)"
  154. :width="column.width"
  155. :label="column.label"
  156. :fixed="column.fixed">
  157. <crud-components v-if="column.children"
  158. :columnOption="column.children"
  159. :tableOption="tableOption"
  160. :tableForm="tableForm"
  161. :columnIndex="columnIndex"
  162. :DIC="DIC">
  163. <template slot-scope="scope"
  164. v-for="item in column.children"
  165. :slot="item.prop">
  166. <slot :row="scope.row"
  167. :dic="scope.dic"
  168. :label="scope.label"
  169. :name="item.prop"
  170. v-if="item.solt"></slot>
  171. </template>
  172. </crud-components>
  173. <template slot-scope="scope">
  174. <template v-if="cellEditFlag(scope.row,column)">
  175. <component size="small"
  176. :is="getSearchType(column.type)"
  177. v-model="tableForm[column.prop]"
  178. :type="getType(column)"
  179. clearable
  180. :placeholder="column.label"
  181. :dic="setDic(column.dicData,DIC[column.dicData])"></component>
  182. </template>
  183. <slot :row="scope.row"
  184. :dic="setDic(column.dicData,DIC[column.dicData])"
  185. :label="detail(scope.row,column)"
  186. :name="column.prop"
  187. v-else-if="column.solt"></slot>
  188. <template v-else>
  189. <span v-html="detail(scope.row,column)"></span>
  190. </template>
  191. </template>
  192. </el-table-column>
  193. <el-table-column fixed="right"
  194. v-if="vaildData(tableOption.menu,config.menu)"
  195. :label="config.menuTitle"
  196. :align="tableOption.menuAlign"
  197. :header-align="tableOption.menuHeaderAlign"
  198. :width="vaildData(tableOption.menuWidth,config.menuWidth)">
  199. <template slot-scope="scope">
  200. <el-dropdown split-button
  201. icon="el-icon-menu"
  202. type="primary"
  203. v-if="vaildData(tableOption.menuBtn,config.menuBtn)"
  204. :size="config.menuBtnSize">
  205. {{config.menuBtnTitle}}
  206. <el-dropdown-menu slot="dropdown">
  207. <el-dropdown-item v-if="vaildData(tableOption.viewBtn,true)"
  208. @click.native="rowView(scope.row,scope.$index)">{{config.viewBtnTitle}}</el-dropdown-item>
  209. <el-dropdown-item divided
  210. v-if="vaildData(tableOption.editBtn,true)"
  211. @click.native="rowEdit(scope.row,scope.$index)">{{config.editBtnTitle}}</el-dropdown-item>
  212. <el-dropdown-item divided
  213. v-if="vaildData(tableOption.delBtn,true)"
  214. @click.native="rowDel(scope.row,scope.$index)">{{config.delBtnTitle}}</el-dropdown-item>
  215. <slot name="dropMenu"
  216. :row="scope.row"
  217. :dic="scope.dic"
  218. :label="scope.label"
  219. :index="scope.$index"></slot>
  220. </el-dropdown-menu>
  221. </el-dropdown>
  222. <el-button type="primary"
  223. :icon="scope.row.$cellEdit?config.cellSaveBtnIcon:config.cellEditBtnIcon"
  224. :size="config.cellBtnSize"
  225. @click.stop="rowCell(scope.row,scope.$index)"
  226. v-if="vaildData(tableOption.cellBtn ,config.cellBtn)">{{scope.row.$cellEdit?config.cellSaveBtnTitle:config.cellEditBtnTitle}}</el-button>
  227. <el-button type="success"
  228. :icon="config.viewBtnIcon"
  229. :size="config.viewBtnSize"
  230. @click.stop="rowView(scope.row,scope.$index)"
  231. v-if="vaildData(tableOption.viewBtn,tableOption.menuBtn?false:config.viewBtn)">{{config.viewBtnTitle}}</el-button>
  232. <el-button type="primary"
  233. :icon="config.editBtnIcon"
  234. :size="config.editBtnSize"
  235. @click.stop="rowEdit(scope.row,scope.$index)"
  236. v-if="vaildData(tableOption.editBtn,tableOption.menuBtn?false:config.editBtn)">{{config.editBtnTitle}}</el-button>
  237. <el-button type="danger"
  238. :icon="config.delBtnIcon"
  239. :size="config.delBtnSize"
  240. @click.stop="rowDel(scope.row,scope.$index)"
  241. v-if="vaildData(tableOption.delBtn,tableOption.menuBtn?false:config.delBtn)">{{config.delBtnTitle}}</el-button>
  242. <slot name="menu"
  243. :row="scope.row"
  244. :dic="scope.dic"
  245. :label="scope.label"
  246. :index="scope.$index"></slot>
  247. </template>
  248. </el-table-column>
  249. </el-table>
  250. <!-- 分页 -->
  251. <div :class="b('pagination')"
  252. v-if="vaildData(tableOption.page,config.page) && listLen">
  253. <el-pagination :current-page.sync="page.currentPage"
  254. :background="vaildData(tableOption.pageBackground,config.pageBackground)"
  255. :page-size="page.pageSize"
  256. :page-sizes="page.pageSizes"
  257. @size-change="sizeChange"
  258. @current-change="currentChange"
  259. layout="total, sizes, prev, pager, next, jumper"
  260. :total="page.total"></el-pagination>
  261. </div>
  262. </el-card>
  263. <!-- 表单 -->
  264. <el-dialog lock-scroll
  265. :custom-class="vaildData(tableOption.customClass,config.customClass)"
  266. :fullscreen="vaildData(tableOption.formFullscreen,config.formFullscreen)"
  267. :modal-append-to-body="false"
  268. :append-to-body="true"
  269. :title="dialogTitle"
  270. :visible.sync="boxVisible"
  271. :width="vaildData(tableOption.formWidth,config.formWidth)"
  272. @close="hide">
  273. <div :class="b('dialog', ['overflow'])">
  274. <avue-form v-model="tableForm"
  275. ref="tableForm"
  276. :disabled="keyBtn"
  277. :uploadBefore="uploadBefore"
  278. :uploadAfter="uploadAfter"
  279. :option="formOption">
  280. <template slot-scope="scope"
  281. v-for="item in columnOption"
  282. :slot="item.prop">
  283. <slot :value="scope.value"
  284. :column="scope.column"
  285. :dic="scope.dic"
  286. :name="item.prop+'Form'"
  287. v-if="item.formsolt"></slot>
  288. </template>
  289. </avue-form>
  290. </div>
  291. <span slot="footer"
  292. class="dialog-footer">
  293. <slot name="menuForm"
  294. :row="tableForm"
  295. :type="boxType"></slot>
  296. <el-button type="primary"
  297. @click="rowUpdate"
  298. v-if="boxType=='edit'"
  299. :loading="keyBtn">{{config.updateBtnTitle}}</el-button>
  300. <el-button type="primary"
  301. @click="rowSave"
  302. :loading="keyBtn"
  303. v-else-if="boxType=='add'">{{config.saveBtnTitle}}</el-button>
  304. <el-button @click="closeDialog">{{config.cancelBtnTitle}}</el-button>
  305. </span>
  306. </el-dialog>
  307. <!-- 动态列 -->
  308. <el-dialog lock-scroll
  309. :modal-append-to-body="false"
  310. :append-to-body="true"
  311. :title="config.columnBtnTitle"
  312. :visible.sync="columnBox">
  313. <el-checkbox-group v-model="columnIndex">
  314. <el-row :span="24">
  315. <el-col :span="6"
  316. v-for="(item,index) in columnList"
  317. :key="index">
  318. <el-checkbox :label="item.prop">{{item.label}}</el-checkbox>
  319. </el-col>
  320. </el-row>
  321. </el-checkbox-group>
  322. </el-dialog>
  323. </div>
  324. </template>
  325. <script>
  326. import dateSelect from '../../date-select'
  327. import create from '../../utils/create';
  328. import crud from '../../mixins/crud.js';
  329. import column from '../../mixins/column.js';
  330. import crudComponents from './crud-components';
  331. import config from './config.js';
  332. import {
  333. validatenull
  334. } from '../../utils/validate.js';
  335. import {
  336. setTimeout
  337. } from 'timers';
  338. export default create({
  339. name: 'crud',
  340. mixins: [crud(), column()],
  341. components: {
  342. crudComponents,
  343. dateSelect
  344. },
  345. data () {
  346. return {
  347. clientHeight: document.documentElement.clientHeight,
  348. defaultForm: {
  349. tableForm: {},
  350. searchForm: {}
  351. },
  352. defaultParam: ['$index'],
  353. keyBtn: false,
  354. config: config,
  355. list: [],
  356. searchShow: true,
  357. searchForm: {},
  358. boxVisible: false,
  359. boxType: 'add',
  360. columnIndex: [],
  361. columnBox: false,
  362. columnList: [],
  363. tableForm: {},
  364. tableOption: {},
  365. tableFormRules: {},
  366. tableIndex: -1,
  367. tableSelect: []
  368. };
  369. },
  370. created () {
  371. // 初始化数据
  372. this.dataInit();
  373. // 初始化列
  374. this.columnInit();
  375. },
  376. computed: {
  377. dialogTitle () {
  378. const key = `${this.boxType}Title`;
  379. return this.tableOption[key] || this.config[key];
  380. },
  381. listLen () {
  382. return this.list.length !== 0
  383. },
  384. columnOption () {
  385. return this.tableOption.column || [];
  386. },
  387. selectLen () {
  388. return this.tableSelect ? this.tableSelect.length : 0;
  389. },
  390. searchSolt () {
  391. return this.vaildData(this.tableOption.searchsolt, false);
  392. },
  393. searchFlag () {
  394. if (this.searchSolt) return true;
  395. else return !validatenull(this.searchForm);
  396. },
  397. formOption () {
  398. let option = this.deepClone(this.tableOption);
  399. option.submitBtn = false;
  400. option.submitPostion = 'right';
  401. option.boxType = this.boxType;
  402. option.dicFlag = false;
  403. option.dicData = this.DIC;
  404. option.emptytBtn = false;
  405. return option;
  406. }
  407. },
  408. watch: {
  409. columnOption () {
  410. this.columnInit();
  411. },
  412. data () {
  413. this.dataInit();
  414. }
  415. },
  416. mounted () { },
  417. props: {
  418. value: {
  419. type: Object,
  420. default: () => {
  421. return {};
  422. }
  423. },
  424. beforeClose: Function,
  425. beforeOpen: Function,
  426. rowClassName: Function,
  427. uploadBefore: Function,
  428. uploadAfter: Function,
  429. page: {
  430. type: Object,
  431. default () {
  432. return {
  433. total: 0, // 总页数
  434. currentPage: 0, // 当前页数
  435. pageSize: 10, // 每页显示多少条
  436. pageSizes: [10, 20, 30, 40, 50, 100],
  437. background: true // 背景颜色
  438. };
  439. }
  440. },
  441. tableLoading: {
  442. type: Boolean,
  443. default: false
  444. },
  445. data: {
  446. type: Array,
  447. required: true,
  448. default: () => {
  449. return [];
  450. }
  451. }
  452. },
  453. methods: {
  454. closeDialog () {
  455. this.tableIndex = -1;
  456. this.tableForm = {};
  457. this.boxVisible = false;
  458. this.keyBtn = false;
  459. },
  460. selectClear () {
  461. this.$refs.table.clearSelection();
  462. },
  463. indexMethod (index) {
  464. return (index + 1) + (((this.page.currentPage || 1) - 1) * (this.page.pageSize || 10));
  465. },
  466. refreshChange () {
  467. this.$emit('refresh-change', {
  468. page: this.page,
  469. searchForm: this.searchForm
  470. });
  471. },
  472. rulesInit () {
  473. this.tableFormRules = {};
  474. this.columnOption.forEach(ele => {
  475. if (ele.rules) this.tableFormRules[ele.prop] = ele.rules;
  476. });
  477. },
  478. columnInit: function () {
  479. const safe = this;
  480. this.columnIndex = [];
  481. this.columnList = [];
  482. function addChild (list) {
  483. list.forEach((ele, index) => {
  484. const children = ele.children;
  485. if (!validatenull(children)) {
  486. safe.tableOption.columnBtn = false;
  487. addChild(children);
  488. }
  489. if (validatenull(ele.hide)) safe.columnIndex.push(ele.prop);
  490. if (ele.showClomnu !== false) {
  491. let obj = {
  492. label: ele.label,
  493. prop: ele.prop,
  494. index: index
  495. };
  496. safe.columnList.push(safe.deepClone(obj));
  497. }
  498. });
  499. }
  500. addChild(this.columnOption)
  501. },
  502. formVal () {
  503. Object.keys(this.value).forEach(ele => {
  504. this.tableForm[ele] = this.value[ele];
  505. })
  506. this.$emit('input', this.tableForm);
  507. },
  508. dataInit () {
  509. this.list = [].concat(this.data);
  510. //初始化序号
  511. this.list.forEach((ele, index) => {
  512. ele.$index = index;
  513. })
  514. },
  515. formInit () {
  516. this.defaultForm = this.formInitVal(this.columnOption);
  517. this.tableForm = this.deepClone(this.defaultForm.tableForm);
  518. this.searchForm = this.deepClone(this.defaultForm.searchForm);
  519. this.searchShow = this.vaildData(this.tableOption.searchShow, this.config.searchShow);
  520. this.formVal();
  521. },
  522. // 搜索清空
  523. searchReset () {
  524. this.$refs['searchForm'].resetFields();
  525. this.$emit('search-reset');
  526. },
  527. // 页大小回调
  528. sizeChange (val) {
  529. this.$emit('size-change', val);
  530. },
  531. //日期组件回调
  532. dateChange (val) {
  533. this.$emit('date-change', val);
  534. },
  535. // 页码回调
  536. currentChange (val) {
  537. this.$emit('current-change', val);
  538. },
  539. //设置单选
  540. currentRowChange (currentRow, oldCurrentRow) {
  541. this.$emit('current-row-change', currentRow, oldCurrentRow);
  542. },
  543. //设置多选选中
  544. setCurrentRow (row) {
  545. this.$refs.table.setCurrentRow(row);
  546. },
  547. // 选中实例
  548. toggleSelection (rows) {
  549. if (rows) {
  550. rows.forEach(row => {
  551. this.$refs.table.toggleRowSelection(row);
  552. });
  553. } else {
  554. this.$refs.table.clearSelection();
  555. }
  556. },
  557. // 选择回调
  558. selectionChange (val) {
  559. this.tableSelect = val;
  560. this.$emit('selection-change', this.tableSelect);
  561. },
  562. // 排序回调
  563. sortChange (val) {
  564. this.$emit('sort-change', val);
  565. },
  566. // 搜索回调
  567. searchChange () {
  568. this.$emit('search-change', this.searchForm);
  569. },
  570. // 行双击
  571. rowDblclick (row, event) {
  572. this.$emit('row-dblclick', row, event);
  573. },
  574. // 行单机
  575. rowClick (row, event, column) {
  576. this.$emit('row-click', row, event, column);
  577. },
  578. // 新增
  579. rowAdd () {
  580. this.boxType = 'add';
  581. this.tableForm = this.deepClone(this.defaultForm.tableForm);
  582. this.clearDefaultParam();
  583. this.$emit('input', this.tableForm);
  584. this.show();
  585. },
  586. rowCell (row, index) {
  587. if (row.$cellEdit) this.rowCellUpdate(row, index)
  588. else this.rowCellEdit(row, index)
  589. },
  590. // 单元格编辑
  591. rowCellEdit (row, index) {
  592. if (this.tableIndex != -1) {
  593. this.$message.error('先保存当前编辑的数据');
  594. return;
  595. }
  596. this.tableIndex = index;
  597. this.tableForm = this.deepClone(row);
  598. this.$emit('input', this.tableForm);
  599. row.$cellEdit = !row.$cellEdit;
  600. this.$set(this.list, index, row);
  601. },
  602. // 编辑
  603. rowEdit (row, index) {
  604. this.tableForm = this.deepClone(row);
  605. this.clearDefaultParam();
  606. this.$emit('input', this.tableForm);
  607. this.tableIndex = index;
  608. this.boxType = 'edit';
  609. this.show();
  610. },
  611. //查看
  612. rowView (row, index) {
  613. this.tableForm = this.deepClone(row);
  614. this.clearDefaultParam();
  615. this.$emit('input', this.tableForm);
  616. this.tableIndex = index;
  617. this.boxType = 'view';
  618. this.keyBtn = true;
  619. this.show();
  620. },
  621. rowCellUpdate (row, index) {
  622. const form = this.deepClone(this.tableForm);
  623. this.$emit('input', form);
  624. this.$emit(
  625. 'row-update',
  626. form,
  627. index,
  628. () => {
  629. row.$cellEdit = !row.$cellEdit;
  630. this.tableForm = {};
  631. this.tableIndex = -1;
  632. this.$set(this.list, index, form);
  633. }
  634. );
  635. },
  636. // 删除
  637. rowDel (row, index) {
  638. this.$emit('row-del', row, index);
  639. },
  640. // 保存
  641. rowSave () {
  642. this.$refs['tableForm'].validate().then(() => {
  643. this.keyBtn = true;
  644. this.$emit('row-save', this.deepClone(this.tableForm), this.closeDialog,
  645. () => {
  646. this.keyBtn = false;
  647. });
  648. });
  649. },
  650. // 更新
  651. rowUpdate () {
  652. this.$refs['tableForm'].validate().then(() => {
  653. this.keyBtn = true;
  654. const index = this.tableIndex;
  655. this.$emit(
  656. 'row-update',
  657. this.deepClone(this.tableForm),
  658. index,
  659. this.closeDialog,
  660. () => {
  661. this.keyBtn = false;
  662. }
  663. );
  664. });
  665. },
  666. // 显示表单
  667. show (cancel) {
  668. const callack = () => {
  669. if (cancel !== true) {
  670. this.$nextTick(() => {
  671. this.$refs['tableForm'].clearValidate();
  672. this.$refs['tableForm'].cascadeInit();
  673. });
  674. this.boxVisible = true;
  675. }
  676. };
  677. if (typeof this.beforeOpen === 'function') this.beforeOpen(callack, this.boxType);
  678. else callack();
  679. },
  680. // 隐藏表单
  681. hide (cancel) {
  682. const callack = () => {
  683. if (cancel !== false) {
  684. this.$refs['tableForm'].resetForm();
  685. this.$refs['tableForm'].clearValidate();
  686. }
  687. };
  688. if (typeof this.beforeClose === 'function') this.beforeClose(callack, this.boxType);
  689. else callack();
  690. },
  691. //清空多余字段
  692. clearDefaultParam () {
  693. this.defaultParam.forEach(ele => {
  694. delete this.tableForm[ele];
  695. })
  696. },
  697. resetForm () {
  698. this.$refs['tableForm'].resetForm();
  699. this.$emit('input', this.tableForm);
  700. }
  701. }
  702. });
  703. </script>