Vue实现自定义拖拽指令

一、展示效果

拖拽

二、代码实现

(1)自定义全局指令

src目录下的utils文件夹下创建candrag.js文件

// candrag.js中的代码如下
export default {
    // 定义 Vue 插件
    install(Vue) {
        Vue.directive('candrag', {
            // 全局指令名为 v-candrag
            inserted(el) {
                el.onmousedown = function(ev) {
                    // 获取鼠标按下时的偏移量(鼠标位置 - 元素位置)
                    const disX = ev.clientX - el.offsetLeft
                    const disY = ev.clientY - el.offsetTop
                    document.onmousemove = function(ev) {
                        // 获取鼠标实时移动时,元素的位置(鼠标实时位置 - 偏移量)
                        const l = ev.clientX - disX
                        const t = ev.clientY - disY
                        // 实时设置元素位置
                        el.style.left = l + 'px'
                        el.style.top = t + 'px'
                    }
                    document.onmouseup = function() {
                        // 鼠标抬起时,销毁移动事件和鼠标抬起事件
                        document.onmousemove = null
                        document.onmouseup = null
                    }
                }
            }
        })
    }
}

(2)引用指令

main.js文件中引入并注册指令

// main.js中代码
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
import candrag from '@/utils/candrag.js' // 引入指令

Vue.use(candrag) //使用并注册指令

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

(3)使用指令

// 使用指令,指令为v-candrag,在想要进行拖拽的地方使用v-candrag即可进行拖拽
<template>
    <el-dialog
        v-candrag
        :title="textMap[dialogStatus] + '组织机构'"
        width="480px"
        :visible="dialogVisible"
        :close-on-click-modal="false"
        :close-on-click-escape="false"
        @closed="onDialogClosed"
        @open="onDialogOpen"
        @close="onDialogClose"
    >
        <el-form
            ref="dataForm"
            v-loading="formLoading"
            :rules="rules"
            :model="temp"
            size="mini"
            label-position="right"
            label-width="80px"
            style="width: 440px; margin-left: 15px"
        >
            <el-form-item label="名称" prop="departName">
                <el-input
                    v-model="temp.departName"
                    style="width: 300px"
                    maxlength="20"
                    show-word-limit
                />
            </el-form-item>
            <el-form-item label="部门类型" prop="departType">
                <el-select
                    v-model="temp.departType"
                    placeholder="请选择..."
                    clearable
                    filterable
                    style="width: 300px"
                >
                    <el-option
                        v-for="item in $store.state.dic.departType"
                        :key="item.key"
                        :label="item.value"
                        :value="item.key"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="地理位置" prop="address">
                <el-input
                    v-model.number="posComp"
                    style="width: 300px"
                    :readonly="true"
                    placeholder="请选择..."
                    @focus="dialogPosVisible = true"
                >
                    <i slot="suffix" style="margin-right: 5px">
                        <el-button
                            size="mini"
                            type="primary"
                            plain
                            icon="el-icon-location"
                            class="btn-address"
                            @click="dialogPosVisible = true"
                        />
                    </i>
                </el-input>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button
                type="primary"
                @click="dialogStatus === 'create' ? createData() : updateData()"
            >
                保存
            </el-button>
            <el-button style="margin-right: 50px" @click="dialogVisible = false"> 取消 </el-button>
        </div>
        <pos-dialog :show.sync="dialogPosVisible" :pos.sync="temp.address" type="depart" />
    </el-dialog>
</template>
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值