在 <script>、<template>、<style> 标签外首行误输入内容 vts
vts
<script setup lang="ts" name="BaseDocxPreviewDialog">
/**
* docx文件预览模态框组件
*/
defineOptions({ name: "BaseDocxPreviewDialog" });
import { renderAsync } from "docx-preview";
import { nextTick, ref, watchEffect } from "vue";
interface Props {
/** 标题 */
title?: string;
/** 文件 */
file?: File | null;
}
const props = withDefaults(defineProps<Props>(), { title: "", file: null });
// 对话框显示标识
const dialogVisible = ref(false);
// 预览容器实例
const previewContainerRef = ref<HTMLElement | null>(null);
// 显示对话框
const showDialog = async () => {
dialogVisible.value = true;
};
// 关闭对话框
const closeDialog = () => {
dialogVisible.value = false;
};
// 自动监听数据变化,并且自动渲染文档
watchEffect(async () => {
if (previewContainerRef.value) {
try {
// 调用 renderAsync 方法渲染文档到预览容器
await renderAsync(props.file, previewContainerRef.value);
} catch (error) {
// 预览容器显示文件渲染失败的信息
previewContainerRef.value.innerHTML = "文件渲染失败,只支持docx格式文件";
// 更改预览容器样式属性内容
previewContainerRef.value.style.textAlign = "center";
previewContainerRef.value.style.color = "red";
// 这里更改预览容器的字体大小后,会影响预览文件的字体,故暂时不更改字体大小,统一采用默认的字体大小
// previewContainerRef.value.style.fontSize = "80px";
}
}
});
defineExpose({ showDialog });
</script>
<template>
<div>
<el-dialog
:title="props.title"
width="850px"
top="0vh"
style="border-radius: 10px"
center
v-model="dialogVisible"
:close-on-press-escape="true"
:close-on-click-modal="false"
:show-close="false"
draggable
@closed="closeDialog">
<template #>
<div class="preview-container" ref="previewContainerRef"></div>
</template>
<template #footer>
<div>
<el-button type="primary" @click="closeDialog">关闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<style scoped lang="scss">
.preview-container {
border: 1px solid #ccc;
min-height: 500px;
}
</style>
在 Vue 3 的单文件组件(.vue
文件)中,在 <script>
、<template>
、<style>
标签外输入内容不会导致程序报错,但这部分内容会被构建工具忽略,不会包含在最终输出的代码中。原因如下:
1. Vue SFC 规范的定义
Vue 的单文件组件(SFC)规范明确规定,
.vue
文件只能包含三种顶层标签:<template>
、<script>
和<style>
(以及它们的自定义块,如<docs>
)。标签外的内容不符合 SFC 规范,但 Vue 的编译器(如
@vue/compiler-sfc
)会直接忽略这些内容,而不是抛出错误。这是一种“宽容”的处理方式,确保构建过程不会因为无关内容而中断。
2. 构建工具的处理(如 Vite 或 Vue CLI)
构建工具(如 Vite 或 Vue CLI)使用
@vue/compiler-sfc
解析.vue
文件时,会提取并处理这三个标签内的内容,标签外的内容会被丢弃。例如,如果你在标签外写了一段文本或 HTML,它不会出现在编译后的组件中,也不会影响运行时行为。
3. 为什么设计为不报错?
兼容性和灵活性:Vue 允许在
.vue
文件中使用自定义块(如<docs>
、<unit-test>
),这些块可能被其他工具处理。标签外的内容可能是开发者无意中输入的,严格报错反而会影响开发体验。渐进式警告:某些情况下,Vue 编译器可能会在控制台输出警告(取决于工具配置),但不会直接终止构建过程。
4. 示例验证
假设有一个 .vue
文件内容如下:
vue
Some invalid text outside tags <template> <div>Hello World</div> </template> <script setup> // Script logic </script> <style> /* Styles */ </style>
编译后:
Some invalid text outside tags
会被忽略,最终组件只包含<template>
、<script>
和<style>
的内容。
5. 是否需要避免这种行为?
是的!虽然不会报错,但标签外的内容毫无意义,且可能导致代码可读性降低。建议遵循 SFC 规范,仅使用标准标签或自定义块。
总结
Vue 3 的编译器会忽略 .vue
文件中 <script>
、<template>
、<style>
标签外的内容,不会报错也不会包含这些内容到最终代码中。这是为了保持构建过程的鲁棒性,但开发者应避免这种写法以确保代码规范。