解决 vue.draggable 拖拽 点击事件失效无效与拖拽事件冲突的问题

Posted 狼丶宇先森

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决 vue.draggable 拖拽 点击事件失效无效与拖拽事件冲突的问题相关的知识,希望对你有一定的参考价值。

draggable 是个非常不错,而且很方便的拖拽组件,但是你在项目中可能会遇到被包裹的拖拽元素对象的点击事件失效的问题,事件冲突了.先看代码示例,再看解决思路及方法.

安装使用:

yarn add vuedraggable

或者

npm i -S vuedraggable

github: https://github.com/SortableJS/Vue.Draggable

 

1. 被拖拽组件的父组件 Warp.vue

<template>
    <draggable v-model="sendData.template" class="app-form-items" @change="handleDraggableFormItemChange">
        <template v-for="(item,index) in sendData.template">
            <app-form-item
                :key="index"
                :active="formItemActiveIndex == index"
                @selected="handleControlSelected(item,index)"
                @delete="handleControlDelete(item,index)"
            >
                 item.name 
            </app-form-item>
        </template>
    </draggable>
</template>
<script>
import draggable from 'vuedraggable';
import AppFormItem from './AppFormItem';
export default 
    components: 
        draggable,
        AppFormItem
    ,
    data() 
        return 
            sendData: 
                template: [name:'拖拽对象1',name:'拖拽对象2',name:'拖拽对象3'] //模板列表
            
        ;
    ,
    methods: 

        /**
         * 拖拽控件
         */
        handleDraggableFormItemChange(e) 
            console.log(`拖拽回调:`, e);
        ,

        /**
         * 选中控件
         */
        handleControlSelected(data, index) 
            console.log(`handleControlSelected 选中控件:`, data, index);
        ,

        /**
         * 移除控件
         */
        handleControlDelete(data, index) 
            console.log(`handleControlDelete 移除控件:`, data, index);
        
    
;
</script>
<style lang="less" scoped>
.app-create-form
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    .create-edit
        flex: 1;
        .app-mobile-editor
            margin: 0 auto;
            .app-form-warp
                height: 100%;
                .app-form-items
                    height: calc(100% - 46px) ;
                    overflow: auto;
                    .app-form-item
                        cursor: move;
                        font-size: 14px;
                    
                
            
        
    

</style>

2. 拖拽的组件对象 AppFormItem.vue

<template>
    <div class="app-form-item" :class="'app-item-selected': active" @click.stop.prevent="handleClick()">
        <span class="del-btn" title="移除控件" @click.stop.prevent="handleDel()">
            <i class="iconfont iconquxiao" />
        </span>
        <slot />
    </div>
</template>
<script>
export default 
    name: 'AppFormItem',
    props: 
        active: 
            type: Boolean,
            required: false,
            default: false
        
    ,
    methods: 
        handleClick() 
            this.$emit('selected');
        ,
        handleDel() 
            this.$emit('delete');
        
    
;
</script>
<style lang="less" scoped>
.app-form-item
    background: #fff;
    padding: 16px 20px;
    border: 1px solid #fff;
    & + .app-form-item
        margin-top: 10px;
    
    .del-btn
        display: none;
    

.app-item-selected
    position: relative;
    border: 1px solid #f00;
    .del-btn
        display: flex;
        width: 18px;
        height: 18px;
        align-items: center;
        justify-content: center;
        position: absolute;
        right: 0;
        top: 0;
        color: #fff;
        background: #f00;
        cursor: pointer;
        border-radius: 0 0 0 2px;
        z-index: 99;
        &:hover
            opacity: .8;
        
        i
            font-size: 12px;
        
    

</style>

实际应用效果:

 

重点来了:

解决直接绑定点击事件与拖拽事件冲突,可以使用封装子组件的形式,在子组件触发点击事件,然后在父组件使用子组件触发事件的回调即可.如果你的被拖拽对象上面有很多个元素有绑定事件,那么你需要使用.stop和.prevent修饰符来禁止默认事件和冒泡.

如果你有更好的方法,可留言分享交流.

 

网友的其它解决方案分享留言:

qq_34854119:这个拖动插件有一个属性distance, 默认值是0, 把点击事件识别成了拖动事件了, 如果把它的值设置成>0的数, 自己的组件就可以响应点击事件了.

1.这个拖动插件有一个属性distance, 默认值是0, 把点击事件识别成了拖动事件了, 如果把它的值设置成>0的数, 自己的组件就可以响应点击事件了

<slick-list lockAxis="y" v-model="allData" @input="sortResult" :distance="1">

 

以上是关于解决 vue.draggable 拖拽 点击事件失效无效与拖拽事件冲突的问题的主要内容,如果未能解决你的问题,请参考以下文章

vue draggable 火狐拖拽搜索问题

vue.draggable拖拽组件中用transition-group包裹拖拽组件了,拖拽还是没有动画?

Vue.Draggable学习总结

Vue.Draggable 心得

Vue.Draggable 心得

Vue.Draggable 心得