vue3封装表格嵌套表单问题汇总

发布于:2024-07-02 ⋅ 阅读:(11) ⋅ 点赞:(0)

1.插槽嵌套多层数据ui组件怎么使用
思路:插槽具名【区分】后暴露传递,这个为神魔要区分,因为封装组件表格列表项也有插槽
步骤一:表单插槽暴露

    <ElForm
      class="form-search"
      :model="formParams"
      ref="formRef"
      :style="fixedStyle"
    >
      <div
        :class="['form-serach-item-box']"
        v-for="(item, index) of (disposeFormItemList || []).slice(
          0,
          formItemNum
        )"
        :key="index"
        v-show="!item.show"
        :grid="fiexedNum"
      >
        <!-- 搜索插槽 -->
        <ElFormItem
          class="form-item-input"
          v-if="item.type !== '%' && item.type == 'slot'"
          colon
          :label="item.label"
          :prop="item.prop"
        >
          <!-- 插槽自定义检索组件 -->
          <slot
            v-if="item.slotName"
            :name="item.slotName"
            v-bind="{
              field: item.prop,
              model: formParams,
            }"
          ></slot>
        </ElFormItem>
      </div>
    </ElForm>

步骤2:表格组件区分暴露插槽

  <div class="table-warpper_lat" :style="fixedTableHeight">
    <C_BasicFormSearch
      ref="_formSearchRef"
      v-if="formItemList"
      :id="_searchFormUuid"
      :formParams="initFormParams!"
      :formItemList="list"
      @e_dispatchGetDataFn="e_dispatchGetDataFn"
      @e_changeParms="emits('e_changeParams', $event)"
      @changeFlodSearch="calcTableClientHeight"
      @reset="emits('reset')"
      :formSearchInputHistoryString="formSearchInputHistoryString"
      :class="_isShowSearch ? 'show-search' : 'none-search'"
      :formItemNum="formItemNum"
      :fiexedNum="fiexedNum"
      :isShowSearchMore="isShowSearchMore"
      :cardBorder="cardBorder"
      :useOutReset="useOutReset"
      :drawerSize="drawerSize"
      :searchFormJustify="searchFormJustify"
      :searchFormLabelPosition="searchFormLabelPosition"
    >
      <template
        #[replaceFormSlotKey(item)]="data"
        v-for="item in getFormSlotKeys"
      >
        <slot :name="item" v-bind="data || {}"></slot>
      </template>
    </C_BasicFormSearch>
    <ElCard
      :shadow="shadow"
      :class="{ 'table-warpper': true, 'table-no-border': !cardBorder }"
      :id="_tableUuid"
    >
      <!-- TODO: 表格 -->
      <ElTable
        :row-key="rowkey"
        v-bind="$attrs"
        ref="_tableRef"
        :border="border"
        :data="_tableData"
        :tree-props="props.treeProps"
        :class="props.className"
        :header-cell-style="setHeaderStyle"
        v-loading="_isLoading"
        @selection-change="selectChange"
        @select="select"
        @select-all="selectAll"
        @cell-mouse-enter="cellMouseEnter"
        @cell-mouse-leave="cellMouseLeave"
        @cell-click="cellClick"
        @cell-dblclick="cellDblclick"
        @cell-contextmenu="cellContextmenu"
        @row-click="rowClick"
        @row-contextmenu="rowContextmenu"
        @row-dblclick="rowDblclick"
        @header-click="headerClick"
        @header-contextmenu="headerContextmenu"
        @sort-change="sortChange"
        @filter-change="filterChange"
        @current-change="currentChange"
        @header-dragend="headerDragend"
        @expand-change="expandChange"
        @clearSelection="() => (_selectedAllRows = [])"
        v-waterMarker="waterMarker"
      >
        <el-table-column
          fixed="left"
          :width="25"
          type=""
          v-if="getIsDraggable()"
          ><el-icon class="dragIcon" title="拖拽"><Rank /></el-icon>
        </el-table-column>
        <el-table-column
          fixed="left"
          v-if="isSelect"
          v-bind="selectConfig"
          type="selection"
          align="center"
        />
        <el-table-column
          type="index"
          :width="indexWidth"
          fixed="left"
          :index="props.indexFn"
          label="序号"
          v-if="showIndex"
          align="center"
          class-name="index"
        >
          <template #header v-if="indexHeaderSlots">
            <component :is="indexHeaderSlots" />
          </template>
        </el-table-column>
        <template v-for="item of tableColumns" :key="item">
          <tableColumn :item="item" v-bind="omit(item, ['children'])">
            <template #[item]="scope" v-for="item in getTableColumnSlots">
              <slot
                :name="item"
                :column="scope.column"
                :row="scope.row"
                :index="scope.$index"
              />
            </template>
          </tableColumn>
        </template>
        <el-table-column
          fixed="right"
          label="操作"
          :width="actionWidth"
          align="center"
          v-if="$slots.action"
        >
          <template #default="scope">
            <slot
              name="action"
              :column="scope.column"
              :row="scope.row"
              :index="scope.$index"
            />
          </template>
        </el-table-column>
      </ElTable>
      <div class="table-footer-wrapper">
        <div class="table-footer-left">
          <slot name="table-footer-tool" />
        </div>
        <!-- TODO: 分页器 -->
        <div
          v-if="isShowPage && total > 0"
          class="table-footer-right"
          :style="{
            justifyContent: pageAlignJustifyContent,
          }"
        >
          <ElPagination
            v-model:currentPage="page"
            v-model:page-size="pageSize"
            :page-sizes="pageSizes"
            :small="'small'"
            :disabled="false"
            :background="true"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </ElCard>
  </div>

//表格搜索插槽-开始
function replaceFormSlotKey(key: string) {
  if (!key) return ''
  return key?.replace?.(/form\-/, '') ?? ''
}
const getFormSlotKeys = computed(() => {
  const that = getCurrentInstance()
  const keys = Object.keys(that!.slots)
  return keys
    .map((item) => (item.startsWith('form-') ? item : null))
    .filter((item) => !!item) as string[]
})
//表格搜索插槽-结束
// 列设置
const tableColumns = ref<I_TableColumns[]>(props.columns)
// 表格列中的插槽
const getTableColumnSlots = computed(() => {
  const that = getCurrentInstance()
  const slotsList: string[] = []
  Object.keys(that!.slots).forEach((item) => {
    if (!item.startsWith('form-')) {
      slotsList.push(item)
    }
  })
  return [
    ...tableColumns.value.filter((item) => item.slot).map((item) => item.slot),
    'expandSlot', // 兼容列 type 为 'expand' 的列
    ...slotsList,
  ]
})


步骤3页面使用姿势

    <template #form-contractCode1="{ model, field }">
      <el-input type="number" v-model="model[field]" placeholder="请输入">
        <template #append>元</template>
      </el-input>
    </template>
    配置项
      // // 表格搜索插槽-步骤1

{
type: ‘slot’,
prop: ‘overhaulCode1’,
label: ‘单号1’,
placeholder: ‘请输入1’,
slotName: ‘contractCode1’,
},
成果展示
在这里插入图片描述