vue中使用render函数动态生成树结构并回显数据

需求:我们要实现如下格式的树结构,能动态创建、删除和输入值并能回显数据。

 步骤一:通过iview UI 组件生成一个树结构,只要data里面的数据是数组且内部每一个对象里都嵌套一个 children 数组,就能创建一个树结构。

<Tree style="margin-top:20px;" :data="information" :render="renderContent" ></Tree>

数据结构如下: 

 

步骤二:render 函数结构如下, 在methods定义里面。

    renderContent(h,{ root, node, data }){
      return h("div",{
        style: {
          display: 'inline-block',
          width: '100%'
        }
      },[
        h("span","菜单参数"), // 显示的标题
        h("Input",{ // 输入框
          props:{
            size: 'small',
            level:{ required: true }  // 必填项
          },
          attrs:{
            placeholder:"请输入变量名",
            value:data.variableName // 回显数据
          },
          style:{
            width:"130px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.variableName = e.target.value // 将输入的值赋值到data的参数里
              console.log("输出输入的值:",e.target.value)
            }
          }
        }),
        h("Input",{
          props:{
            size: 'small',
            level:{ required: true }  // 必填项
          },
          attrs:{
            placeholder:"请输入字段名",
            value:data.fieldName // 回显值
          },
          style:{
            width:"130px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.fieldName = e.target.value // 输入时赋值
              console.log("输出输入的值:",e.target.value)
            }
          }
        }),
        h("Checkbox",{ // 复选框
          props:{
            size: 'small',
            level:{ required: true },  // 必填项
            value:data.isRequired == "1" ? true:false // 回显值,1为true不是则为false。
          },
          style:{
            width:"70px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.isRequired = e  // 输入时赋值
              console.log("输出输入的值:",e)
            }
          }
        },"是否必传"),  // 复选框旁的提示文字。
        h("Input",{
          props:{
            size: 'small',
            level:{ required: true }  // 必填项
          },
          attrs:{
            placeholder:"请输入类型名",
            value:data.type // 回显数据
          },
          style:{
            width:"130px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.type = e.target.value // 输入时赋值
              console.log("输出输入的值:",e.target.value)
            }
          }
        }),
        h("Input",{
          props:{
            size: 'small',
            level:{ required: true }  // 必填项
          },
          attrs:{
            placeholder:"请输入最大长度",
            value:data.maxlength // 回显数据
          },
          style:{
            width:"130px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.maxlength = e.target.value // 输入时赋值
              console.log("输出输入的值:",e.target.value)
            }
          }
        }),
        h("Input",{
          props:{
            size: 'small',
            level:{ required: true }  // 必填项
          },
          attrs:{
            placeholder:"请输入示例值",
            value:data.example // 回显数据
          },
          style:{
            width:"130px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.example = e.target.value // 输入时赋值
              console.log("输出输入的值:",e.target.value)
            }
          }
        }),
        h("Input",{
          props:{
            size: 'small',
            level:{ required: true }  // 必填项
          },
          attrs:{
            placeholder:"请输入描述",
            value:data.description // 回显数据
          },
          style:{
            width:"130px",
            marginLeft: '20px'
          },
          on:{
            'on-change':(e)=>{
              data.description = e.target.value // 输入时赋值
              console.log("输出输入的值:",e.target.value)
            }
          }
        }),
        h('Button', { // 在结尾添加按钮
          props: Object.assign({}, this.buttonProps, {
            icon: 'ios-add',
            type: 'success'
            }),
            style: {
              marginLeft: '20px',
              fontSize:'16px'
            },
            on: {
              click: () => { this.append(data) } // data是点击时这一行的数据
            }
        }),
        h('Button', {
          props: Object.assign({}, this.buttonProps, {
            icon: 'ios-close',
            type: 'error'
          }),
          style: {
            marginLeft: '8px',
            fontSize:'16px'
          },
          on: {
            click: () => { this.remove(root, node, data) } // data是点击时这一行的数据
          }
        })
      ])
    },

步骤三:结构出来后,我们就需要实现动态添加父级和子集,由于官方文档给出的解释太过笼统,下面我们将一步一步实现此结构。

 步骤四:首先点击新增参数按钮,生成父级级和子级结构。

  ①通过工厂函数生成一个对象,此对象包含了树结构内部的所有参数,用来生成父级和子级。

    studentSystem(variableName,fieldName,isRequired,type,
      maxlength,example,description,children,fieldId,fatherId,apiId){
      let obj = {}
      obj.variableName = variableName // 变量名
      obj.fieldName =  fieldName // 字段名称
      obj.isRequired = isRequired // 是否必传
      obj.type = type // 类型
      obj.maxlength = maxlength // 最大长度
      obj.example = example // 示例值
      obj.description = description // 描述
      obj.children = children // 子集数组
      obj.fieldId = fieldId // 本身id
      obj.parentId =  fatherId // 父 id
      obj.apiId = apiId // 接口id 
      obj.requestType = "1" // body
      return obj
  },

 ②点击新增参数按钮,使用上面创建的函数,往data绑定的数组里面添加一条对象。

    newParameters(){
      this.information.push(this.studentSystem("","","","","","","", 
      [],this.newID++,0,this.id1))
    },

 效果如下:

 ③:点击加号时,往当前点击的这一行对象里面的children数组里添加一条对象。

      data是当前点击这一行的所有数据。

    append(data){
      data.children.push(this.studentSystem("","","","","","","", 
      [],this.newID++,data.fieldId,this.id1))
    },

 效果如下:

 ④点击减号时,能删除点击的这一行结构。  官方给出的方法只能删除子一级的,无法删除父级,我们要单独写方法来删除父级。

首先我们在数组里通过indexOf来查找点击的这一行数据是否在总数组里,查到后返回其下标并通过splice来删除这一行。

最后我们在try和catch来执行,当try里删除子集报错时,就说明删除的是父级,就会执行catch里面的方法。

    remove(root, node, data){
      try {
        // 删除子集
        const parentKey = root.find(e => e === node ).parent
        const parent = root.find(e => e.nodeKey === parentKey).node
        const index = parent.children.indexOf(data)
        parent.children.splice(index,1)
      }catch{
        // 删除一集
        this.information.splice(this.information.indexOf(data),1)
      }
    },

 步骤五:发请求保存数据,直接将整个数据传递过去即可。

   saveSubmit(){
      new Promise((resolve,reject)=>{
        Api.addedParameterTreeStructure(this.information).then(response=>{
          this.$Message.success("提交成功!")
          this.$router.push("interfaceManagement")
        }).catch(error=>{
          reject(error)
        })
      })
    },

 步骤六: 发请求回显数据,拿到的数据直接赋值到数组里即可,由于在步骤二中已经将数组中的参数赋值到value中去,这里就直接能回显数据。

  bodyParameterDisplayed(){
      let data = { apiId:this.id1 }
      new Promise((resolve,reject)=>{
        Api.bodyParameterTreeStructureDisplayed(data).then(response=>{
          this.information = response.result.bodyList
        }).catch(error=>{
          reject(error)
        })
      })
    }

おすすめ

転載: blog.csdn.net/weixin_48674314/article/details/119808247