Vue 学习随笔系列七 -- 表单动态生成

表单动态生成

文章目录

  • 表单动态生成
      • 1、动态表单组件封装
      • 2、组件引用
      • 3、实现效果


1、动态表单组件封装

<!-- 动态生成下拉框,可同理生成input框等 -->
<template>
  <el-dialog
    custom-class="custom-dialog"
    :title="dialogTitle"
    :visible.sync="visible"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :before-close="handleClose"
    width="40%" 
  >
    <el-form 
      :model="form"
      ref="Form"
      label-width="80px"
    >
      <el-form-item
        v-for="(item, index) in formConfig"
        :key="index"
        :label="item.label"
      >
        <el-select
          clearable
          size="small"
          multiple
          v-model="formConfig[index].result.value"
          placeholder="请选择"
          style="width: 90%;"
          @change="val=>handelChange(val, index)"
          @clear="val =>handelClear(val, index)"
        >
        <el-option
          v-for="data in item.option"
          :key="data.code"
          :label="data.label"
          :value="data.code"
        >
        </el-option>
      </el-select>
      </el-form-item>

    </el-form>

    <div slot="footer" class="dialog-footer">
      <el-button size="small" @click="handleClose">取消</el-button>
      <el-button size="small" type="primary" @click="handleSubmit">确定</el-button>
    </div>

  </el-dialog>
  
</template>

<script>

  export default {
    data() {
      return {
        dialogTitle: "动态表单",
        visible: false,
        arr: [], // 回显参数
        form: {},
        formConfig: [
          {
            option: [
              {
                code: 1,
                label: '选项1'
              },
              {
                code: 2,
                label: '选项2'
              },
              {
                code: 3,
                label: '选项3'
              }
            ],
            result:{
              label:'',
              value:''
            }
          },
        ],
      }
    },
    // computed(){},
    methods: {
      // 打开弹窗
      handleOpen() {
        this.visible = true
      },
      // 关闭弹窗
      handleClose(){
        this.visible = false
      },
      handelChange(val,index){
        console.log("val==", val)
        if(val.length){//多选
          this.format2(val,index)
        } else {//单选
          this.format1(val,index)
        }                
      },
      // 清空多选框
      handelClear(val, index){
        if(!val){
          const newInitValue = this.formConfig.slice(0, index+1)
          this.formConfig = [...newInitValue]
          return
        }
      },
      //单选
      format1(val,index){
        if(!val){
          const newInitValue = this.formConfig.slice(0, index+1)
          this.formConfig = [...newInitValue]
          return
        }
        const label = this.formConfig[index].option.find(item=>item.code===val).label
        this.$set(this.formConfig[index],'result',{
          label,
          value: val
        })
        this.queryItems(index)
      },
      //多选
      format2(val, index){
        let label = []
        console.log("val.length", val)
        for(let i = 0; i< val.length; i++) {
          this.formConfig[index].option.find( item => {
            if(item.code === val[i]){
              label[i] = item.label
            }
          })
        }

        this.$set(this.formConfig[index], 'result', {
          label,
          value: val
        })
        const params = {index: index, code: val}
        this.getSonList(params)
      },
      //
      // queryItems(index){
      //   const temp = {
      //       option: [
      //         {
      //           code: 1,
      //           label: '选项1'
      //         },
      //         {
      //           code: 2,
      //           label: '选项2'
      //         },
      //         {
      //           code: 3,
      //           label: '选项3'
      //         }
      //       ],
      //       result:{
      //         label:'',
      //         value:''
      //       }
      //     }
      //   this.$set(this.formConfig, index+1, temp)
      // },
      handleSubmit() {
        const temp = this.formConfig.map(item=>item.result)
        let formParams = temp.slice(-2, -1) // 取数组倒数第二位值

        console.log(formParams)

        const params = formParams
        this.$emit('handleSubmit', params)
        this.handleClose()
      },
      // 获取一级科目
      // 获取一级科目
      getList(){
        console.log("getFirstList===")
        // getFirstList().then(res => {
        //   console.log('res===', res)
        //	 const temp = {
        // 		option: res.option,
        //		result: {
        //		label: "",
        //		value: "",
        //   }
        // 	 this.$set(this.formConfig, 0, temp) // 配置第一个下拉框选项
        // })
      },
      getSonList(value){
        console.log("getsonList====", value)
        // const params = {kmcode: value}
        // getsonLists(params).then(res => {
        //   console.log("res==", res)
        //	 const temp = {
        // 		option: res.option,
        //		result: {
        //		label: "",
        //		value: "",
        //   }
        // 	 this.$set(this.formConfig, index + 1, temp) // 配置后续下拉框选项
        // })
        let index = value.index
        // let code = value.code
        const temp = {
          option: [
            {
              code: 1,
              label: '选项1'
            },
            {
              code: 2,
              label: '选项2'
            },
            {
              code: 3,
              label: '选项3'
            }
          ],
          result:{
            label:'',
            value:''
          }
        }
        this.$set(this.formConfig, index+1, temp)
      }
    },
  }
</script>

2、组件引用

<template>
  <div class="main">
    <div class="form-box">
      <el-input
        v-model="value"
        clearable
        style="width: 20%;"
      ></el-input>
      <el-button type="primary" @click="handleOpen()">表单</el-button>
      <MultiForm ref="form" @handleSubmit="handleSubmit"></MultiForm>
    </div>     
  </div>
  
</template>

<script>
import MultiForm from "./multiSelect.vue"

export default {
  name: 'HelloWorld',
  components: {
    MultiForm
  },
  props: {

  },
  data(){
   return {
    value: '', // input输入框的值
   }     
  },
  mounted(){
  },
  methods: {
    handleOpen(){
      this.$refs.form.handleOpen()
    },
    handleSubmit(val){
      console.log("val==", val)
      let arr = val[0].label
      this.value = arr.toString()
    }
  }
}
</script>

<style>

</style>

3、实现效果

点击上一个选项,选中后出现下一个下拉框,并将最后一个数据回显到输入框中
Vue 学习随笔系列七 -- 表单动态生成_第1张图片
Vue 学习随笔系列七 -- 表单动态生成_第2张图片

你可能感兴趣的:(vue.js,学习,javascript)