vue 3/vue路由器 - onclick活动听众计划外射击

发布于 2025-01-23 02:24:19 字数 2945 浏览 0 评论 0 原文

使用Vue 3和Vue路由器。事件听众按计划的初始“单击”导航,从详细信息到vue页面。但是,在连续的“单击”尝试后, hidedEtails()在没有感知的“单击”事件的情况下立即调用。


home.vue

<template>
    <main class="rounded">
        <item-one />
        <item-two />
    </main>
    <aside class="details__modal">
        <router-view></router-view>
    </aside>
</template>

<template>
    <button @click="showDetails(id)">Item Name</button>
</template>

<script lang="ts">
import {showDetails} from '@/scripts/utils'
</script>

详细信息。 AddeventListener()通过全球导航护罩调用。

...
const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: 'home',
        component: Home,
        children: [
            {
                path: 'details',
                name: 'details',
                component: () =>
                    import(
                        /* webpackChunkName: "details" */ '../views/Details.vue'
                    ),
                props: route => route.params,
            },
        ],
    },
]

const router = createRouter({
    history: createWebHistory(),
    routes
})

router.afterEach(to => {
    if (to.name === 'details')
        document.addEventListener('click', handle_hideDetails)
})

lidess.vue

showdetails()上,详细信息。如果 props.id 不存在,则 HidedEtails()将重定向到home.vue。在离开页面之前, removeEventListener()是通过组件导航罩 onbeforerOuteLeave()来调用的。

<template>
    <div class="details__wrapper">...</div
</template>

<script lang="ts">
...
export default defineComponent({
    props: {
        id: {
            type: String
        }
    },
    setup(props){
        if(!props.id) hideDetails()

        onBeforeRouteLeave(_ => document.removeEventListener('click', handle_hideDetails))
    }
})
</script>

utils.ts

所有实用程序功能都在这里。

import vm from '@/main'

export const handle_hideDetails = (e: Event): void => {
    const el = <HTMLElement>document.querySelector('div.details__wrapper')

    if (!e.composedPath().includes(el)) hideDetails()
}

export const showDetails = (id: string): void => {
    document.querySelector('aside.details__modal')?.classList.add('show')

    vm.$router.push({
        name: 'details',
        params: { id },
    })
}

export const hideDetails = (): void => {
    document.querySelector('aside.details__modal')?.classList.remove('show')
    setTimeout(() => vm.$router.push({ name: 'home' }), 2000)
}

Working with Vue 3 and Vue Router. Event listeners work as planned on initial 'click' navigations, to and from Details.vue page. However, upon successive 'click' attempts, hideDetails() is immediately called without a perceived 'click' event.


Home.vue

<template>
    <main class="rounded">
        <item-one />
        <item-two />
    </main>
    <aside class="details__modal">
        <router-view></router-view>
    </aside>
</template>

ItemOne.vue, ItemTwo.vue

<template>
    <button @click="showDetails(id)">Item Name</button>
</template>

<script lang="ts">
import {showDetails} from '@/scripts/utils'
</script>

Vue Router

Details.vue is set up as a child of Home.vue. addEventListener() is called via global navigation guard.

...
const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: 'home',
        component: Home,
        children: [
            {
                path: 'details',
                name: 'details',
                component: () =>
                    import(
                        /* webpackChunkName: "details" */ '../views/Details.vue'
                    ),
                props: route => route.params,
            },
        ],
    },
]

const router = createRouter({
    history: createWebHistory(),
    routes
})

router.afterEach(to => {
    if (to.name === 'details')
        document.addEventListener('click', handle_hideDetails)
})

Details.vue

On showDetails(), Details.vue is rendered as a child of Home.vue and displayed within a modal. If props.id does not exists, hideDetails() redirects to Home.vue. Before leaving page, removeEventListener() is called via the component navigation guard onBeforeRouteLeave().

<template>
    <div class="details__wrapper">...</div
</template>

<script lang="ts">
...
export default defineComponent({
    props: {
        id: {
            type: String
        }
    },
    setup(props){
        if(!props.id) hideDetails()

        onBeforeRouteLeave(_ => document.removeEventListener('click', handle_hideDetails))
    }
})
</script>

utils.ts

All utility functions are here.

import vm from '@/main'

export const handle_hideDetails = (e: Event): void => {
    const el = <HTMLElement>document.querySelector('div.details__wrapper')

    if (!e.composedPath().includes(el)) hideDetails()
}

export const showDetails = (id: string): void => {
    document.querySelector('aside.details__modal')?.classList.add('show')

    vm.$router.push({
        name: 'details',
        params: { id },
    })
}

export const hideDetails = (): void => {
    document.querySelector('aside.details__modal')?.classList.remove('show')
    setTimeout(() => vm.$router.push({ name: 'home' }), 2000)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文