【发布时间】:2020-03-31 09:27:37
【问题描述】:
背景
我按照以下指南创建了一个自定义指令(用于检测元素外部的点击):https://tahazsh.com/detect-outside-click-in-vue。
元素:
<button
id='burger'
ref='burger'
class='burger button is-white'>
<span class='burger-top' aria-hidden='true' style='pointer-events: none;'></span>
<span class='burger-bottom' aria-hidden='true' style='pointer-events: none;'></span>
</button>
指令:
import Vue from 'vue';
let handleOutsideClick;
Vue.directive('outside', {
bind(el, binding, vnode) {
setTimeout(() => {
handleOutsideClick = (e) => {
e.stopPropagation();
const { handler, exclude } = binding.value;
let clickedOnExcludedEl = false;
exclude.forEach((refName) => {
if (!clickedOnExcludedEl) {
const excludedEl = vnode.context.$refs[refName]
console.log(vnode.context.$refs);
clickedOnExcludedEl = excludedEl.contains(e.target);
}
});
if (!el.contains(e.target) && !clickedOnExcludedEl) {
vnode.context[handler]();
}
};
document.addEventListener('click', handleOutsideClick);
document.addEventListener('touchstart', handleOutsideClick);
}, 50);
},
unbind() {
document.removeEventListener('click', handleOutsideClick);
document.removeEventListener('touchstart', handleOutsideClick);
},
});
请注意,我必须添加 setTimeout。
在侧边栏组件中使用指令:
<div
id='sidebar'
class='sidebar-container'
v-show='toggleSideBar'
v-outside='{
handler: "close",
exclude: [
"burger",
],
}'>
<div class='sidebar-content'>
// other content
</div>
</div>
问题
$refs 为空,即使该元素显然有一个 ref。
console.log(vnode.context.$refs); 也清楚这一点。
值得注意的是,通过 id 获取元素是可行的:
exclude.forEach((id) => {
if (!clickedOnExcludedEl) {
const excludedEl = document.getElementById(id);
clickedOnExcludedEl = excludedEl.contains(e.target);
}
});
问题
为什么$refs元素明确存在且可以通过id访问时为空?
【问题讨论】:
-
你有什么错误?
-
您能否向我们展示采用此指令的完整标签标记?
-
更新了我的帖子。汉堡在导航栏中。单击它将打开/关闭侧边栏。此处指令的要点是允许通过单击侧边栏外部来关闭侧边栏。
标签: vue.js vuejs2 vue-directives