Vue.js 自定义指令使用 TypeScript 检测点击外部元素
Posted
技术标签:
【中文标题】Vue.js 自定义指令使用 TypeScript 检测点击外部元素【英文标题】:Vue.js custom directive detecting click outside element with TypeScript 【发布时间】:2020-08-27 01:42:24 【问题描述】:我正在尝试使用此示例创建自定义指令:https://***.com/a/42389266/5470563
main.ts 文件:
import Vue from 'vue';
import HeaderNav from './components/HeaderNav.vue'
Vue.directive('click-outside',
bind: function (el, binding, vnode)
el.clickOutsideEvent = function (event)
// here I check that click was outside the el and his childrens
if (!(el == event.target || el.contains(event.target)))
// and if it did, call method provided in attribute value
vnode.context[binding.expression](event);
;
document.body.addEventListener('click', el.clickOutsideEvent)
,
unbind: function (el)
document.body.removeEventListener('click', el.clickOutsideEvent)
,
);
new Vue(
el: '#app',
components:
HeaderNav
);
我得到一个编译错误:
“htmlElement”类型上不存在属性“clickOutsideEvent”。
我该如何解决?或者有没有更好的解决方案来绑定外部元素点击事件?
【问题讨论】:
【参考方案1】:你有两个选择
将bind
、unbind
函数中的el
参数转换为any
。
bind: function (el: any, binding, vnode)
unbind: function (el: any)
扩展HTMLElement
接口。
你可以把它放在指令声明之前。
interface HTMLElement
clickOutsideEvent: () => void;
【讨论】:
编译现在运行良好,但单击任意位置后出现 JS 错误:Uncaught TypeError: vnode.context[binding.expression] is not a function at HTMLBodyElement.el.clickOutsideEvent 哦,这是因为我没有将函数定义为 v-click-outside 自定义指令的属性。谢谢!【参考方案2】:这是我目前使用的一个实现,希望对您有所帮助:
export default
bind: function(el, binding, vNode)
// Provided expression must evaluate to a function.
if (typeof binding.value !== "function")
const compName = vNode.context.name;
let warn = `[Vue-click-outside:] provided expression '$binding.expression' is not a function, but has to be`;
if (compName)
warn += `Found in component '$compName'`;
console.warn(warn);
// Define Handler and cache it on the element
const bubble = binding.modifiers.bubble;
const handler = e =>
if (bubble || (!el.contains(e.target) && el !== e.target))
binding.value(e);
;
el.__vueClickOutside__ = handler;
// add Event Listeners
document.addEventListener("mousedown", handler);
,
unbind: function(el, binding)
// Remove Event Listeners
document.removeEventListener("mousedown", el.__vueClickOutside__);
el.__vueClickOutside__ = null;
;
然后在你的主文件中注册指令
// Directives
Vue.directive("click-outside", ClickOutside);
【讨论】:
OP 有打字稿错误,他的 javascript 代码看起来不错。 只是建议我以前使用的解决方案,以防万一这个解决方案不起作用。以上是关于Vue.js 自定义指令使用 TypeScript 检测点击外部元素的主要内容,如果未能解决你的问题,请参考以下文章