前端拖拽编辑功能

https://blog.csdn.net/weixin_41646716/article/details/82905765

<1>安装

通过NPM安装

$ npm install awe-dnd --save

插件应用
在main.js中,通过Vue.use导入插件

import VueDND from 'awe-dnd'
 
Vue.use(VueDND)

在你的vue文件中这样引用

<script>
export default {
  data () {
    return {
        colors: [{
            text: "Aquamarine"
        }, {
            text: "Hotpink"
        }, {
            text: "Gold"
        }, {
            text: "Crimson"
        }, {
            text: "Blueviolet"
        }, {
            text: "Lightblue"
        }, {
            text: "Cornflowerblue"
        }, {
            text: "Skyblue"
        }, {
            text: "Burlywood"
        }]
    }
  }
}
</script>
 
<template>
  <div class="color-list">
      <div 
          class="color-item" 
          v-for="color in colors" v-dragging="{ item: color, list: colors, group: 'color' }"
          :key="color.text"
      >{{color.text}}</div>
  </div>
</template>

vue2.0的使用方式

<div class="color-list">
    <div 
        class="color-item" 
        v-for="color in colors" v-dragging="{ item: color, list: colors, group: 'color' }"
        :key="color.text"
    >{{color.text}}</div>
</div>

vue1.0的使用方式

<div class="color-list">
    <div 
        class="color-item" 
        v-for="color in colors" v-dragging="{ item: color, list: colors, group: 'color', key: color.text }"
        track-by="text"
    >{{color.text}}</div>
</div>

添加事件

<div class="color-list">
    <div 
        class="color-item" 
        v-for="color in colors" v-dragging="{ item: color, list: colors, group: 'color', otherData: otherData }"
        :key="color.text"
    >{{color.text}}</div>
</div>

export default {
  mounted () {
    this.$dragging.$on('dragged', ({ value }) => {
      console.log(value.item)
      console.log(value.list)
      console.log(value.otherData)
    })
    this.$dragging.$on('dragend', () => {
        
    })
  }
}

组件参数
名称类型默认值说明


image.png

<2>vue 组件排列顺序

安装

npm install awe-dnd --save

main.js

import VueDND from 'awe-dnd'
 
Vue.use(VueDND)

sortable.vue

排序完后的操作挺重要的,因为我们一般排序完要重新提交排序后的数据给后台保存,以便下一次安装我们所需要的顺序显示,这里的list就可以帮我们做到这一点,但是我们需要给数据添加一个uniqueId标志。然后在排序完后或者列表对应的顺序和uniqueId提交给后台,我也不知道我说的你们能理解吗,反正你们也可以打印出来看看。

image.png

<3>

https://blog.csdn.net/u011384023/article/details/79762299

<4>

一个基于 Sortable.js 的vue拖拽插件 支持触屏操作 自动适应 draggable组件的v-model属性实现双向绑定。 如果要多个盒子互相拖拽,需定义options,将其group属性定义为同一个值即可 源码如下:

image.png

一个基于Sortable.js的vue拖拽插件
支持触屏操作
自动适应

image.png
image.png

就是这种感觉

draggable组件的v-model属性实现双向绑定。
如果要多个盒子互相拖拽,需定义options,将其group属性定义为同一个值即可
源码如下:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Document</title>

<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>

<script src="http://cdn.jsdelivr.net/npm/sortablejs@1.7.0/Sortable.min.js"></script>

 

<script src="http://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.15.0/vuedraggable.min.js"></script>

</head>

<body>

<div id="tuozhuai_view">

<!--  -->

<draggable  v-model="fruit" :options="{group:'people'}">

  <div v-for="element in fruit">{{element}}</div>

</draggable>

{{fruit}}

<br>

<br>

<draggable  v-model="girl" :options="{group:'people'}">

  <div v-for="element in girl">{{element}}</div>

</draggable>

{{girl}}

</div>

 

<script type="text/javascript">

new Vue({

el:'#tuozhuai_view',

data:{

fruit:['apple','banana','orage'],

girl:['linzhil','cjk','bdyjy'],

}

})

</script>

</body>

</html>

<5>https://blog.csdn.net/qq_40882724/article/details/80798135

:翻看vue文档发现可以注册全局指令,用于DOM元素的底层处理,这个挺靠谱。

Vue.directive( 指令名,{ 钩子函数 } )
image.png

3.思路:很简单:首先记录整个对话框距离文档边界的左边距和上边距(当然你监听右边距也oK的,但是别监听下边距,因为我们一般是设置上边距,饿了么也是如此。正如我们调整高度时,会说往下拉一点,或者往上去一点)。鼠标按下的时候监听mousedown事件,记录鼠标距离对话框边界的距离(左边距LEFT,上边距TOP).然后监听document的mousemove事件,因为我们不可能确保我们的鼠标一直都在框中拖拽,因为我们速度有慢有快,在mousemove中保证鼠标与对话框的位置跟mousedown时一致。鼠标mouseup时移除mousemove和mouseup的监听,下次对话框打开时再把它的位置还原如初。

image.png

5.贴上代码:

import Vue from 'vue'

let LEFT;

let TOP;

//指令的传参形式为<dialogo v-dialogdrag=" { target:'selector',container:'.box',dialogVisible:"传入对话框的visible变量" } "></dialog>

Vue.directive('dialogdrag',{

inserted(el,binding){

let container = el.querySelector(binding.value.container);

let target = el.querySelector(binding.value.target);

 
 
let temContainerWidth = getComputedStyle(container).width;

let temHtmlWidth = getComputedStyle(document.firstElementChild).width;

if(temContainerWidth.indexOf('%') != -1){

//百分值

LEFT = (

parseFloat(temHtmlWidth) -

parseFloat(temHtmlWidth) * temContainerWidth.substring(0,temContainerWidth.length-1)/100

)/2;

}else if(temContainerWidth.indexOf('px') != -1){

//像素值

LEFT = (

parseFloat(temHtmlWidth) -

parseFloat(temContainerWidth)

)/2;

}else{

//其他值

throw ('对话框容器宽度只能为像素或百分比!')

}

console.log(temContainerWidth);

console.log(temHtmlWidth);

//

let temMarginTop = getComputedStyle(container).marginTop;

if(temMarginTop && temMarginTop.indexOf('px') != -1){

//不为空并且以像素为单位

TOP = parseFloat(temMarginTop);

}else{

throw ('请设置对话框容器上边距margin-top并以像素为单位!')

}

console.log(LEFT)

//删除对话容器的行内样式(marginleft,margintop,marginbottom,marginrigth);

delete container.style.marginTop;

delete container.style.marginLeft;

delete container.style.marginRight;

delete container.style.marginBottom;

delete container.style.margin;

//赋值给marginTop;marginLeft;

container.style.marginTop = TOP+'px';

container.style.marginLeft = LEFT+'px';

 
//事件监听

target.addEventListener('mousedown',function(event){

//获取鼠标距离对话框容器的左上边距

let leftValue = event.clientX - parseFloat(getComputedStyle(container).marginLeft);

let topValue = event.clientY - parseFloat(getComputedStyle(container).marginTop);

document.addEventListener('mousemove',moveFn,true)

document.addEventListener('mouseup',upFn,true)

function moveFn(event){

console.log('还在移动')

target.style.cursor = 'move';

container.style.marginLeft = (event.clientX-leftValue)+'px';

container.style.marginTop = (event.clientY-topValue)+'px';

 
}

function upFn(event){

target.style.cursor = 'default';

document.removeEventListener('mousemove',moveFn,true);

//document.removeEventListener('mouseup',upFn);

}

})

},

componentUpdated(el,binding){

if(binding.value.dialogVisible){

//打开时还原对话框位置

el.querySelector(binding.value.container).style.marginTop = TOP+'px';

 
el.querySelector(binding.value.container).style.marginLeft = LEFT+'px';

 
}

}

})
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,175评论 0 1
  • 简说Vue (组件库) https://github.com/ElemeFE/element" 饿了么出品的VUE...
    Estrus丶阅读 1,805评论 0 1
  • UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组...
    鲁大师666阅读 43,486评论 5 97
  • Vue2.0+组件库总结 UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基...
    szch阅读 1,981评论 1 52
  • 李坚已经一个小时没碰手机了,他在屋里转来转去 时间对他来说过得过分地慢,他随手拿起一本书翻了两页又随手扔一边 抬头...
    一派荒唐之癸巳年间阅读 481评论 0 1