8
0

table-form.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <template>
  2. <div
  3. :id="`table-form-item-${keyId}`" v-loading="isLoading" :class="!isTableForm ? 'no-scroll-bar' : ''"
  4. :style="tableFormStyle" class="hc-table-form-data-item"
  5. >
  6. <el-scrollbar v-if="isScroll" class="table-form-item-scrollbar">
  7. <div :id="`table-form-${keyId}`" class="hc-excel-table-form" @click.capture="excelTableFormClick" />
  8. </el-scrollbar>
  9. <div v-else :id="`table-form-${keyId}`" class="hc-excel-table-form" @click.capture="excelTableFormClick" />
  10. <hc-empty v-if="!isTableForm" :src="notableform" :title="noTips" />
  11. </div>
  12. </template>
  13. <script setup>
  14. import { nextTick, onMounted, ref, watch } from 'vue'
  15. import HTableForm from '~src/plugins/HTableForm'
  16. import notableform from '~src/assets/view/notableform.svg'
  17. import { isString } from 'js-fast-way'
  18. //初始
  19. const props = defineProps({
  20. pkey: [String, Number],
  21. noTip: {
  22. type: [String, Number],
  23. default: '暂无表单数据',
  24. },
  25. html: String,
  26. form: {
  27. type: Object,
  28. default: () => ({}),
  29. },
  30. loading: Boolean,
  31. scroll: {
  32. type: Boolean,
  33. default: true,
  34. },
  35. height: {
  36. type: String,
  37. default: '100%',
  38. },
  39. width: {
  40. type: String,
  41. default: 'auto',
  42. },
  43. })
  44. //事件
  45. const emit = defineEmits(['rightTap', 'render', 'excelBodyTap'])
  46. //初始变量
  47. const keyId = ref(props.pkey)
  48. const noTips = ref(props.noTip)
  49. const isScroll = ref(props.scroll)
  50. const isLoading = ref(props.loading)
  51. //表单数据
  52. const excelHtml = ref(props.html)
  53. const excelForm = ref(props.form)
  54. //样式
  55. const tableFormApp = ref(null)
  56. const tableFormVM = ref(null)
  57. const tableFormStyle = ref('')
  58. const isTableForm = ref(false)
  59. //监听
  60. watch(() => [
  61. props.pkey, props.noTip, props.scroll, props.loading, props.width, props.height,
  62. ], ([pkey, tip, scroll, loading, width, height]) => {
  63. keyId.value = pkey
  64. noTips.value = tip
  65. isScroll.value = scroll
  66. isLoading.value = loading
  67. setItemStyle(width, height)
  68. })
  69. //html变动
  70. watch(() => props.html, (html) => {
  71. excelHtml.value = html
  72. setExcelHtml()
  73. })
  74. //深度监听变动的对象数据
  75. watch(() => props.form, (val) => {
  76. excelForm.value = val
  77. //console.log('表单数据变动', val)
  78. setPickerKey()
  79. setFormData(val)
  80. }, { deep: true })
  81. //渲染完成
  82. onMounted(() => {
  83. setItemStyle(props.width, props.height)
  84. setPickerKey()
  85. getExcelHtml()
  86. })
  87. //设置样式
  88. const setItemStyle = (width, height) => {
  89. tableFormStyle.value = `width: ${width}; height: ${height};`
  90. }
  91. //表单被点击
  92. const excelTableFormClick = () => {
  93. emit('excelBodyTap', keyId.value)
  94. }
  95. //获取已填写的数据
  96. const setPickerKey = () => {
  97. HTableForm.setPickerKey(excelForm.value)
  98. }
  99. const setExcelHtml = () => {
  100. setPickerKey()
  101. //先卸载
  102. if (tableFormApp.value) {
  103. tableFormApp.value?.unmount()
  104. tableFormApp.value = null
  105. nextTick(() => {
  106. getExcelHtml()
  107. })
  108. } else {
  109. getExcelHtml()
  110. }
  111. }
  112. //获取模板标签数据
  113. const getExcelHtml = () => {
  114. const pkeyId = keyId.value
  115. const temp = isString(excelHtml.value) ? excelHtml.value : ''
  116. if (temp && pkeyId) {
  117. //渲染表单
  118. isTableForm.value = true
  119. const { app, vm } = HTableForm.createForm({
  120. template: temp,
  121. tableForm: excelForm.value,
  122. appId: `#table-form-${pkeyId}`,
  123. onFormDataChange: (form) => {
  124. excelForm.value = form
  125. emit('render', form)
  126. },
  127. onRight: () => {
  128. console.log('onRight')
  129. },
  130. onBlur: () => {
  131. console.log('onBlur')
  132. },
  133. onLeftClick: () => {
  134. console.log('onLeftClick')
  135. },
  136. })
  137. tableFormApp.value = app
  138. tableFormVM.value = vm
  139. excelForm.value.isRenderForm = true
  140. emit('render', excelForm.value)
  141. } else {
  142. isTableForm.value = false
  143. excelForm.value.isRenderForm = false
  144. emit('render', excelForm.value)
  145. }
  146. }
  147. //获取表单数据
  148. const getFormData = () => {
  149. return excelForm.value
  150. }
  151. //设置表单数据
  152. const setFormData = (data) => {
  153. excelForm.value = data
  154. tableFormVM.value?.setFormData(excelForm.value)
  155. }
  156. //卸载渲染
  157. const unmountHtml = () => {
  158. if (tableFormApp.value) {
  159. tableFormApp.value?.unmount()
  160. }
  161. }
  162. // 暴露出去
  163. defineExpose({
  164. getFormData,
  165. setFormData,
  166. setExcelHtml,
  167. unmountHtml,
  168. })
  169. </script>
  170. <style lang="scss">
  171. //插入特殊字符弹窗的输入框
  172. .hc-table-form-data-item .hc-excel-table-form td,
  173. .hc-table-form-data-item .hc-excel-table-form td .el-input .el-input__wrapper .el-input__inner,
  174. .el-form-item.special-form-item .el-form-item__content .el-input .el-input__wrapper .el-input__inner {
  175. font-family: "hc-eudc", hc-sans, 宋体, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
  176. }
  177. .hc-table-form-data-item {
  178. position: relative;
  179. padding: 12px;
  180. height: 100%;
  181. overflow: hidden;
  182. background-color: white;
  183. &.no-scroll-bar .el-scrollbar {
  184. display: none;
  185. }
  186. .hc-excel-table-form {
  187. position: relative;
  188. display: flex;
  189. padding: 10px;
  190. justify-content: center;
  191. td {
  192. position: relative;
  193. padding: 6px;
  194. background-clip: padding-box;
  195. .el-input {
  196. clear: both;
  197. color: #606266;
  198. border-radius: 3px;
  199. height: $initials;
  200. background-color: #ffffff !important;
  201. .el-input__wrapper {
  202. background-color: inherit;
  203. caret-color: var(--el-color-primary);
  204. }
  205. .el-input__suffix-inner {
  206. width: 18px;
  207. }
  208. }
  209. //焦点
  210. .el-input .el-input__wrapper.is-focus, .el-input .el-input__wrapper:hover {
  211. box-shadow: 0 0 0 1.5px var(--el-input-focus-border-color) inset;
  212. background-color: #eddac4;
  213. }
  214. //公式
  215. &[gscolor] {
  216. .el-input {
  217. background-color: #dcdcdc !important;
  218. }
  219. }
  220. //文本选中颜色
  221. .el-input .el-input__wrapper input {
  222. &::selection {
  223. background: var(--el-color-primary-light-9);
  224. color: var(--el-color-primary);
  225. }
  226. &::-moz-selection {
  227. background: var(--el-color-primary-light-9);
  228. color: var(--el-color-primary);
  229. }
  230. }
  231. }
  232. //列合并的单元格
  233. td[rowspan] {
  234. height: $initials;
  235. }
  236. //非输入框颜色
  237. td:not([titlexx]), td[titlexx*=''],
  238. td:not([title]), td[title*=''] {
  239. background-color: white !important;
  240. user-select: none;
  241. }
  242. }
  243. }
  244. </style>