vue 3 指令监听 vue 发射
Posted
技术标签:
【中文标题】vue 3 指令监听 vue 发射【英文标题】:vue 3 directives listen vue emit 【发布时间】:2021-02-03 01:52:45 【问题描述】:我想要实现的是构建一个加载 vue 指令, 带有 v-loading 指令的函数将渲染微调器和阻塞事件,直到函数 promise 解决或拒绝。
到目前为止我所尝试的:
-
使用addEventListener,但是只能监听dom的native事件,不能监听vue事件
劫持 vue $emit 函数,但收到警告说不要覆盖名为 $ 的 vue 本机函数,即使此解决方案有效,我认为这是一个糟糕的解决方案。
在指令参数中,binding.instance[binding.value.name] 引用组件中的 onEvent 函数,我尝试覆盖它但它不起作用。当 onEvent 再次触发时,它会在覆盖之前运行旧的 onEvent。
第三方事件发射器(例如,手套)。这种方法效果很好,但是自定义组件必须编写额外的代码来发出事件。
作为下面的示例代码,
v-loading 的用户必须记住写 2 个发射(mitt 和 vue 的发射)。
这不是那么直接,而且它有额外的依赖性。
// mitt solution
// custom-component template
<custom-component v-loading:event="onEvent">
// custom-component script
setup(props, emit)
function emitEvent()
emit("event");
// bad: have to remember to write this extra line, and it is third party dependency
mittEmitter.emit("event");
那么,还有其他解决方案可以从 vue 的 $emit 中监听 vue 的事件(不是 dom 的原生事件)吗?
LoadingDirective.ts
import Directive from "vue";
const Loading: Directive =
mounted(el, binding)
const eventName = binding.arg;
const onEvent = binding.value;
// I want to listen vue's event(eventName) here
// do something extra
onEvent(); // original onEvent() function to run in App.vue
// do something extra
;
export default Loading;
App.vue
<template>
<!-- when onEvent triggered, a spinner will be render in custom-component -->
<custom-component v-loading:event="onEvent" />
</template>
CustomComponent.vue
<script lang="ts">
import defineComponent from "vue";
export default defineComponent(
setup(props, emit)
function emitEvent()
// use only vue's emit
emit("event")
return
onEvent
;
);
</script>
【问题讨论】:
【参考方案1】:Vue 3 文档 recommends 使用外部库,例如 mitt
或 tiny-emitter
。
JSFiddle Example
<template>
<div id="app">
<custom-component v-loading="eventHandler" />
</div>
</template>
const emitter = mitt();
const customComponent = template: '<h1>Example</h1>' ;
const app = Vue.createApp(
components: customComponent ,
setup()
setTimeout(() =>
emitter.emit('loadingEvent', colour: 'Green' );
, 1000);
const eventHandler = e => console.log('Handled!', e);
return eventHandler ;
,
);
app.directive('loading',
mounted(el, binding)
const func = binding.value;
emitter.on('loadingEvent', data =>
// your logic here...
func(data);
);
,
);
app.mount('#app');
【讨论】:
感谢您的回答。我忘了提,我确实找到了第三方手套解决方案。但这不是我想做的完美解决方案,因为它具有第三方依赖性,而且使用起来也不是那么直接,用户必须记住编写 mitt.emit() 以使 v-loading 工作。我已经更新了我的问题。但是,我没有找到任何其他解决方案来收听 vue 的发射。所以,我会先将你的答案标记为正确。 @LHJ 是的,我不确定这是否是 Vue 3 中的回归。我尝试使用onMounted
和 nextTick
在没有 mitt
的情况下实现您想要的结果,但没有成功。
很好的答案,但不幸的是,我们不得不依赖第三方库来完成以前版本中开箱即用的事情。以上是关于vue 3 指令监听 vue 发射的主要内容,如果未能解决你的问题,请参考以下文章