简体   繁体   English

如何设置 Vue 3 父组件向子组件发出事件

[英]How to set up Vue 3 parent component to emit event to child component

I am attempting to set up a button in a Vue 3 Tailwind parent component to trigger a HeadlessUI transition event in a child component.我试图在 Vue 3 Tailwind 父组件中设置一个按钮来触发子组件中的 HeadlessUI 转换事件。 My goal is to enable the button in the parent to emit an event, while the child component "watches" for the event before triggering the transition event as part of the callback function in the watch.我的目标是使父组件中的按钮能够发出事件,而子组件在触发转换事件之前“监视”该事件,作为手表中回调 function 的一部分。 So far, I have the parent component set up to trigger the emit, while the child component is set up to watch for the "transition" event.到目前为止,我已将父组件设置为触发发射,同时将子组件设置为监视“转换”事件。 However, the event is not being executed.但是,该事件未被执行。 I'm afraid I don't have the watch in the child component set up correctly, so as to watch for the button click in the parent component.恐怕我没有正确设置子组件中的手表,以便观察父组件中的按钮点击。 How can I go about enabling the child component to watch for the click of the button in the parent component? go 如何让子组件监听父组件中按钮的点击?

Here is my code so far:到目前为止,这是我的代码:

Parent:家长:

<!-- This example requires Tailwind CSS v2.0+ -->
<template>
  <div class="min-h-full">
    <Disclosure as="nav" class="bg-gray-800">
      <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <div class="flex items-center justify-between h-16">
          <div class="flex items-center">
            <div class="hidden md:block">
              <div class="ml-10 flex items-baseline space-x-4">
                <button type="button" @click="transition" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Click to transition</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </Disclosure>

    <main>
      <div class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
        <div class="px-4 py-6 sm:px-0">
          <HelloWorld :event="transition" />
        </div>
      </div>
    </main>
  </div>
</template>

<script setup>
import { Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
import { BellIcon, MenuIcon, XIcon } from '@heroicons/vue/outline'
import HelloWorld from './components/HelloWorld.vue'
</script>

Child:孩子:

<template>
  <div class="flex flex-col items-center py-16">
    <div class="w-96 h-96">
      <TransitionRoot
        appear
        :show="isShowing"
        as="template"
        enter="transform transition duration-[400ms]"
        enter-from="opacity-0 rotate-[-120deg] scale-50"
        enter-to="opacity-100 rotate-0 scale-100"
        leave="transform duration-200 transition ease-in-out"
        leave-from="opacity-100 rotate-0 scale-100 "
        leave-to="opacity-0 scale-95 "
      >
        <div class="w-full h-full bg-gray-400 rounded-md shadow-lg" />
      </TransitionRoot>
    </div>
  </div>
</template>

<script setup>
import { ref, toRefs, watch } from 'vue'
import { TransitionRoot } from '@headlessui/vue'

const props = defineProps({
  transition: Function
})
const { transition } = toRefs(props)
const isShowing = ref(true)

watch(transition, () => {
  isShowing.value = false

  setTimeout(() => {
    isShowing.value = true
  }, 500)
})
</script>

events should go up and state should go down.事件应该 go 向上和 state 应该 go 向下。

make your child component to watch a property and the button in parent should change the state of that property让您的子组件观看属性,父组件中的按钮应更改该属性的 state

update:更新:

const { transition } = toRefs(props)

you might be losing reactivity here.您可能会在这里失去反应性。

more info: https://stackoverflow.com/a/64926664/420096更多信息: https://stackoverflow.com/a/64926664/420096

update2:更新2:

the way you made it should work, but point directly to the prop is fine too: https://codesandbox.io/s/relaxed-sea-y95x6c?file=/src/App.vue你制作它的方式应该有效,但直接指向道具也很好: https://codesandbox.io/s/relaxed-sea-y95x6c?file=/src/App.vue

Based on Sombriks' feedback, here is the answer:根据 Sombriks 的反馈,答案如下:

Parent:家长:

<!-- This example requires Tailwind CSS v2.0+ -->
<template>
  <div class="min-h-full">
    <Disclosure as="nav" class="bg-gray-800">
      <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <div class="flex items-center justify-between h-16">
          <div class="flex items-center">
            <div class="hidden md:block">
              <div class="ml-10 flex items-baseline space-x-4">
                <button type="button" @click="transition" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Click to transition</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </Disclosure>

    <main>
      <div class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
        <div class="px-4 py-6 sm:px-0">
          <HelloWorld :show="show" />
        </div>
      </div>
    </main>
  </div>
</template>

<script setup>
import { Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
import { BellIcon, MenuIcon, XIcon } from '@heroicons/vue/outline'
import { ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'

const show = ref(true)

const transition = () => {
  show.value = !show.value
}

</script>

Child:孩子:

<template>
  <div class="flex flex-col items-center py-16">
    <div class="w-96 h-96">
      <TransitionRoot
        appear
        :show="isShowing"
        as="template"
        enter="transform transition duration-[400ms]"
        enter-from="opacity-0 rotate-[-120deg] scale-50"
        enter-to="opacity-100 rotate-0 scale-100"
        leave="transform duration-200 transition ease-in-out"
        leave-from="opacity-100 rotate-0 scale-100 "
        leave-to="opacity-0 scale-95 "
      >
        <div class="w-full h-full bg-gray-400 rounded-md shadow-lg" />
      </TransitionRoot>
    </div>
  </div>
</template>

<script setup>
import { ref, toRefs, watch } from 'vue'
import { TransitionRoot } from '@headlessui/vue'

const props = defineProps({
  show: Boolean
})
const { show } = toRefs(props)
const isShowing = ref(true)

watch(show, () => {
  isShowing.value = false

  setTimeout(() => {
    isShowing.value = true
  }, 500)
})
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Vue 3:从父组件向子组件发出事件 - Vue 3: Emit event from parent to child component $ emit从子级到父级Vue 2的事件 - $emit an event from child to parent component Vue 2 父级的Vue.js $ emit事件,并在组件(子级)上接收 - Vue.js $emit event from parent and receive it on a component (child) VueJS如何从子组件向其父组件发出事件 - VueJS How to emit an event from a child component to its parent component vue 发出事件并在父组件中接收 - vue emit event and receive in parent component 为什么不更新我在子组件中传递的父组件中的值并更新使用自定义事件 $emit Vue 3? - Why not updating value in the parent component which I passed in child component and updating use custom event $emit Vue 3? Vue中点击槽子组件时忽略父组件的发射 - Ignore the emit of a parent component when clicking on the slot child component in Vue 如何处理自定义子事件,该事件通过this。$ emit在父组件中<script> portion of the .vue file? - How can I handle a custom child event, emitted via this.$emit, in a parent component, within the <script> portion of the .vue file? 子组件发出自定义事件,但未触发父组件的侦听器 - child component emit an custom event, but parent component's listener not triggered 无法从Vue.js的子组件向父组件发出事件 - Not able to emit an event to a parent component from child component in Vuejs
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM