Open AnnVoV opened 6 years ago
$emit
重点问题 现象:遇到的问题,在指令里emit 的时候,我的自定义参数通过$emit带不出去?
原因: 本质原因不是参数无法带出去,而是我搞错了我的指令里ctx.$emit的指向, 也就是说ctx.emit是谁抛出的
ctx.$emit
// 看下我写的模板 // hotzone/index.vue <template> <div class="hotzone-container"> <section v-touchdir="hotzoneList"> </section> </div> </template> // APP.vue // 使用了上面的组件 <hotzone-drag></hotzone-drag> // hotzone/index.js // 我在mousestart的时候,写了下面的事件 handler = { mousedown: function(e) { // 我这里emit 了selectstart事件,我以为我的selectstart事件是从hotzone-container 上emit的,这个ctx指向的是components context,所以其实是hotzone-drag这个组件在emit,所以接受这个事件的也是hotzone-drag这个组件 ctx.$emit('selectstart', {...}); } };
定向emit: 某些情况我们需要设置我们接受事件的target,就可以考虑使用自定义事件来new CustomEvent() 和 dispatchEvent 解决方法:目前是通过自定义事件做的 参考:https://github.com/vuejs/vue/issues/7147
new CustomEvent()
dispatchEvent
event = new CustomEvent('addhotzone', dragPos) target.dispatchEvent(event)
指令外部与指令内部需要传递一些数据,我们则可以通过v-bindDir:xxx 这种方式来绑定数据或者函数
举个例子: 外部使用热区组件时,会维护一个hotzoneList,来维护当前的热区数组;当点击删除按钮时,可能会删除hotzoneList对应的某个元素;此时我们需要让指令内部知道我们的hotzoneList发生了变化,那我们可以这样
<section class="hotzone" :style="{backgroundImage: `url( ${imgUrl})`, width: `${containerWidth}px`, height: `${containerHeight}px`, backgroundSize: 'cover'}" v-touchdir="hotzoneList" @addhotzone="addZone" @selectstart="selectStart" @selectup="changeZone"></section> // 然后在指令内部的update方法里 export default { bind (el, binding, vnode) { bindEvent(el, vnode.context, vnode) }, update(el, binding, vnode) { allHotzone = binding.value && binding.value.length || 0; }, unbind (el) { offEvent(el) } }
本质是对Node.contains 这个api不熟悉, 这个方法很常用 看下v-clickoutside 这个判断的实现 https://github.com/varHarrie/varharrie.github.io/issues/4
export defult { bind(el, binding, vnode) { this.click = (e) => { return !el.contains(e.target); } document.body.addEventListener('click', this.click) } update() { } unbind(el) { document.body.removeEventListener('click', this.click) } }
1.拖拽实现思路
2.指令里
$emit
为什么不如预期重点问题 现象:遇到的问题,在指令里emit 的时候,我的自定义参数通过
$emit
带不出去?原因: 本质原因不是参数无法带出去,而是我搞错了我的指令里
ctx.$emit
的指向, 也就是说ctx.emit是谁抛出的定向emit: 某些情况我们需要设置我们接受事件的target,就可以考虑使用自定义事件来
new CustomEvent()
和dispatchEvent
解决方法:目前是通过自定义事件做的 参考:https://github.com/vuejs/vue/issues/71473.v-bindDir:xxx
指令外部与指令内部需要传递一些数据,我们则可以通过v-bindDir:xxx 这种方式来绑定数据或者函数
举个例子: 外部使用热区组件时,会维护一个hotzoneList,来维护当前的热区数组;当点击删除按钮时,可能会删除hotzoneList对应的某个元素;此时我们需要让指令内部知道我们的hotzoneList发生了变化,那我们可以这样
4.clickoutside 的判断方法
本质是对Node.contains 这个api不熟悉, 这个方法很常用 看下v-clickoutside 这个判断的实现 https://github.com/varHarrie/varharrie.github.io/issues/4