typescript Nuxt 3应用程序中的父母与孩子通信

xpcnnkqh  于 2023-08-08  发布在  TypeScript
关注(0)|答案(3)|浏览(243)

我目前有一个网络应用程序设置与Nuxt3,Typescript和使用合成API
Nuxt有这些布局文件,我认为是我的父母。所以我的layouts/default.vue文件包含一个名为Qdrawer的Quasar侧菜单。在父布局文件中,我也有一个<NuxtPage />,用于加载页面。
其中一个页面包含一个我想从父Qdrawer与之交谈的传单Map。例如,当我单击Qdrawer菜单中的某个项目时,我希望Map跳转到特定位置。
Qdrawer具有内置事件,这些事件会在您能想到的所有操作上发出。但据我所知,事件是用于孩子与父母的沟通,你做父母与孩子的 prop 。
我想使用prop绑定,但我必须将prop绑定到<NuxtPage \>标记,如<NuxtPage :mydrawer="qdrawer-state" \>。我面临的问题是,在/map以外的路由上,我得到了控制台日志错误。这是因为prop绑定是在所有页面上完成的,而不仅仅是在MapPage上。
当我在MapPage.vue中的div上进行属性绑定时,我会收到关于呈现顺序的控制台警告。
因此,在某种程度上,我认为使用内置的Qdrawer事件比使用prop绑定更有意义。但是如果prop绑定是正确的方法,我需要在一个Map only组件的parent内部绑定它。
<NuxtPage />似乎对此太通用了。也许我可以在路由器级别进行属性绑定?

q3qa4bjr

q3qa4bjr1#

正如你所说的,事件发送给父级,而prop用于向子级发送数据。但是在这种情况下,它并不是你从例如一个API,并希望在子组件中显示或操作。
我将简单地添加一个类似Mitt(https://github.com/developit/mitt)的事件总线,然后在Map组件中注册一个侦听器,并从菜单中触发它们。但是,如果你的菜单已经发出了你可以在Map中使用的事件,我会简单地使用它。
对于简单地传递数据,你不应该养成习惯,但在这种情况下,这似乎是合理的。
你说的也对。我会避免的,印象深刻的是,它甚至工作:D
希望有帮助

von4xj4u

von4xj4u2#

听起来你有两个不相关的组件,有时其中一个需要对另一个被点击做出React。
可能性包括:
1.一个更高级别的组件监听事件,provide是map组件可以inject或绑定并做出React的东西。这是不优雅的,因为高级组件被深度嵌套的专业化知识污染了
1.一些带外全局单例可以被发布和子发布到。@ChristofferOne建议使用消息总线来实现此目的。
1.状态修改也可以通过一个表示Map位置状态的Pinia存储(另一个单例)和一个Map组件监视或绑定的getter来实现。Map组件可能已经在使用菜单可以直接寻址的某种存储。即使Map组件不活动,存储也会是活动的,所以总是有地方可以写入新的位置,菜单组件上面的事件侦听器可以做到这一点。
1.正如您所提到的,菜单事件可以触发导航,包括调出Map组件并将位置绑定到它。你的描述表明你不希望这种情况一直发生,狡猾。
哪个选项最适合您,这在一定程度上取决于您的依赖项中已经存在的内容。出于这个原因,我对用于单个组件的事件总线(或Pinia)持谨慎态度。正确的选择还取决于你可能计划的其他互动。
如果没有人需要知道Map的焦点是什么,那么事件总线方法可能是正确的,如果你想询问Map的位置,或者让Map“神奇地”聚焦在最后选择的位置,即使它是不可见的,那么商店可能会更好。

lf3rwulv

lf3rwulv3#

要实现父布局(layouts/default.vue)和MapPage.vue组件之间的通信,可以组合使用props和自定义事件。Prop绑定是一种将数据从父组件传递到子组件的好方法,而自定义事件适合于子组件到父组件的通信。
下面是一个建议的方法:
使用Props:在MapPage.vue组件中,定义props以从父布局接收必要的数据。这些 prop 将用于更新Map的状态。
MapPage.vue:

<template>
  <div>
    <!-- Your Leaflet map code goes here, using the "myDrawer" prop -->
  </div>
</template>

<script setup>
import { ref, defineProps } from 'vue';

const { myDrawer } = defineProps(['myDrawer']);
</script>

字符串
发出自定义事件:在父布局(layouts/default.vue)中,监听Qdrawer事件,并在单击某个项目时发出一个自定义事件。定制事件将携带必要的数据(例如,特定位置)。
layouts/default.vue:

<template>
  <div>
    <Qdrawer @itemClicked="handleItemClicked" />
    <NuxtPage />
  </div>
</template>

<script setup>
import { ref } from 'vue';

const qdrawerState = ref({});

function handleItemClicked(location) {
  // Emit custom event with the location data
  emit('mapLocationChanged', location);
}
</script>


收听自定义事件:回到MapPage.vue组件,监听父布局发出的自定义事件。当接收到事件时,相应地更新Map的位置。
MapPage.vue:

<template>
  <div>
    <!-- Your Leaflet map code goes here, using the "myDrawer" prop -->
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, onUpdated, defineProps } from 'vue';

const { myDrawer } = defineProps(['myDrawer']);

onMounted(() => {
  // Listen to the custom event from the parent layout
  const handleMapLocationChanged = (location) => {
    // Update the map's location using the received data (location)
  };

  // Register the event listener
  window.addEventListener('mapLocationChanged', handleMapLocationChanged);

  // Clean up the event listener when the component is unmounted
  onUnmounted(() => {
    window.removeEventListener('mapLocationChanged', handleMapLocationChanged);
  });
});
</script>


这样,通信就可以使用自定义事件来完成,并且在不需要属性的页面上不会遇到属性绑定的问题。自定义事件只有在Qdrawer项目被点击时才会被触发,MapPage组件会相应地响应该事件。

相关问题