element-ui自定义选择控件

1.需求:由程序员定义好控件,如单选框,多选下拉框,单选下拉框等,然后由用户决定使用哪个或者多个,是否必填,长度限制等

2.新增控件

<template>
  <div>

    <el-row :gutter="20">
      <el-form-item style="font:22px">
        {{ widgetTitle }}
        <el-button icon="plus" class="primary" @click="addwidget">新增</el-button>
      </el-form-item>
    </el-row>

    <el-table
      v-loading="widgetListLoading"
      ref="multipleTable"
      :data="widgetList"
      border
      stripe
      tooltip-effect="dark"
      style="width: 100%">
      <el-table-column
        prop="name"
        label="控件名称"
        align="center"
        show-overflow-tooltip/>
      <el-table-column
        prop="length"
        label="限制长度"
        align="center"
        show-overflow-tooltip/>
      <el-table-column
        prop="fillData"
        label="选项内容"
        align="center"
        show-overflow-tooltip/>
      <el-table-column
        :formatter="requiredFormatter"
        prop="required"
        label="是否必填"
        align="center"
        show-overflow-tooltip/>
      <el-table-column
        prop="prompt"
        label="提示信息"
        align="center"
        show-overflow-tooltip/>

      <el-table-column
        :formatter="statusFormatter"
        prop="status"
        label="状态"
        align="center"
        show-overflow-tooltip/>

      <el-table-column label="操作" align="center">
        <template slot-scope="scope">
          <el-button
            size="small"
            @click="widgetEdit(scope.$index, scope.row)">编辑
          </el-button>
          <el-button
            size="small"
            type="danger"
            @click="widgetDelete(scope.$index, scope.row)">删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog :title="dialogTitle" :visible.sync="dialogShow" :close="resetForm">
      <el-form
        v-loading="formLoading"
        ref="widgetForm"
        :model="widget"
        :rules="widgetFormRules"
        label-position="left"
        label-width="100px"
        style="margin: 0 3%">

        <el-form-item label="控件名:" prop="name">
          <el-input v-model="widget.name" style="width: 360px"/>
        </el-form-item>

        <el-form-item label="控件类型:" prop="type">
          <el-select v-model="widget.type" placeholder="请选择" style="width: 360px">
            <el-option
              v-for="item in componentTypes"
              :key="item.value"
              :label="item.label"
              :value="item.value"/>
          </el-select>
        </el-form-item>

        <el-form-item v-if="widget.type === 'text'" label="长度限制:">
          <el-input-number v-model="widget.length" :min="1" :max="1000" />
        </el-form-item>

        <el-form-item v-if="widget.type !== 'text' && widget.type !== '' " label="选项内容:" prop="fillData">
          <el-tag
            v-for="tag in dynamicTags"
            :key="tag"
            :disable-transitions="false"
            closable
            @close="handleClose(tag)">
            {{ tag }}
          </el-tag>
          <el-input
            v-if="inputVisible"
            ref="saveTagInput"
            v-model="inputValue"
            class="input-new-tag"
            size="small"
            @keyup.enter.native="handleInputConfirm"
            @blur="handleInputConfirm"
          />
          <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 添加选项</el-button>
        </el-form-item>

        <el-form-item label="必填/选填:" prop="required">
          <el-select v-model="widget.required" placeholder="请选择" style="width: 360px">
            <el-option
              v-for="item in isRequired"
              :key="item.value"
              :label="item.label"
              :value="item.value"/>
          </el-select>
        </el-form-item>

        <el-form-item label="提示信息:" prop="prompt">
          <el-input v-model="widget.prompt" style="width: 360px"/>
        </el-form-item>

        <el-form-item label="状态:" prop="status">
          <el-select v-model="widget.status" placeholder="请选择" style="width: 360px">
            <el-option
              v-for="item in isUse"
              :key="item.value"
              :label="item.label"
              :value="item.value"/>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="saveLoading" type="primary" @click="savewidget">确定</el-button>
        <el-button @click="resetForm">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>

export default {
  props: {
    mediaTypeId: {
      type: String,
      required: true
    },
    widgetTitle: {
      type: String,
      required: true
    },
    commonId: {
      type: String,
      required: true
    },
    widgetList: {
      type: Array,
      required: true
    },
    deleteWidgetList: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      dynamicTags: [],
      inputVisible: false,
      inputValue: '',
      isRequired: [
        {
          value: 1,
          label: '必填'
        }, {
          value: 0,
          label: '选填'
        }
      ],
      isUse: [
        {
          value: 1,
          label: '启用'
        }, {
          value: 0,
          label: '停用'
        }
      ],
      componentTypes: [
        {
          value: 'text',
          label: '文本框'
        },
        {
          value: 'selectBox',
          label: '单选下拉框'
        },
        {
          value: 'multipleSelect',
          label: '多选下拉框'
        },
        {
          value: 'radio',
          label: '单选框'

        }

      ],
      // widgetList: [],
      widgetListLoading: false,
      page: 1,
      size: 10,
      total: 0,
      sizes: [10, 20, 50, 100],

      dialogTitle: '新增',
      dialogShow: false,
      formLoading: false,
      treeLoading: false,
      saveLoading: false,
      filterText: '',
      menus: [],
      widget: {
      },
      widgetFormRules: {
        name: [{ required: true, message: '请输入控件名', trigger: 'blur' }],
        type: [{ required: true, message: '请选择控件类型', trigger: 'blur' }],
        dynamicTags: [{ required: true, message: '请输入选项内容', trigger: 'blur' }],
        status: [{ required: true, message: '请选择控件状态', trigger: 'blur' }],
        required: [{ required: true, message: '请选择是否必填', trigger: 'blur' }]
      }
    }
  },
  watch: {},
  // created() {
  // },
  methods: {
    handleClose(tag) {
      this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1)
    },

    showInput() {
      this.inputVisible = true
      this.$nextTick(_ => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },

    handleInputConfirm() {
      const inputValue = this.inputValue
      if (inputValue) {
        this.dynamicTags.push(inputValue)
      }
      this.inputVisible = false
      this.inputValue = ''
    },

    widgetEdit(index, row) {
      this.dialogTitle = '编辑'
      this.dialogShow = true
      this.formLoading = false
      this.widget = this.widgetList[index]

      if (this.widget.id != null) {
        this.widget.operation = 'edit'
      }

      // 将逗号分隔的字符串转成数组
      if (this.widget.fillData != null) {
        this.dynamicTags = this.widget.fillData.split(',')
      } else {
        this.dynamicTags = []
      }
    },
    widgetDelete(index, row) {
      this.$confirm('此操作将永久删除该条结算方式数据, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.widgetListLoading = false
        // 如果id存在,则说明是数据库中存在的,否则为前端新增的无需
        if (this.widgetList[index].id !== '') {
          this.widgetList[index].operation = 'delete'
          this.deleteWidgetList.push(this.widgetList[index])
        }
        this.widgetList.pop(index)
        this.$message({
          showClose: true,
          message: '删除成功',
          duration: 4000,
          type: 'success'
        })
      })
    },
    addwidget() {
      this.dialogTitle = '新增'
      this.dialogShow = true
      var newWidget = { id: '',
        name: '',
        type: '',
        common: '',
        prompt: '',
        length: 0,
        status: '',
        required: '',
        fillData: '',
        operation: 'add'
      }
      this.widgetList.push(newWidget)
      this.widget = newWidget
    },
    savewidget() {
      this.$refs['widgetForm'].validate(valid => {
        if (valid) {
          this.saveLoading = true
          this.widget.common = this.commonId
          // this.dynamicTags.toString将数组转成以逗号分隔字符串
          this.widget.fillData = this.dynamicTags.toString()

          this.dynamicTags = []
          this.saveLoading = false
          this.dialogShow = false
        }
      })
    },
    resetForm() {
      this.dialogShow = false
      this.$refs['widgetForm'].resetFields()
      this.saveLoading = false
    },
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    statusFormatter(row, column, cellValue) {
      if (cellValue === 1) {
        return '启用'
      } else {
        return '停用'
      }
    },
    requiredFormatter(row, column, cellValue) {
      if (cellValue === 1) {
        return '必填'
      } else {
        return '选填'
      }
    }
  }
}
</script>

<style rel='stylesheet/scss' lang='scss' scoped>
</style>

3.控件展示:


<template>
  <div>

    <!-- 下拉框模板 -->
    <el-form-item v-for="(widget, index) of widgetArray " :rules="{required: isRequired[widget.required], message: '请输入${widget.value}', trigger: 'blur'}" :key="index" :label="widget.name" style="width: 360px" >

      <el-select v-if="widget.type === 'selectBox'" :title="widget.prompt" :disabled="auditDisabled" v-model="widget.value" placeholder="请选择" style="width: 360px">
        <el-option
          v-for="(item,num) of widget.fillData.split(',')"
          :key="num"
          :label="item"
          :value="item"/>
      </el-select>
      <!-- 多选输入框 -->
      <el-select v-if="widget.type === 'multipleSelect' " :disabled="auditDisabled" v-model="widget.value" :title="widget.prompt" multiple placeholder="请选择" style="width: 360px">
        <el-option
          v-for="(comtent,numb) in widget.fillData.split(',')"
          :key="numb"
          :label="comtent"
          :value="comtent"/>
      </el-select>

      <!-- 文本框框模板 -->
      <el-input v-if="widget.type === 'text'" :disabled="auditDisabled" v-model.trim="widget.value" :title="widget.prompt" maxlength="`${widget.length}`" style="width: 360px"/>
      <!-- 单选框的模板 -->

      <el-radio-group v-if="widget.type === 'radio' " :title="widget.prompt" :disabled="auditDisabled" v-model="widget.value">
        <el-radio v-for="(item,indexNum) of widget.fillData.split(',')" :key ="indexNum" :label="item">{{ item }}</el-radio>
      </el-radio-group>
      <br>
    </el-form-item>
  </div>
</template>

<script>
export default {
  props: {
    widgetArray: {
      type: Array,
      required: true
    },
    auditDisabled: {
      type: Boolean,
      required: true
    }
  },
  data() {
    return {
      isRequired: [false, true],
      multiValue: []
    }
  },
  created() {

  }
}
</script>

4.数据展示的格式

{
    "desc":"success",
    "code":0,
    "origin_request_id":null,
    "response_time":"2019-01-29 09:18:58.112",
    "total":null,
    "errors":null,
    "response":[
        {
            "id":1,
            "common":1,
            "required":0,
            "status":1,
            "name":"禁投行业",
            "prompt":"选择广告的禁投行业,您的广告不会出现在所选类型的广告",
            "type":"multipleSelect",
            "fillData":"金融理财,服装鞋帽,医疗保健,教育培训,箱包饰品,食品饮料,家庭日用,房地产,母婴护理,化妆护理,手机数码,家用电器,硬件办公,家居建材,网络服务,生活服务,交通出行,旅游住宿,游戏,通讯服务,休闲娱乐,优惠卡券,电商平台,餐饮服务",
            "mediaTypeId":69,
            "length":5,
            "value":null,
            "mediaId":null
        },
        {
            "id":8,
            "common":1,
            "required":1,
            "status":0,
            "name":"测试",
            "prompt":"ddd",
            "type":"selectBox",
            "fillData":"ddd,123,2345",
            "mediaTypeId":69,
            "length":0,
            "value":null,
            "mediaId":null
        },
        {
            "id":16,
            "common":1,
            "required":1,
            "status":0,
            "name":"输入框",
            "prompt":"请填写内容",
            "type":"text",
            "fillData":"",
            "mediaTypeId":69,
            "length":3,
            "value":null,
            "mediaId":null
        },
        {
            "id":32,
            "common":0,
            "required":1,
            "status":1,
            "name":"1231",
            "prompt":"ddd",
            "type":"text",
            "fillData":"",
            "mediaTypeId":1,
            "length":11,
            "value":null,
            "mediaId":null
        }
    ]
}

猜你喜欢

转载自blog.csdn.net/u011662320/article/details/86685469
今日推荐