赞
踩
此功能的来源来自于当时需要制作一个便于客户操作的打印设计功能,然后就有了这个项目。这个帖子主要是用于分享与谈论,相互学习。
当全部功能整理完毕后,会把此demo开源
设计
预览
显示主要是使用了在page这个div上相对定位(position: relative;),里面的组件使用绝对定位(position: absolute;)使用top和left来绑定x坐标与y坐标即可。
这里使用了vue中的component标签来v-for动态生成组件,这个具体的后面会说明
- <component
- :is="moduleData.type"
- :com="moduleData"
- :class="[moduleData.isSelect && moduleData.config.isChildren? 'active':'']"
- :data-title="moduleData.type"
- :key="moduleData.uuid"
- :val="moduleData"
- class="layer"
- ></component>
拖拽移动主要使用了@mousedown获取点击的元素是否是组件,(这个我就是通过在组件html原始上绑定data-xxx属性来判断的)如果是组件就给组件元素或者在页面上绑定一个mousemove事件(这里选择的是在页面上绑定),当鼠标mouseup时移除事件即可
关键代码:
- handleMouseDown(e){
-
- // 如果没有选中组件 在画布上点击时需要调用 e.preventDefault() 防止触发 drop 事件
- if(recursionGetSelectCom(this.$vptd.state.page.tempItems).length===0)
- e.preventDefault()
-
-
- var target = this.selectTarget(e.target)
- //判断是不是选中了组件,如果是组件不向下执行
- if (target) {
- e.stopPropagation()
- e.preventDefault()
- var uuid = target.getAttribute('data-uuid')
- // 设置选中元素
- this.$vptd.commit('select', {
- uuid: uuid,
- })
- // 绑定移动事件:除背景图以外的元件才能移动
- let element = recursionGetSelectCom(this.$vptd.state.page.tempItems).filter(i=>i.uuid===uuid)
-
- if (element.length > 0 && element[0].config.dragable) {
- //绑定选中com事件
- this.initmovement(e,element[0]) // 参见 mixins
- return
- }
- }
-
-
- this.hideArea()
- // 获取编辑器的位移信息,每次点击时都需要获取一次。主要是为了方便开发时调试用。
- const rectInfo = this.$refs.edit.getBoundingClientRect()
- this.editorX = rectInfo.x
- this.editorY = rectInfo.y
-
- const startX = e.clientX
- const startY = e.clientY
- this.start.x = startX - this.editorX
- this.start.y = startY - this.editorY
- // 展示选中区域
- this.isShowArea = true
-
- const move = (moveEvent) => {
- this.width = Math.abs(moveEvent.clientX - startX)
- this.height = Math.abs(moveEvent.clientY - startY)
- if (moveEvent.clientX < startX) {
- this.start.x = moveEvent.clientX - this.editorX
- }
-
- if (moveEvent.clientY < startY) {
- this.start.y = moveEvent.clientY - this.editorY
- }
- }
-
- const up = (e) => {
- document.removeEventListener('mousemove', move)
- document.removeEventListener('mouseup', up)
-
- if (e.clientX === startX && e.clientY === startY) {
- console.log("鼠标未移动,取消选中")
- this.$vptd.commit('setSelectElement', [])
- }else {
- //获取选中的组件然后给选中组件中的isSelect值进行改变
- console.log("鼠标框选")
- this.$vptd.commit('setSelectElement', this.getSelectArea())
- }
-
- this.hideArea()
- }
-
- document.addEventListener('mousemove', move)
- document.addEventListener('mouseup', up)
- },
其中主要是用了@dragstart与@drop与@dragover方法
组件列表:html
- <div class="item"
- :key="index"
- :draggable="true"
- @dragstart="dragStart($event, index)"
- @click="(e) => {addTempItem(e,item)}">
- <span :style="{fontWeight:item.config.isEdit? 'bold':'',fontStyle:item.config.isEdit? '':'italic'}">{{ item.title }}</span>
- </div>
组件列表:js
- methods: {
- // 添加组件
- addTempItem (e, item) {
- this.$vptd.dispatch('addTempItem', item)
- },
- dragStart (ev, index) {
- ev.dataTransfer.setData('index', index)
- }
- },
设计页面html
- <div
- :style="{
- height: '100px',
- width: '100px',
-
- }"
- ref="edit"
- class="screen"
- @dragover.prevent="dragOver"
- @drop="dropToAddCom($event)"
- @mousedown="handleMouseDown"
- >
- </div>
设计页面js
- dragOver(ev){
- ev.preventDefault()
- },
- dropToAddCom(ev){
- ev.preventDefault()
- const rest = this.$refs.edit.getBoundingClientRect();
- this.$vptd.dispatch('addTempItemByIndex',
- { index : ev.dataTransfer.getData('index'),
- x: Math.round(ev.clientX-rest.x),
- y :Math.round(ev.clientY-rest.y)
- })
- },
以上就是组件拖拽添加与在page上的拖拽设计,以上代码都不可直接使用,因为代码不全,仅仅能提供参考,或者自行修改也可
后续的更新等我忙完这段时间了补上。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。