ZaiZai 1 年之前
父節點
當前提交
10c7d19684
共有 1 個文件被更改,包括 256 次插入1 次删除
  1. 256 1
      src/components/table-form/table-form.vue

+ 256 - 1
src/components/table-form/table-form.vue

@@ -1,10 +1,265 @@
 <template>
+    <div
+        :id="`table-form-item-${keyId}`" v-loading="isLoading" :class="!isTableForm ? 'no-scroll-bar' : ''"
+        :style="tableFormStyle" class="hc-table-form-data-item"
+    >
+        <el-scrollbar v-if="isScroll" class="table-form-item-scrollbar">
+            <div :id="`table-form-${keyId}`" class="hc-excel-table-form" @click.capture="excelTableFormClick" />
+        </el-scrollbar>
+        <div v-else :id="`table-form-${keyId}`" class="hc-excel-table-form" @click.capture="excelTableFormClick" />
+        <hc-empty v-if="!isTableForm" :src="notableform" :title="noTips" />
+    </div>
 </template>
 
 <script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+import HTableForm from '~src/plugins/HTableForm'
+import notableform from '~src/assets/view/notableform.svg'
+import { isString } from 'js-fast-way'
 
+//初始
+const props = defineProps({
+    pkey: [String, Number],
+    noTip: {
+        type: [String, Number],
+        default: '暂无表单数据',
+    },
+    html: String,
+    form: {
+        type: Object,
+        default: () => ({}),
+    },
+    loading: Boolean,
+    scroll: {
+        type: Boolean,
+        default: true,
+    },
+    height: {
+        type: String,
+        default: '100%',
+    },
+    width: {
+        type: String,
+        default: 'auto',
+    },
+})
+
+//事件
+const emit = defineEmits(['rightTap', 'render', 'excelBodyTap'])
+//初始变量
+const keyId = ref(props.pkey)
+const noTips = ref(props.noTip)
+const isScroll = ref(props.scroll)
+const isLoading = ref(props.loading)
+
+//表单数据
+const excelHtml = ref(props.html)
+const excelForm = ref(props.form)
+
+//样式
+const tableFormApp = ref(null)
+const tableFormVM = ref(null)
+const tableFormStyle = ref('')
+const isTableForm = ref(false)
+
+//监听
+watch(() => [
+    props.pkey, props.noTip, props.scroll, props.loading, props.width, props.height,
+], ([pkey, tip, scroll, loading, width, height]) => {
+    keyId.value = pkey
+    noTips.value = tip
+    isScroll.value = scroll
+    isLoading.value = loading
+    setItemStyle(width, height)
+})
+
+//html变动
+watch(() => props.html, (html) => {
+    excelHtml.value = html
+    setExcelHtml()
+})
+
+//深度监听变动的对象数据
+watch(() => props.form, (val) => {
+    excelForm.value = val
+    //console.log('表单数据变动', val)
+    setPickerKey()
+    setFormData(val)
+}, { deep: true })
+
+//渲染完成
+onMounted(() => {
+    setItemStyle(props.width, props.height)
+    setPickerKey()
+    getExcelHtml()
+})
+
+
+//设置样式
+const setItemStyle = (width, height) => {
+    tableFormStyle.value = `width: ${width}; height: ${height};`
+}
+
+//表单被点击
+const excelTableFormClick = () => {
+    emit('excelBodyTap', keyId.value)
+}
+
+//获取已填写的数据
+const setPickerKey = () => {
+    HTableForm.setPickerKey(excelForm.value)
+}
+
+const setExcelHtml = () => {
+    setPickerKey()
+    //先卸载
+    if (tableFormApp.value) {
+        tableFormApp.value?.unmount()
+        tableFormApp.value = null
+        nextTick(() => {
+            getExcelHtml()
+        })
+    } else {
+        getExcelHtml()
+    }
+}
+
+//获取模板标签数据
+const getExcelHtml = () => {
+    const pkeyId = keyId.value
+    const temp = isString(excelHtml.value) ? excelHtml.value : ''
+    if (temp && pkeyId) {
+        //渲染表单
+        isTableForm.value = true
+        const { app, vm } = HTableForm.createForm({
+            template: temp,
+            tableForm: excelForm.value,
+            appId: `#table-form-${pkeyId}`,
+            onFormDataChange: (form) => {
+                excelForm.value = form
+                emit('render', form)
+            },
+            onRight: () => {
+                console.log('onRight')
+            },
+            onBlur: () => {
+                console.log('onBlur')
+            },
+            onLeftClick: () => {
+                console.log('onLeftClick')
+            },
+        })
+        tableFormApp.value = app
+        tableFormVM.value = vm
+        excelForm.value.isRenderForm = true
+        emit('render', excelForm.value)
+    } else {
+        isTableForm.value = false
+        excelForm.value.isRenderForm = false
+        emit('render', excelForm.value)
+    }
+}
+
+//获取表单数据
+const getFormData = () => {
+    return excelForm.value
+}
+
+//设置表单数据
+const setFormData = (data) => {
+    excelForm.value = data
+    tableFormVM.value?.setFormData(excelForm.value)
+}
+
+//卸载渲染
+const unmountHtml = () => {
+    if (tableFormApp.value) {
+        tableFormApp.value?.unmount()
+    }
+}
+
+// 暴露出去
+defineExpose({
+    getFormData,
+    setFormData,
+    setExcelHtml,
+    unmountHtml,
+})
 </script>
 
-<style scoped lang="scss">
+<style lang="scss">
+//插入特殊字符弹窗的输入框
+.hc-table-form-data-item .hc-excel-table-form td,
+.hc-table-form-data-item .hc-excel-table-form td .el-input .el-input__wrapper .el-input__inner,
+.el-form-item.special-form-item .el-form-item__content .el-input .el-input__wrapper .el-input__inner {
+    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;
+}
 
+.hc-table-form-data-item {
+    position: relative;
+    padding: 12px;
+    height: 100%;
+    overflow: hidden;
+    background-color: white;
+    &.no-scroll-bar .el-scrollbar {
+        display: none;
+    }
+    .hc-excel-table-form {
+        position: relative;
+        display: flex;
+        padding: 10px;
+        justify-content: center;
+        td {
+            position: relative;
+            padding: 6px;
+            background-clip: padding-box;
+            .el-input {
+                clear: both;
+                color: #606266;
+                border-radius: 3px;
+                height: $initials;
+                background-color: #ffffff !important;
+                .el-input__wrapper {
+                    background-color: inherit;
+                    caret-color: var(--el-color-primary);
+                }
+                .el-input__suffix-inner {
+                    width: 18px;
+                }
+            }
+            //焦点
+            .el-input .el-input__wrapper.is-focus, .el-input .el-input__wrapper:hover {
+                box-shadow: 0 0 0 1.5px var(--el-input-focus-border-color) inset;
+                background-color: #eddac4;
+            }
+            //公式
+            &[gscolor] {
+                .el-input {
+                    background-color: #dcdcdc !important;
+                }
+            }
+            //文本选中颜色
+            .el-input .el-input__wrapper input {
+                &::selection {
+                    background: var(--el-color-primary-light-9);
+                    color: var(--el-color-primary);
+                }
+                &::-moz-selection {
+                    background: var(--el-color-primary-light-9);
+                    color: var(--el-color-primary);
+                }
+            }
+        }
+        //列合并的单元格
+        td[rowspan] {
+            height: $initials;
+        }
+        //非输入框颜色
+        td:not([titlexx]), td[titlexx*=''],
+        td:not([title]), td[title*=''] {
+            background-color: white !important;
+            user-select: none;
+        }
+    }
+}
 </style>