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
}
]
}