Открытие / закрытие модального с помощью Vue3 composition API работает не так, как ожидалось

#vue.js #vue-component

#vue.js #vue-компонент

Вопрос:

Я хочу создать простой модальный режим открытия / закрытия, используя Vue3 composition API, но он не работает.

Если я использую v-if (как в приведенном ниже коде), модал не открывается, если я использую v-show модал, открывается, но кнопка закрытия не работает.

В качестве дополнения добавьте eventListener клавишу for ESC, а затем удалите ее unMounted .

App.vue

     <div class="min-h-screen flex items-center justify-center">
          <button @click="isModalOpen = true" type="button" class="btn btn-blue">Open Modal</button>
        </div>
    
        <announcement-modal
            v-if="isModalOpen"
            @click="isModalOpen = true"
            v-model:isOpen="isModalOpen">
    
        </announcement-modal>
      </div>
    </template>
    
    <script>
    
    import { ref } from "vue";
    import AnnouncementModal from "./components/AnnouncementModal";
    
    export default {
      components: {
        AnnouncementModal,
      },
      setup() {
        const isModalOpen = ref(false);
    
        return {
          isModalOpen,
        }
      },
    
    }
    </script>
 

Объявление.vue

         <div class="text-center">
            <button @click="closeModal" type="button" class="btn btn-blue">
              Dismiss
            </button>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    
    import { onUnmounted } from "vue"
    export default {
      props: ["isOpen"],
      setup(props, context) {
    
        onUnmounted(function () {
          console.log("after unmounted")
        });
    
        function closeModal() {
          context.emit("update:is-open", false);
        }
    
        return {
          closeModal
        }
      }
    }
 

Ответ №1:

Он @click="isModalOpen = true" немедленно открывает его каждый раз, когда вы нажимаете, чтобы закрыть модальный.

Удалите этот обработчик событий, и он должен работать:

 const app = Vue.createApp({
  setup() {
    const isModalOpen = Vue.ref(false);

    return {
      isModalOpen
    }
  },
});

app.component('announcement-modal', {
  template: `<div class="text-center">
            <button @click="closeModal" type="button" class="btn btn-blue">
              Dismiss
            </button>
      </div>`,
  setup(props, context) {
    Vue.onUnmounted(function() {
      console.log("after unmounted")
    });

    function closeModal() {
      context.emit("update:is-open", false);
    }

    return {
      closeModal
    }
  }
})

app.mount('#app') 
 <script src="https://unpkg.com/vue@next"></script>

<div id="app">
  <div class="min-h-screen flex items-center justify-center">
    <button @click="isModalOpen = true" type="button" class="btn btn-blue">Open Modal</button>
  </div>

  <announcement-modal v-if="isModalOpen" v-model:is-open="isModalOpen"></announcement-modal>
</div> 

Кроме того, как сказал @Dan, v-model:isOpen="isModalOpen" не должно быть camelCase.