代码之家  ›  专栏  ›  技术社区  ›  base

单击按钮时,如何从父组件打开位于子组件中的模态?

  •  1
  • base  · 技术社区  · 4 月前

    家长有一个按钮。当点击按钮时,我们如何让子组件知道打开模式?

    Parent.vue

    <script setup>
    import Child from "Child.vue";
    </script>
    
    <template>
      <button onClick=""> // open modal when button clicked
      <Child/>
    </template>    
    

    孩子.vue

    <script setup>
    import { ref } from "vue";
    
    const openModal = ref(false);
    </script>
    
    <template>
      <div>example</div>
    </template>
    
    1 回复  |  直到 4 月前
        1
  •  1
  •   rozsazoltan    4 月前

    与父级共享变量

    在“子”组件中,您可以使用 defineExpose 发送 status 父级可访问的反应变量。

    例子

    或实时CDN示例:

    const { createApp, ref, defineExpose } = Vue;
    
    // Child
    const ChildComponent = {
      template: `
        <div v-if="status">
          <div>
            <p>Modal is open!</p>
            <button @click="closeModal">Close</button>
          </div>
        </div>
      `,
      setup() {
        const status = ref(false);
    
        const closeModal = () => {
          status.value = false;
        };
    
        defineExpose({ status });
    
        return { status, closeModal };
      }
    };
    
    // Parent
    const App = {
      components: { ChildComponent },
      setup() {
        const childRef = ref(null);
    
        const openChildModal = () => {
          if (childRef.value) {
            childRef.value.status = true;
          }
        };
    
        return { childRef, openChildModal };
      }
    };
    
    createApp(App).mount("#app");
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
    
    <div id="app">
      <button @click="openChildModal">Open Modal</button>
      <child-component ref="childRef"></child-component>
    </div>

    通知家长某个事件

    然而,我认为从组件中提取函数是不好的做法,就像给定的例子一样。组件应该是自包含的,在任何时候都可以完全重用,并且受外部因素的影响最小。因此,我将把打开和关闭按钮都放在子组件内,允许通过发射通知父组件他们的点击。

    您可以从子组件调用emit,当它被触发时,父组件将收到通知,允许您构建自定义函数作为响应。

    例子

    或实时CDN示例:

    const { createApp, ref, defineEmits } = Vue;
    
    // Child
    const ChildComponent = {
      template: `
        <button v-if="! status" @click="openModal">Open Modal</button>
        <div v-if="status">
          <div>
            <p>Modal is open!</p>
            <button @click="closeModal">Close</button>
          </div>
        </div>
      `,
      setup(_, { emit }) {
        const status = ref(false);
    
        const openModal = () => {
          status.value = true;
          emit('opened');
        };
        
        const closeModal = () => {
          status.value = false;
          emit('closed');
        };
    
        return { status, openModal, closeModal };
      }
    };
    
    // Parent
    const App = {
      components: { ChildComponent },
      setup() {
        const customFnForChildOpen = () => {
          console.log('modal opened');
        };
        
        const customFnForChildClose = () => {
          console.log('modal closed');
        };
    
        return { customFnForChildOpen, customFnForChildClose };
      }
    };
    
    createApp(App).mount("#app");
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
    
    <div id="app">
      <child-component @opened="customFnForChildOpen" @closed="customFnForChildClose"></child-component>
    </div>