一、新建myTree.vue

<template>
  <el-card class="box-card">
    <el-tree :data="datas" @check="getCheckedKeys" show-checkbox default-expand-all node-key="id" ref="tree"
      highlight-current :props="defaultProps">
    </el-tree>
  </el-card>
</template>
<div class="buttons">
  <el-button @click="getCheckedNodes">通过 node 获取</el-button>
  <el-button @click="getCheckedKeys">通过 key 获取</el-button>
  <el-button @click="setCheckedNodes">通过 node 设置</el-button>
  <el-button @click="setCheckedKeys">通过 key 设置</el-button>
  <el-button @click="resetChecked">清空</el-button>
</div>

<script>
  export default {
    data() {
      return {
        //示例数据
        datas: [{
          id: 1,
          label: '一级 1',
          children: [{
            id: 4,
            label: '二级 1-1',
            children: [{
              id: 9,
              label: '三级 1-1-1'
            }, {
              id: 10,
              label: '三级 1-1-2'
            }]
          }]
        }, {
          id: 2,
          label: '一级 2',
          children: [{
            id: 5,
            label: '二级 2-1'
          }, {
            id: 6,
            label: '二级 2-2'
          }]
        }, {
          id: 3,
          label: '一级 3',
          children: [{
            id: 7,
            label: '二级 3-1'
          }, {
            id: 8,
            label: '二级 3-2'
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    props: ['data_conf', 'value'],//data_conf为树结点数据,value为选择值
    created() {
      // console.log(JSON.stringify(this.data_conf))
      console.log('1. value = ' + JSON.stringify(this.value))
      this.datas = this.data_conf
    },
    mounted() {
      this.setCheckedKeys()
    },
    watch: {
      value(val) {
        console.log("in mytree 收到初始化值:"+val)  // 在查看表单数据时,会调用本方法
        this.setCheckedKeys()
      },
      data_conf(val) {
        //绘制表单时,添加为接口地址后,form-generator会向该接口请求数据,请求成功后,将返回的数据,
        //赋值给config.js中定义的dataConsumer: 'data_conf',即本组件中的
        console.log("in mytree 收到data_conf值:"+val)
        this.datas = val;
      }
    },
    methods: {
      getCheckedNodes() {
        console.log(this.$refs.tree.getCheckedNodes());
      },
      getCheckedKeys() {
        console.log(this.$refs.tree.getCheckedKeys());
        //向父级组件传值,固定写法
        this.$emit("input", this.$refs.tree.getCheckedKeys())
      },
      setCheckedNodes() {
        this.$refs.tree.setCheckedNodes([{
          id: 5,
          label: '二级 2-1'
        }, {
          id: 9,
          label: '三级 1-1-1'
        }]);
      },
      setCheckedKeys() {
        if (this.value && this.$refs.tree) {
          this.$refs.tree.setCheckedKeys(this.value);
        }
      },
      resetChecked() {
        this.$refs.tree.setCheckedKeys(this.value);
      }
    },

  };
</script>

二、在项目的main.js中引入

import myTree from  '@/components/form/myTree';
Vue.component('myTree', myTree);

三、在generator/config.js中声明,即添加绘图器左侧的按钮,效果如图

添加左侧按钮

具体代码

// 输入型组件 【左面板】
export const inputComponents = [  //... 
  /** myTree */
  {
    // 组件的自定义配置
    //__config__中定义的属性,都可以在自定义组件中访问
    __config__: {
      label: 'my树',
      labelWidth: null,
      showLabel: true,
      changeTag: true,
      tag: 'myTree',   //自定义组件的名称,myTree.vue, 要一致
      tagIcon: 'input',
      defaultValue: [''],
      required: true,
      layout: 'colFormItem',
      span: 24,
      document: 'https://element.eleme.cn/#/zh-CN/component/input',
      // 正则校验规则
      //regList: [],
      url: '',
      dataType: 'dynamic',
      method: 'get',
      dataPath: 'data',           // 访问url返回结果中的数据键名
      dataConsumer: 'data_conf',  //myTree组件中负责接收初始化值的属性,即tree各节点的值
    },
    // 组件的插槽属性
    __slot__: {
      prepend: '',
      append: ''
    },
    // 其余的为可直接写在组件标签上的属性
    //placeholder: '请输入',
    style: {width: '100%'},
    clearable: true,
    'prefix-icon': '',
    'suffix-icon': '',
    maxlength: null,
    'show-word-limit': false,
    readonly: false,
    disabled: false,
},
]

四、在RightPanel.vue中配置,即组件需要配置哪些属性。

右侧属性面板
这里主要配置接口地址,配置地址后,如果正确,会将树进行初始化。
配置成功后效果图
此时,控制台会输出如下:
在这里插入图片描述
关键代码:在相关位置上,添加本标签的名称 ‘myTree’,属性面板即可显示

<template v-if="['el-cascader', 'el-table', 'el-tree', 'myTree'].includes(activeData.__config__.tag)">
            <el-divider>选项</el-divider>
            <el-form-item v-if="activeData.__config__.dataType" label="数据类型">
              <el-radio-group v-model="activeData.__config__.dataType" size="small">
                <el-radio-button label="dynamic">
                  动态数据
                </el-radio-button>
                <el-radio-button label="static">
                  静态数据
                </el-radio-button>
              </el-radio-group>
            </el-form-item>
            ...
</template>          

五、关键说明

自定义组件的关键在于三点:
(1)子组件本身的初始化,在config.js中定义组件后,其中的__config__中的dataConsumer: 'data_conf’值(也可以自己定义)负责接收相关数据,与myTree.vue中的props: [‘data_conf’, ‘value’]要保持一致。
(2)子组件向父组件传值,即生成表单后对应变量赋值时,固定调用 this.$emit(“input”, 值),表单才能取到值。
(3)当父组件向子组件传值,即表单值恢复显示时,会将值交给value,需要在watch中定义接收方法,即

 watch: {
      value(val) {
        console.log("in mytree 收到初始化值:"+val)  // 在查看表单数据时,会调用本方法
        this.setCheckedKeys()        
      },
      data_conf(val) {
        //绘制表单时,添加为接口地址后,form-generator会向该接口请求数据,请求成功后,将返回的数据,
        //赋值给config.js中定义的dataConsumer: 'data_conf',即本组件中的
        console.log("in mytree 收到data_conf值:"+val)
        this.datas = val;        
      }
    },

六、使用本方法,可以构建复杂的子组件了。

后记:本方法可能比较笨拙,我抛砖引玉,欢迎大家批评批评。

Logo

前往低代码交流专区

更多推荐