vuedraggable官方文档链接使用说明https://www.itxst.com/vue-draggable/re7vfyfe.htmlhttps://www.itxst.com/vue-draggable/re7vfyfe.html
效果图:
使用vuedraggable拖动左边的字段和逻辑到右边形成不同的规则校验
<!--
****--@date 2024-02-01 11:34
****--@author MGD
****--@describe 新增 编辑规则
-->
<template>
<div class="MeetingListAdd">
<template v-if="$route.name==='meetingListTest'">
<el-scrollbar>
<el-container>
<el-aside width="20%" style="overflow-y: auto;height: calc(100vh - 200px)">
<div class="col-field-box">
<el-divider content-position="left">
<div class="title">字段</div>
</el-divider>
<draggable
v-model="arr1"
:group="dragGroup"
:disabled="dragBox"
animation="300"
drag-class="dragClass"
ghost-class="ghostClass"
chosen-class="chosenClass"
@start="onStart"
@end="onEnd"
>
<transition-group>
<div v-for="(item,key) in arr1" :key="key" class="draggable-item">
{{ item.value }}
</div>
</transition-group>
</draggable>
<el-divider content-position="left">
<div class="title">逻辑</div>
</el-divider>
<draggable
v-model="arr3"
:group="dragGroup"
:disabled="dragBox"
animation="300"
drag-class="dragClass"
ghost-class="ghostClass"
chosen-class="chosenClass"
@start="onStart"
@end="onEnd"
>
<transition-group>
<div v-for="(item,key) in arr3" :key="key" class="draggable-item">
{{ item.value }}
</div>
</transition-group>
</draggable>
<el-divider content-position="left">
<div class="title">扩展</div>
</el-divider>
<draggable
v-model="extendVariableArr"
:group="dragGroup"
:disabled="dragBox"
animation="300"
drag-class="dragClass"
ghost-class="ghostClass"
chosen-class="chosenClass"
@start="onStart"
@end="onEnd"
>
<transition-group>
<div v-for="(item,key) in extendVariableArr" :key="key" class="draggable-item">
{{ item.value }}
</div>
</transition-group>
</draggable>
<div style="padding: 20px 0">
<el-form ref="ruleForm" :model="ruleForm" status-icon :rules="rules" label-width="60px" size="mini">
<el-form-item label="key" prop="key">
<el-input v-model="ruleForm.key" placeholder="请输入" />
</el-form-item>
<el-form-item label="value" prop="value">
<el-input v-model="ruleForm.value" placeholder="请输入" />
</el-form-item>
<el-form-item>
<el-button size="mini" icon="el-icon-refresh-right" @click="resetForm('ruleForm')">重置</el-button>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="submitForm('ruleForm')">保存</el-button>
</el-form-item>
</el-form>
</div>
</div>
</el-aside>
<el-container>
<el-main width="80%">
<div class="rule-field-box">
<el-divider content-position="left">
<div class="title">规则<span>(向左边拖入对应字段进行规则添加)</span></div>
</el-divider>
<draggable
v-model="saveRuleArr"
group="sameDraggable"
animation="300"
drag-class="dragClass"
ghost-class="ghostClass"
chosen-class="chosenClass"
:scroll="true"
>
<transition-group class="transition-box">
<div v-for="(item, index) in saveRuleArr" :key="index" class="rule-item">
{{ item.value }}
<div class="close-box" @click="handleDel(index)">
<i class="el-icon-error" />
</div>
</div>
</transition-group>
</draggable>
<div v-if="!saveRuleArr.length" class="empty-box">
<el-empty :image-size="150" description="向左边拖入对应字段进行规则添加" />
</div>
</div>
</el-main>
<el-footer>
<div class="button-box">
<el-button class="resetting" type="danger" icon="el-icon-refresh-right" @click="saveRuleArr = []">重置</el-button>
<el-button class="submit" type="primary" icon="el-icon-edit-outline" :loading="buttonLoading" :disabled="!saveRuleArr.length" @click="handleSave()">保存</el-button>
</div>
</el-footer>
</el-container>
</el-container>
</el-scrollbar>
</template>
<template v-else>
<router-view />
</template>
</div>
</template>
<script>
import Draggable from 'vuedraggable'
export default {
name: 'MeetingListAdd',
components: { Draggable },
mixins: [],
data() {
return {
buttonLoading: false,
dragBox: false,
dragGroup: {
name: 'sameDraggable',
put: false, // true|false|array|function,//是否允许拖入当前组
pull: 'clone'// true|false| 'clone'|array|function,//是否允许拖出当前组
},
ruleForm: {
value: '',
key: ''
},
rules: {
value: [{ required: true, message: '请输入', trigger: 'blur' }],
key: [{ required: true, message: '请输入', trigger: 'blur' }]
},
// 定义要被拖拽对象的数组
arr1: [
{ key: 1, value: '字段1' },
{ key: 2, value: '字段2' },
{ key: 3, value: '字段3' },
{ key: 4, value: '字段4' },
{ key: 5, value: '字段5' }
],
arr3: [
{ key: 1, value: '且' },
{ key: 2, value: '或' },
{ key: 3, value: '非' },
{ key: 4, value: '>' },
{ key: 5, value: '<' },
{ key: 6, value: '=' },
{ key: 7, value: '包含' },
{ key: 8, value: '不包含' }
],
extendVariableArr: [], // 扩展变量
saveRuleArr: [] // 规则空数组
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
// 开始拖拽事件
onStart() {
console.log('=========拖拽开始========')
this.dragBox = true
},
// 拖拽结束事件
onEnd() {
console.log('=======拖拽结束==========')
this.dragBox = false
},
// 删除
handleDel(index) {
this.saveRuleArr.splice(index, 1)
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
const submitInfo = JSON.parse(JSON.stringify(this.ruleForm))
this.extendVariableArr.push(submitInfo)
this.resetForm(formName)
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
// 保存
handleSave() {
console.log(this.saveRuleArr, '==============================规则数据')
}
}
}
</script>
<style lang="scss">
.MeetingListAdd {
height: 100%;
padding: 20px;
.el-scrollbar {
height: 100%;
width: 100%;
overflow-x: hidden;
.el-scrollbar__view {
overflow-x: hidden;
}
.el-scrollbar__wrap {
overflow-x: hidden;
}
}
/*定义要拖拽元素的样式*/
.ghostClass {
display: inline-block;
background-color: #CCE4FF !important;
}
.chosenClass {
padding: 12px;
color: #fff;
display: inline-block;
background-color: #7eb8ff !important;
opacity: 1 !important;
}
.dragClass {
padding: 6px 12px !important;
display: inline-block;
background-color: #CCE4FF !important;
opacity: 1 !important;
box-shadow: none !important;
outline: none !important;
background-image: none !important;
border-radius: 0 !important;
}
.col-field-box {
.title {
padding: 12px 0;
font-size: 18px;
font-weight: bold;
color: #333;
}
.draggable-item {
min-width: 60px;
text-align: center;
margin: 0 8px 8px;
padding: 6px 12px;
display: inline-block;
border-radius: 20px;
color: #fff;
font-size: 14px;
cursor: pointer;
background: linear-gradient(180deg, rgb(107, 145, 218) 0%, rgba(24, 144, 242, 1) 100%);
box-shadow:inset 2px 0 18px rgba(107, 145, 218, 1),inset 0 5px 10px rgba(247, 247, 247, 1);
}
.draggable-item:hover {
background-color: #fdfdfd;
cursor: move;
}
.draggable-item+.draggable-item {
border-top: none;
margin-top: 6px;
}
}
.rule-field-box {
position: relative;
height: calc(100vh - 300px);
padding: 0 12px;
border-radius: 20px;
.title {
padding: 12px 0;
font-size: 18px;
font-weight: bold;
color: #333;
span {
font-weight: normal;
font-size: 14px;
color: #FA8C1E;
}
}
.transition-box {
padding: 12px;
display: block;
height: 60vh;
background: #2b2b2b;
border-radius: 12px;
overflow-y: auto;
}
.empty-box {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
.el-empty__description p {
color: #eee;
font-size: 16px;
}
}
.rule-item {
min-width: 35px;
text-align: center;
position: relative;
font-size: 16px;
display: inline-block;
padding: 12px 4px;
color: #fff;
background: #323232;
flex-wrap: wrap;
.close-box {
display: none;
position: absolute;
top: -5px;
right: -5px;
cursor: pointer;
}
}
.rule-item:hover .close-box {
display: inline-block;
z-index: 1;
}
.rule-item:hover {
background-color: #6b6b6b;
cursor: move;
}
.rule-item+.rule-item {
border-top: none;
margin-top: 6px;
}
}
.button-box {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
.resetting,.submit {
padding: 12px 0;
font-size: 18px;
width: 160px;
border-radius: 6px;
border: none;
background: #2482ED;
}
.resetting {
background: #fff;
color: #2482ED;
border: 1px solid #2482ED;
}
}
}
</style>