需求:
想要实现这样的一个需求,左边是组件库。中间是展示。拖拉组件到中间就形成一个组件。
刚开始用的form-create,发现不行,又用的form-create-design,但vue3版本的只有element plus库,系统刚开始用的ant-design,而且左边我只需要单行输入框和多行输入框组件就够了,有点用宰牛刀的感觉,而且右侧还不能自定义,看悟空CRM的源码看的头大,他还是用的vue2版本+element ui,只能自己撸一了。
刚开始也是看的vuedraggable文档,https://www.itxst.com/vue-draggable-next/tutorial.html,看了半天没看懂,写了个锤子。
后面找啊找,终于找到了一篇让我搞清了逻辑;https://blog.csdn.net/qq_38686683/article/details/129732531,按这个一步步写最终也出来了,这个文章看一下,改下option,另一篇又看下又改下option。搞到最后啥都没有,空白页一个。啊!差点要疯了
安装
npm i -S vuedraggable@next //导入 import draggable from 'vuedraggable'
直接在使用页面导入,因为刚开始文件改了删,删了改,结果一直报错,后面才发现没引入。。。
首先建立三个div,分别展示上图的内容
Vue3版本里不允许在里面进行for循环了,要用<template #item="{ element }"></template>,element 不能随意修改,就是for循环迭代的item
左侧draggable配置:
<draggable :list="leftMenu" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }" :sort="false" itemKey="id" > <template #item="{ element }"> <div class="item move"> <a-button > <template #icon v-if="element.type === 'Input'"><edit-outlined /></template> <template #icon v-if="element.type === 'Textarea'"><ordered-list-outlined /></template> {{ element.name }} </a-button> </div> </template> </draggable>
JS
// 左侧组件菜单 const leftMenu = reactive([ { name: "单行文本", id: 1, type: 'Input' }, { name: "多行文本", id: 2, type: 'Textarea' }, ])
然后这样左侧的菜单就显示了,a-button里是根据name生成不同的icon,icon使用记得引入下,element就看下他的按钮图标怎么用的
import {
EditOutlined,
OrderedListOutlined
} from '@ant-design/icons-vue'
中间draggable:
<draggable :list="centerData" ghost-class="ghost" itemKey="id" :force-fallback="true" group="list" :fallback-class="true" :fallback-on-body="true" class="draggable" > <template #item="{element}"> <div class="item move"> <label class="move">{{ element.name }}</label> <div> <el-input v-model="input" placeholder="请输入" @focus="focusInput(element.name)" v-if="element.type === 'Input'" /></div> <div> <el-input v-model="textarea" :rows="2" type="textarea" @focus="focusInput(element.name)" placeholder="Please input" v-if="element.type === 'Textarea'" /> </div> </div> </template> </draggable>
template写要展示的组件,然后根据name来控制显隐,左边拖进去的数据就会添加到centerData里,然后遍历判断就可以了,组件少可以这么搞,组件多的建议使用component标签来映射,可以看上边的第二个链接,反正原理现在就弄明白了,右边还在搞,搞完更新
JS
// 中间数据 const centerData = reactive([]) // 鼠标聚焦输入框时,显示右侧内容 const focusInput = (titleName: string) => { rightTitle.value = titleName }