基于 DSL 的动态组件设计

75 阅读1分钟

以 Input 组件为例,阐述其动态渲染的逻辑

Input 组件代码

<template>
  <el-input v-model="dtoValue" v-bind="schema.option" class="input" />
</template>

<script setup>
import { ref, onMounted } from 'vue';

const { schemaKey, schema } = defineProps({
  schemaKey: {
    type: String,
    default: ''
  },
  schema: {
    type: Object,
    default: () => { }
  }
})

const emit = defineEmits(['loaded']);

const dtoValue = ref();

const getValue = () => {
  return dtoValue.value !== undefined ? {
    [schemaKey]: dtoValue.value,
  } : {}
};

const reset = () => {
  dtoValue.value = schema.option.default;
};

onMounted(()=>{
  reset();
  emit('loaded');
})

defineExpose({
  getValue,
  reset
})

</script>

在 config 中引入

import input from './complex-view/input/input.vue';

const SearchItemConfig = {
  input: {
    component: input,
  }
};

export default {
  ...SearchItemConfig,
};

字段的对应配置

properties: {
    product_id: {
      type: 'string',
      label: '商品ID',
      tableOption: {
        width: 300,
        'show-overflow-tooltip': true,
      },
      searchOption: {
        comType: 'input',
      },
    },
}

根据配置动态渲染对应组件

<!-- 动态组件 -->
<el-form-item v-for="(schemaItem, key) in schema.properties" :key="key" :label="schemaItem.label">
  <component
    :is="SearchItemConfig[schemaItem.option?.comType]?.component"
    ref="searchComlist"
    :schema-key="key"
    :schema="schemaItem"
    @loaded="handleChildLoaded"
  />
</el-form-item>

学习内容源自--抖音“哲玄前端”《大前端全栈实践》