You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

171 line
5.3 KiB

  1. <template>
  2. <view>
  3. <!-- 循环按照 formValue 里的行来渲染表格块 -->
  4. <view v-for="(valueItem, valueIndex) in value" :key="valueIndex">
  5. <!-- 表格内部的组件 只有几种 (layer 类似 select,label 类似 title) -->
  6. <!-- 表格标题 除了第一个,后面的都有删除按钮 -->
  7. <view class="table-item padding-lr">
  8. <view class="table-item-title">{{ item.title }} (第{{ valueIndex + 1 }}行)</view>
  9. <view v-if="valueIndex !== 0 && edit" @click="tableDelete(valueIndex)" class="table-item-delete text-blue">
  10. 删除
  11. </view>
  12. </view>
  13. <!-- 循环按照 fieldsData 里面定义的列来渲染组件 -->
  14. <view v-for="tableItem of item.fieldsData" :key="tableItem.id">
  15. <!-- 标题文字 label -->
  16. <l-input
  17. v-if="tableItem.type === 'label'"
  18. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  19. :title="tableItem.name"
  20. disabled
  21. />
  22. <!-- 文字输入框 input (text) -->
  23. <l-input
  24. v-else-if="tableItem.type === 'input'"
  25. @input="setTableValue(`${valueIndex}.${tableItem.field}`, $event)"
  26. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  27. :disabled="!edit"
  28. :required="Boolean(tableItem.verify)"
  29. :title="tableItem.name"
  30. />
  31. <!-- 单选和选择 radio select -->
  32. <l-select
  33. v-else-if="tableItem.type === 'radio' || tableItem.type === 'select'"
  34. @input="setTableValue(`${valueIndex}.${tableItem.field}`, $event)"
  35. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  36. :required="Boolean(tableItem.verify)"
  37. :range="tableItem.__sourceData__"
  38. :title="tableItem.name"
  39. :disabled="!edit"
  40. />
  41. <!-- 弹层选择器 layer -->
  42. <l-layer-picker
  43. v-else-if="tableItem.type === 'layer'"
  44. @input="layerSetTableValue(valueIndex, $event, tableItem.__sourceData__)"
  45. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  46. :required="Boolean(tableItem.verify)"
  47. :readonly="!edit"
  48. :title="tableItem.name"
  49. :source="tableItem.__sourceData__.source"
  50. :layerData="tableItem.__sourceData__.layerData"
  51. />
  52. <!-- 时间 datetime / time -->
  53. <l-datetime-picker
  54. v-else-if="tableItem.type === 'datetime' && tableItem.datetime === 'datetime'"
  55. @input="setTableValue(`${valueIndex}.${tableItem.field}`, $event)"
  56. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  57. :required="Boolean(tableItem.verify)"
  58. :disabled="!edit"
  59. :title="tableItem.name"
  60. />
  61. <!-- 日期 datetime / date -->
  62. <l-date-picker
  63. v-else-if="tableItem.type === 'datetime' && tableItem.datetime !== 'datetime'"
  64. @input="setTableValue(`${valueIndex}.${tableItem.field}`, $event)"
  65. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  66. :required="Boolean(tableItem.verify)"
  67. :disabled="!edit"
  68. :title="tableItem.name"
  69. />
  70. <!-- 多选 checkbox -->
  71. <l-checkbox-picker
  72. v-else-if="tableItem.type === 'checkbox'"
  73. @input="setTableValue(`${valueIndex}.${tableItem.field}`, $event)"
  74. :value="getTableValue(`${valueIndex}.${tableItem.field}`)"
  75. :readonly="!edit"
  76. :range="tableItem.__sourceData__"
  77. :required="Boolean(tableItem.verify)"
  78. :title="tableItem.name"
  79. />
  80. </view>
  81. </view>
  82. <!-- 添加表格按钮 -->
  83. <view
  84. v-if="edit"
  85. @click="tableAdd()"
  86. class="bg-white flex flex-wrap justify-center align-center solid-bottom margin-bottom"
  87. >
  88. <view class="add-btn text-blue padding">+ 添加一行表格</view>
  89. </view>
  90. </view>
  91. </template>
  92. <script>
  93. import get from 'lodash/get'
  94. import set from 'lodash/set'
  95. export default {
  96. name: 'l-customform-table',
  97. props: {
  98. item: { type: Object, required: true },
  99. value: { type: Array, required: true },
  100. edit: { type: Boolean, default: true }
  101. },
  102. methods: {
  103. // 设置表单数据的方法
  104. setTableValue(path, value) {
  105. const newVal = this.COPY(this.value)
  106. set(newVal, path, value)
  107. this.$emit('input', newVal)
  108. },
  109. // 获取表单数据的方法
  110. getTableValue(path) {
  111. return get(this.value, path)
  112. },
  113. // 弹层,可能一次性设置多个字段
  114. layerSetTableValue(tableIndex, layerValue, layerInfo) {
  115. const newVal = this.COPY(this.value)
  116. const layerData = layerInfo.layerData || []
  117. layerData.forEach(({ name, value }) => {
  118. set(newVal, `${tableIndex}.${value}`, layerValue[name] || '')
  119. })
  120. this.$emit('input', newVal)
  121. },
  122. // 删除表格行
  123. tableDelete(tableIndex) {
  124. const newVal = this.value.filter((t, i) => i !== tableIndex)
  125. this.$emit('input', newVal)
  126. },
  127. // 添加表格行
  128. tableAdd() {
  129. const newVal = [...this.value, this.COPY(this.item.__defaultItem__)]
  130. this.$emit('input', newVal)
  131. }
  132. }
  133. }
  134. </script>
  135. <style lang="less" scoped>
  136. .table-item {
  137. display: flex;
  138. align-items: center;
  139. justify-content: space-between;
  140. font-size: 14px;
  141. height: 30px;
  142. .table-item-action {
  143. cursor: pointer;
  144. }
  145. }
  146. .add-btn {
  147. text-align: center;
  148. line-height: 1em;
  149. }
  150. </style>