用vue实现拖拽

拖拽

拖拽问题:

  • 1.指令内部 和 按钮操作同一个数据
  • 2.方法之间的沟通

解决方法:

  • 1.指令通过传参来拿到data数据, 事件也能拿到data数据
    点击按钮时数据发生改变,指令的数据也接受到改变,根据值做不同的事件
    通过指令传参,自定义指令中通过binding中的参数value接到参数

  • 2.找同一的挂载点
    bind 和 componentUpdated 有共同的el参数,两者通过el进行数据共享

<div id="app">
        <button @click="canDrag = !canDrag">Drag : {{canDrag}}</button>
        <div class="box" v-drag.limit="canDrag"></div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script>

        Vue.directive('drag', {
            bind(el, {modifiers,value}) {
                let isDragStart = false;
                let disX = 0;
                let disY = 0;
                el.canDrag = value;
                el.addEventListener('mousedown', e => {
                    if (!el.canDrag) return;
                    disX = e.clientX - el.offsetLeft;
                    disY = e.clientY - el.offsetTop;
                    isDragStart = true;

                    e.preventDefault();
                });
                document.addEventListener('mousemove', e => {
                    if (isDragStart) {
                        let x = e.clientX - disX;
                        let y = e.clientY - disY;

                        if (modifiers.limit) {
                            if (x < 0) {
                                x = 0;
                            }
                            if (y < 0) {
                                y = 0;
                            }
                        }

                        el.style.left = x + 'px';
                        el.style.top = y + 'px';
                    }
                });
                document.addEventListener('mouseup', e => {
                    isDragStart = false;
                });
            },
            componentUpdated(el, {value}) {
                console.log('componentUpdated', value);
                el.canDrag = value;
            }
        });
        
        let app = new Vue({
            el: '#app',
            data: {
                canDrag: false
            }
        });
    </script>

钩子函数

指令的运行方式很简单,它提供了一组指令生命周期钩子函数,我们只需要在不同的生命周期钩子函数中进行逻辑处理就可以了

  • bind : 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置

  • inserted : 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)

  • update : 所在组件更新的时候调用

  • componentUpdated : 所在组件更新完成后调用

  • unbind : 只调用一次,指令与元素解绑时调用
    指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。

  • binding:一个对象,包含以下属性:
    1.name:指令名,不包括 v- 前缀。
    2.value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
    3.oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    4.expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
    5.arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
    6.modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
    除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})

new Vue({
  el: '#hook-arguments-example',
  data: {
    message: 'hello!'
  }
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值