那么否则: 1<总数量<=20
赋值的每个项都是必填
父组件:
ActionThenElse.vue
<template>
<el-form :model="formData" ref="formRef" :rules="formRules">
<ActionGroup
v-model="formData.actions"
prop="actions"
label="那么:"
:variable-options="variableOptions"
:total-count="totalActionCount"
:other-count="formData.elseActions.length"
:required="isActionsRequired"
/>
<ActionGroup
v-model="formData.elseActions"
prop="elseActions"
label="否则:"
:variable-options="variableOptions"
:total-count="totalActionCount"
:other-count="formData.actions.length"
:required="isElseActionsRequired"
/>
<el-form-item>
<el-button type="primary" @click="validateForm">校验表单</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, computed } from 'vue'
import ActionGroup from './ActionGroup.vue'
const formRef = ref()
const formData = ref({
actions: [],
elseActions: [],
})
const variableOptions = [
{ value: 'var1', label: '变量1' },
{ value: 'var2', label: '变量2' },
]
const totalActionCount = computed(() => {
return formData.value.actions.length + formData.value.elseActions.length
})
const isActionsRequired = computed(() => {
return formData.value.elseActions.length === 0
})
const isElseActionsRequired = computed(() => {
return formData.value.actions.length === 0
})
const formRules = {
actions: [
{
validator: (rule, value, callback) => {
if (totalActionCount.value === 0) {
callback(new Error('至少需要一条操作(在"那么"或"否则"中)'))
} else {
callback()
}
},
trigger: 'change',
},
],
elseActions: [
{
validator: (rule, value, callback) => {
if (totalActionCount.value === 0) {
callback(new Error('至少需要一条操作(在"那么"或"否则"中)'))
} else {
callback()
}
},
trigger: 'change',
},
],
}
const validateForm = () => {
formRef.value.validate((valid, fields) => {
if (!valid) {
return
}
})
}
const resetForm = () => {
formRef.value.resetFields()
formData.value = {
actions: [{ actionType: '', leftValue: '', rightValue: '' }],
elseActions: [],
}
}
</script>
子组件ActionGroup.vue:
<!-- ActionGroup.vue -->
<template>
<el-form-item :label="label" :prop="prop">
<div class="action-container">
<el-button
type="primary"
link
@click="addAction"
icon="Plus"
:disabled="disableAdd"
>
添加操作 ({{ modelValue.length }})
</el-button>
<div v-if="showEmptyTip" class="empty-tip">
{{ emptyTip }}
</div>
<div
v-for="(action, index) in modelValue"
:key="`${prop}-${index}`"
class="action-row"
>
<el-form-item
:prop="`${prop}.${index}.actionType`"
:rules="[{ required: true, message: '请选择操作类型', trigger: 'change' }]"
>
<el-select
v-model="action.actionType"
placeholder="选择操作类型"
style="width: 180px; margin-right: 10px"
>
<el-option value="assignment" label="赋值" />
</el-select>
</el-form-item>
<el-form-item
:prop="`${prop}.${index}.leftValue`"
:rules="[{ required: true, message: '请选择变量', trigger: 'change' }]"
>
<el-select
v-model="action.leftValue"
placeholder="选择变量"
style="width: 180px; margin-right: 10px"
>
<el-option
v-for="opt in variableOptions"
:key="opt.value"
:label="opt.label"
:value="opt.value"
/>
</el-select>
</el-form-item>
<span class="operator">=</span>
<el-form-item
:prop="`${prop}.${index}.rightValue`"
:rules="[{ required: true, message: '请输入值', trigger: 'blur' }]"
>
<el-input
v-model="action.rightValue"
placeholder="输入值"
style="width: 180px; margin-right: 10px"
/>
</el-form-item>
<el-button
type="danger"
link
@click="removeAction(index)"
icon="Delete"
/>
</div>
</div>
</el-form-item>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
modelValue: {
type: Array,
required: true,
default: () => []
},
prop: {
type: String,
required: true
},
label: {
type: String,
default: ''
},
variableOptions: {
type: Array,
default: () => []
},
totalCount: {
type: Number,
default: 0
},
otherCount: {
type: Number,
default: 0
},
emptyTip: {
type: String,
default: '请添加操作'
},
required: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:modelValue'])
const disableAdd = computed(() => {
return props.totalCount >= 20
})
const showEmptyTip = computed(() => {
return props.required && props.modelValue.length === 0
})
const addAction = () => {
const newActions = [...props.modelValue, {
actionType: '',
leftValue: '',
rightValue: ''
}]
emit('update:modelValue', newActions)
}
const removeAction = (index) => {
const newActions = [...props.modelValue]
newActions.splice(index, 1)
emit('update:modelValue', newActions)
}
</script>
<style scoped>
.action-container {
border: 1px solid #dcdfe6;
padding: 12px;
border-radius: 4px;
background-color: #f5f7fa;
}
.action-row {
display: flex;
align-items: center;
margin-top: 10px;
}
.operator {
margin: 0 10px;
font-weight: bold;
color: #606266;
}
.empty-tip {
color: #f56c6c;
font-size: 12px;
margin: 5px 0;
}
</style>
效果:




浙公网安备 33010602011771号