首页 > 解决方案 > 如何在单独的 vue 文件中使用模态内容在 vuejs 3 应用程序中制作模态?

问题描述

在@vue/cli 4.5.8 应用程序中,我想制作模态查看示例:https ://v3.vuejs.org/examples/modal.html

试图在单独的 vue 文件中设置模态内容并失败。我有文件 src/views/test2.vue :

<template>
    <div>
        showModal::{{ showModal }}<br>;
        <button id="show-modal" @click="showModal = true">Show Modal</button>
        <!-- use the modal component, pass in the prop -->
        <modal v-if="showModal" @close="showModal = false">
            <!--
              you can use custom content here to overwrite
              default content
            -->
            <template v-slot:header>
                <h3>custom header</h3>
            </template>
        </modal>
    </div>
</template>

<script>
    import { ref, onMounted, defineComponent /* , modal */ } from 'vue'
    import modal from '../views/Modal.vue'
    console.log('modal::')
    console.log(modal)
    
    export default defineComponent({
        name: 'test2Page',
        components: {
            modal
        },
        setup () {
            let showModal = ref(false)

            const test2OnMounted = async () => {
                console.log('test2OnMounted!!!::')
            }

            onMounted(test2OnMounted)

            return {
                showModal
            }
        } // setup() {

    })

</script>

并使用模态定义的 src/views/Modal.vue 文件:

<transition name="modal">
    <div class="modal-mask">
        <div class="modal-wrapper">
            <div class="modal-container">
                
                <div class="modal-header">
                    <slot name="header">
                        default header
                    </slot>
                </div>
                
                <div class="modal-body">
                    <slot name="body">
                        default body
                    </slot>
                </div>
                
                <div class="modal-footer">
                    <slot name="footer">
                        default footer
                        <button class="modal-default-button" @click="$emit('close')">
                            OK
                        </button>
                    </slot>
                </div>
            </div>
        </div>
    </div>
</transition>

<style scoped>
    .modal-mask {
        position: fixed;
        z-index: 9998;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        display: table;
        transition: opacity 0.3s ease;
    }

    .modal-wrapper {
        display: table-cell;
        vertical-align: middle;
    }

    .modal-container {
        width: 300px;
        margin: 0px auto;
        padding: 20px 30px;
        background-color: #fff;
        border-radius: 2px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
        transition: all 0.3s ease;
        font-family: Helvetica, Arial, sans-serif;
    }

    .modal-header h3 {
        margin-top: 0;
        color: #42b983;
    }

    .modal-body {
        margin: 20px 0;
    }

    .modal-default-button {
        display: block;
        margin-top: 1rem;
    }

    /*
     * The following styles are auto-applied to elements with
     * transition="modal" when their visibility is toggled
     * by Vue.js.
     *
     * You can easily play with the modal transition by editing
     * these styles.
     */

    .modal-enter {
        opacity: 0;
    }

    .modal-leave-active {
        opacity: 0;
    }

    .modal-enter .modal-container,
    .modal-leave-active .modal-container {
        -webkit-transform: scale(1.1);
        transform: scale(1.1);
    }

</style>

结果我的页面打开没有错误,但点击按钮我得到了错误:

runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Component is missing template or render function. 
  at <Modal key=0 onClose=fn > 
  at <Test2Page onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy {…} > > 
  at <RouterView> 
  at <App>

哪种格式有效?

"core-js": "^3.6.5",
"vue": "^3.0.0",

谢谢!

标签: vue.jsvuejs3

解决方案


您的 Modal 组件应由模板标签包装:

<template>
<transition name="modal">
    <div class="modal-mask">
        ....
    </div>
</transition>
</template>

<style scoped>
  ...
</style>

推荐阅读