Vue 封装 El-dialog对话框渲染异常

Element-Puls 封装 对话框(el-dialog) 不渲染

我自己封装了一个简易的对话框,但是它并不能按照封装前的模式进行工作,我尝试使用生命周期函数,去打印它的各阶段运行时变量值,但是没有一个是可以打印的,甚至我都怀疑这玩意根本就没被加载进dom树.

以下是封装组件代码(无报错的异常代码):

<template>
    <el-col>
        <el-dialog v-model="props.visible" title="Campus tips" width="30vw" top="30vh">
            <span>{{ props.message }}</span>
            <template #footer>
                <span class="dialog-footer">
                    <el-button :type="props.status ? 'success' : 'danger'">确认</el-button>
                </span>
            </template>
        </el-dialog>
    </el-col>
</template>
<script setup lang="ts">
import { watch,defineEmits } from 'vue';
// import { Dialog } from '../assets/types';
// 在这之前我,我还尝试用使用inject/provide进行数据通信,但是无一例外,全都没有"回信"
// const props = inject<Dialog>('Dialog')

const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
  },
  status: {
    type: Boolean,
    required: true,
  },
  message: {
    type: String,
    required: true,
  }
});

const emit = defineEmits(['load'])

// watch 无响应,无输出
watch(
    () => props.visible,
    (newValue) => {
        // props!.visible = newValue;
        console.log(newValue)
        emit('load',newValue)
    }
);

watch(
    () => props?.message,
    (newValue) => {
        // props!.message = newValue;
        console.log(newValue)

    }
);

watch(
    () => props?.status,
    (newValue) => {
        // props!.status = newValue;
        console.log(newValue)
    }
);
</script>

异常DOM (图1):

img

图2:

img

原始代码(父组件):

<template>
    <el-col id="index">
        <RouterView></RouterView>

        <!-- 这里就是那个封装组件的调用,我看不出问题-->
        <dialog @load="modifyObj" :message="dialogObj.message" :status="dialogObj.status" :visible="dialogObj.visible" />
          
        <!--下面是原始组件,说是封装,其实就是移植-->
<!-- 
        <el-dialog v-model="dialogObj.visible" title="Campus tips" width="30vw" style="margin-top: 40vh;">
            <span>{{ dialogObj.message }}</span>
            <template #footer>
                <span class="dialog-footer">
                    <el-button :type="dialogObj?.status ? 'success' : 'danger'">确认</el-button>
                </span>
            </template>
        </el-dialog> -->
    </el-col>
</template>

<script lang="ts" setup >
import { provide, reactive, watch } from 'vue'
import type { Dialog } from '../../assets/types';
import dialog from '../../components/dialog.vue';

const dialogObj = reactive<Dialog>({
    message: '错误警示',
    visible: false,
    status: true
})


function modifyObj(visible:boolean) {
    dialogObj.visible = visible
}
// watch 正常
watch(()=>dialogObj.visible,
(value)=>{
    console.log(value)
})

// 这个还会被其他组件使用,工作正常
provide('Dialog', dialogObj)
</script>

以上就是所有的相关代码了,所以有人能看出什么问题不?

问题中提供的代码片段为visible=fasle时的代码,当它等于true时,也是同样的状态,Dom树没有任何变化!

在Vue.js 3中,如果你将组件名定义为全小写的方式,那么它会被解析为 HTML 标签,并按照标签处理。

这是因为在 Vue.js 3 中,有一个新的特性叫做自定义元素,它允许您将任何语法正确的 HTML 标签作为Vue.js组件使用。为了使自定义元素可以更容易地与已存在的HTML标签一起使用,Vue.js 3 在解析组件名时采用了一种“同音转换”的策略。这意味着当组件名全部为小写时,Vue.js 3会将其解析为自定义元素,而不是 Vue 组件。

举个例子,如果你有一个组件名为 "my-component",那么它会被解析为 Vue 组件。但是,如果你将组件名改为 "mycomponent"(全小写),那么它会被解析为自定义元素(类似于使用常规 HTML 标记)。

需要注意的是,如果您使用自定义元素而不是 Vue 组件,您就不能访问组件的生命周期钩子和其他高级功能。因此,在编写 Vue.js 3 应用程序时,请务必使用 PascalCase(大驼峰式命名)并将每个单词的首字母大写,以确保您的组件可以被 Vue.js 正确解析为 Vue 组件。


<template>
    <el-col id="index">
        <Dialog @load="modifyObj" :message="dialogObj.message" :status="dialogObj.status" :visible="dialogObj.visible" />
          
    </el-col>
</template>
 
<script lang="ts" setup >
import DIalog from '../../components/dialog.vue';
 
</script>