VUE3中 在复用组件中使用mitt,重复执行
childA
<script lang="ts" setup>
const handleFunc = () => {
mitter.emit('on-func')
}
</script>
childB
<script lang="ts" setup>
const count = ref<number>(0)
onMounted(() => {
mitter.on('on-func')
count.value++
console.log('count', count.value)
})
</script>
父组件--parent
<template>
<childA />
<childB />
</template>
在页面中复用父组件
<template>
<parent />
<parent />
<parent />
</template>
上述代码中,当触发三个<parent />组件其中之一的时候,<childB />中的 mitter.on('on-func')会被触发三次。
复用组件的时候,mitt会存在组件隔离吗,如果mitter.on只想被当前组件的mitter.emit所触发,要怎么写。
在 utils
文件夹中创建一个 mittFactory.ts
文件,用于生成 mitt
实例:
// utils/mittFactory.ts
import mitt from 'mitt';
export const createMitt = () => {
return mitt();
};
在每个组件中引入并使用这个工厂函数来创建 mitt
实例。
<script lang="ts" setup>
import { createMitt } from '../utils/mittFactory';
const mitter = createMitt();
const handleFunc = () => {
mitter.emit('on-func');
};
</script>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { createMitt } from '../utils/mittFactory';
const mitter = createMitt();
const count = ref<number>(0);
onMounted(() => {
mitter.on('on-func', () => {
count.value++;
console.log('count', count.value);
});
});
</script>
在父组件中创建 mitt
实例并通过 props
传递给子组件。
<template>
<childA :mitter="mitter" />
<childB :mitter="mitter" />
</template>
<script lang="ts" setup>
import { createMitt } from '../utils/mittFactory';
import ChildA from './ChildA.vue';
import ChildB from './ChildB.vue';
const mitter = createMitt();
</script>
修改子组件以接收并使用传递的 mitt
实例。
<script lang="ts" setup>
import { defineProps } from 'vue';
const props = defineProps<{ mitter: any }>();
const handleFunc = () => {
props.mitter.emit('on-func');
};
</script>
<script lang="ts" setup>
import { ref, onMounted, defineProps } from 'vue';
const props = defineProps<{ mitter: any }>();
const count = ref<number>(0);
onMounted(() => {
props.mitter.on('on-func', () => {
count.value++;
console.log('count', count.value);
});
});
</script>
通样每个父组件实例都会有自己的 mitt
实例,从而避免了事件监听器在全局范围内触发的问题。
在 Vue 3 中使用 mitt 进行事件管理时,如果在复用组件中遇到事件重复执行的问题,通常是因为事件监听器 (mitter.on
) 没有在组件卸载时正确移除。这会导致每当组件重新挂载时,都会添加一个新的监听器,而旧的监听器依然存在,从而引发重复执行的问题。
为了解决这个问题,你应该在 onUnmounted
钩子中移除之前添加的监听器。这样可以确保每个组件实例只会有一个监听器,并且在组件销毁时清理掉。
以下是修改后的 childB
组件代码:
<script lang="ts" setup>
import { ref, onMounted, onUnmounted } from 'vue';
import mitter from 'mitt'; // 确保你已经正确导入了 mitt 实例
const count = ref<number>(0);
const handleFunc = () => {
count.value++;
console.log('count', count.value);
};
onMounted(() => {
mitter.on('on-func', handleFunc);
});
onUnmounted(() => {
mitter.off('on-func', handleFunc);
});
</script>
在这个修改中,我们定义了一个 `handleFunc` 函数来处理事件,并在 `onMounted` 钩子中将其添加到 mitt 的事件监听器中。同时,在 `onUnmounted` 钩子中,我们使用 `mitter.off` 来移除这个监听器。
这样,每个 `childB` 组件实例都会独立管理自己的事件监听器,不会受到其他组件实例的影响,从而解决了重复执行的问题。
下面的代码直接打开这个页面执行没有问题,但是做为组件放到Dialog里被另一个页面执行,打开是图片就无放显示,有大神能看出是哪里问题吗?
vue3.0+tsx中子组件注册的两个emit方法,点击事件btnclick在父组件中正常,然后一个接收消息的事件rollback,没触发。 子组件: 接收socket消息是正常的,msg也能正常打印,就是父组件无法接收事件 父组件: 父组件没触发rollback方法,有没有大神帮忙看下怎么回事
问题内容: 我在一个商业android应用程序上工作。我还使用了一些使用不同许可类型许可的库,其中一些声明如下: 如果库中有带有归因说明的“ NOTICE”文件,则在分发时必须包括该NOTICE (例如,其中之一已获得 Apache License 2.0 的 许可 )。 有多个库。使用 gradle 或 Android Studio 进行构建时,出现以下构建错误: 到目前为止,我在Interne
我在一个商业android应用程序工作。我还使用了一些在不同许可类型下许可的库,其中一些声明如下: (例如,其中一个是在Apache License2.0下获得许可的)。 不止一个图书馆。当我使用gradle或Android Studio进行构建时,我会得到以下构建错误: 到目前为止,我在internet和stackoverflow上找到的答案建议,通过在文件中添加以下内容,从打包中删除licen
我在一个商业android应用程序上工作。我还在使用一些根据不同许可证类型授权的库,其中一些声明如下: 如果库中有一个带有属性注释的“通知”文件,则在分发时必须包含该通知 (例如,其中一个是Apache License 2.0许可的)。 图书馆不止一个。当我使用gradle或Android Studio进行构建时,我得到以下构建错误: 根据这些库的许可证(例如Apache许可证2.0),应该包括许
我正在中绑定组件 当我试图从访问时 最后是 错误[org.apache.catalina.core.containerbase.[jboss.web].[default-host].[/mdf-portal-web].[Faces Servlet]](http-localhost-127.0.0.1-8080-10)Servlet Faces Servlet的Servlet.service()引发
主要内容:全局组件实例,实例,实例,全局组件实例,局部组件实例,Prop,Prop 实例,Prop 实例组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树: 每个 Vue 应用都是通过用 createApp 函数创建的,传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。 一个应用需要被挂载到一
使用vue3开发项目,其中有使用iframe内嵌外部链接页面(外部链接不是自己的项目),打包成静态页面。 先在项目外打开并登录该内嵌页面 再从项目中打开该内嵌页面会发现该内嵌页面的登录状态失效了 且只有IOS会这样,Android不会 我是直接通过js操作Iframe替换的src的链接 根据搜索来的方法尝试过 但仍然没有效果,最后只好把IOS先禁用掉