Variant Form 3 增加treeSelect树形选择组件

本文使用非扩展方式增加 Variant Form 3 组件,直接整合修改源码用于记录修改过程,涉及elementPlus+VUE3。

1、新建VUE组件,涉及目录

src\components\form-designer\form-widget\field-widget
treeSelect 是 tree+select 两个组件整合,做,直接可以复制 原select-widget.vue为tree-select-widget.vue。修改文件内el-select 为el-tree-select,不同的是select下拉列表与tree-select下拉树 选项生成方式不同,select 是使用el-option ,tree-select 直接使用data。

tree-select-widget.vue
<template>
  <form-item-wrapper :designer="designer" :field="field" :rules="rules" :design-state="designState"
                     :parent-widget="parentWidget" :parent-list="parentList" :index-of-parent-list="indexOfParentList"
                     :sub-form-row-index="subFormRowIndex" :sub-form-col-index="subFormColIndex" :sub-form-row-id="subFormRowId">
    <el-select ref="fieldEditor" v-model="fieldModel" v-show="!isReadMode" class="full-width-input"
               :disabled="field.options.disabled"
               :size="widgetSize"
               :clearable="field.options.clearable"
               :filterable="field.options.filterable"
               :allow-create="field.options.allowCreate"
               :default-first-option="allowDefaultFirstOption"
               :automatic-dropdown="field.options.automaticDropdown"
               :multiple="field.options.multiple" :limit="field.options.multipleLimit"
               :placeholder="field.options.placeholder || i18nt('render.hint.selectPlaceholder')"
               :remote="field.options.remote" :remote-method="remoteQuery"
               @focus="handleFocusCustomEvent" @blur="handleBlurCustomEvent"
               @change="handleChangeEvent">
      <el-option v-for="item in field.options.optionItems" :key="item.value" :label="item.label"
                 :value="item.value" :disabled="item.disabled">
      </el-option>
    </el-select>
    <template v-if="isReadMode">
      <span class="readonly-mode-field">{{optionLabel}}</span>
    </template>
  </form-item-wrapper>
</template>

<script>
  import FormItemWrapper from './form-item-wrapper'
  import emitter from '@/utils/emitter'
  import i18n, {translate} from "@/utils/i18n";
  import fieldMixin from "@/components/form-designer/form-widget/field-widget/fieldMixin";

  export default {
    name: "select-widget",
    componentName: 'FieldWidget',  //必须固定为FieldWidget,用于接收父级组件的broadcast事件
    mixins: [emitter, fieldMixin, i18n],
    props: {
      field: Object,
      parentWidget: Object,
      parentList: Array,
      indexOfParentList: Number,
      designer: Object,

      designState: {
        type: Boolean,
        default: false
      },

      subFormRowIndex: { /* 子表单组件行索引,从0开始计数 */
        type: Number,
        default: -1
      },
      subFormColIndex: { /* 子表单组件列索引,从0开始计数 */
        type: Number,
        default: -1
      },
      subFormRowId: { /* 子表单组件行Id,唯一id且不可变 */
        type: String,
        default: ''
      },

    },
    components: {
      FormItemWrapper,
    },
    data() {
      return {
        oldFieldValue: null, //field组件change之前的值
        fieldModel: null,
        rules: [],
      }
    },
    computed: {
      allowDefaultFirstOption() {
        return (!!this.field.options.filterable && !!this.field.options.allowCreate)
      },

    },
    beforeCreate() {
      /* 这里不能访问方法和属性!! */
    },

    created() {
      /* 注意:子组件mounted在父组件created之后、父组件mounted之前触发,故子组件mounted需要用到的prop
         需要在父组件created中初始化!! */
      this.registerToRefList()
      this.initOptionItems()
      this.initFieldModel()
      this.initEventHandler()
      this.buildFieldRules()

      this.handleOnCreated()
    },

    mounted() {
      this.handleOnMounted()
    },

    beforeUnmount() {
      this.unregisterFromRefList()
    },

    methods: {

    }
  }
</script>

<style lang="scss" scoped>
  @import "../../../../styles/global.scss"; /* form-item-wrapper已引入,还需要重复引入吗? */

  .full-width-input {
    width: 100% !important;
  }

</style>

2、在src\components\form-designer\widget-panel\widgetConfig.js 中定义tree-select组件在设置器里的属性参数。

{
    type: 'tree-select',
    icon: 'select-field',
    formItemFlag: true,
    options: {
      name: '',
      label: '',
      labelAlign: '',
      defaultValue: '',
      placeholder: '',
      columnWidth: '200px',
      size: '',
      labelWidth: null,
      labelHidden: false,
      checkStrictly: true,
      disabled: false,
      hidden: false,
      clearable: true,
      filterable: false,
      allowCreate: false,
      remote: false,
      automaticDropdown: false,  //自动下拉
      multiple: false,
      multipleLimit: 0,
      dsEnabled: false, // 是否使用数据源数据
      dsName: '', // 数据源名称
      dataSetName: '',  //数据集名称
      labelKey: 'label',
      valueKey: 'value',
      optionItems: [  
        {value: '1',label: 'Level one 1',children: [{value: '1-1',label: 'Level two 1-1',children: [{value: '1-1-1',label: 'Level three 1-1-1',},],},],},  
        {value: '2',label: 'Level one 2',children: [{  value: '2-1',  label: 'Level two 2-1',  children: [{value: '2-1-1',label: 'Level three 2-1-1',},  ],},{  value: '2-2',  label: 'Level two 2-2',  children: [{value: '2-2-1',label: 'Level three 2-2-1',},  ],},],  },  
        {value: '3',label: 'Level one 3',children: [{  value: '3-1',  label: 'Level two 3-1',  children: [{value: '3-1-1',label: 'Level three 3-1-1',},  ],},{  value: '3-2',  label: 'Level two 3-2',  children: [{value: '3-2-1',label: 'Level three 3-2-1',},  ],},],  },
        ],
      required: false,
      requiredHint: '',
      validation: '',
      validationHint: '',
      //-------------------
      customClass: '',  //自定义css类名
      labelIconClass: null,
      labelIconPosition: 'rear',
      labelTooltip: null,
      //-------------------
      onCreated: '',
      onMounted: '',
      onRemoteQuery: '',
      onChange: '',
      onFocus: '',
      onBlur: '',
      onValidate: '',
       },
  },

3、src\utils\sfc-generator.js 增加渲染的模板,

'tree-select': (widget, formConfig, parentWidget) => {
    const {vModel, disabled, size, clearable, filterable, allowCreate, defaultFirstOption, automaticDropdown,
      multiple, multipleLimit, remote, placeholder,checkStrictly} = getElAttrs(widget, formConfig, parentWidget)
 	
    return `<el-tree-select ${vModel} class="full-width-input" ${disabled} ${checkStrictly} ${size} ${clearable} ${filterable}
            ${allowCreate} ${defaultFirstOption} ${automaticDropdown}  ${multiple} ${multipleLimit} ${placeholder}
            ${remote}></el-tree-select>`
  },

4、src\utils\utils.js 下拉树使用数据源方式,数据处理与select不同,需要修改function translateOptionItems(rawData, widgetType, labelKey, valueKey)

/**
 * 替代eval
 * @param {*} fun 
 * @returns 
 */
export function gEval(fun){
  let function1 = Function;
  try{
     return new function1('return '+fun)();
  }catch(err){
     return eval(fun);
  }
}

/**
 * 转译选择项数据
 * @param rawData
 * @param widgetType
 * @param labelKey
 * @param valueKey
 * @returns {[]}
 */
export function translateOptionItems(rawData, widgetType, labelKey, valueKey) {
  if (widgetType === 'cascader') { // 级联选择 树选择框 不转译
    return deepClone(rawData)
  }
  
  if (widgetType === 'tree-select') { // 树选择框 不转译
    let rawData1 = deepClone(rawData);
    if(typeof rawData1=='string'){
      return gEval(rawData1)
    }
    return rawData1;
  }

  let result = []
  if (!!rawData && (rawData.length > 0)) {
    rawData.forEach(ri => {
      result.push({
        label: ri[labelKey],
        value: ri[valueKey]
      })
    })
  }

  return result
}

5、在src\components\form-designer\form-widget\field-widget\fieldMixin.js 文件的 initOptionItems和loadOptionItemsFromDataSet 增加tree-select 数据源支持。

6、在src\lang\zh-CN.js等designer下的widgetLabel内语言文件增加标识

‘tree-select’: ‘下拉树’,

经过以上6步,组件基本整合完毕了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值