在Vue 3的<script setup>
语法中,直接使用name
属性而不报错的原因是项目配置了第三方插件(如vite-plugin-vue-setup-extend
或unplugin-vue-define-options
)。这些插件允许在<script setup>
标签上直接定义name
属性,并在编译阶段将其注入为组件的选项。
详细解释:
-
传统写法:
-
单独的
<script>
块定义:vue
<script lang="ts"> export default { name: "ProgressCtrl" }; </script>
-
-
第三方插件的作用:
-
插件如
vite-plugin-vue-setup-extend
扩展了Vue SFC的编译逻辑,允许在<script setup>
标签上添加name
属性:vue
<script setup lang="ts" name="Home"> // ... </script>
-
编译时,插件会将
name
提取并自动生成defineOptions
调用,等效于显式使用defineOptions
。
-
-
为何不报错:
-
如果没有插件,Vue编译器会忽略未知属性(如
name
),但不会自动处理为组件选项,可能导致name
未生效。 -
配置插件后,插件在编译阶段识别
name
属性并注入组件选项,因此不会报错且name
生效。
-
验证与解决方案:
-
检查项目配置:查看
vite.config.ts
或类似文件是否包含类似插件:typescript
import vueSetupExtend from 'vite-plugin-vue-setup-extend'; export default { plugins: [vue(), vueSetupExtend()] };
-
替代方案:若不想用插件,改用
defineOptions
或单独<script>
块定义name
。
总结:
在<script setup>
中直接写name
属性不报错,是因为插件在编译阶段处理了这一特性,将其转换为合法的组件选项。这是对Vue SFC编译流程的扩展,并非Vue原生支持的功能。
1. <script setup>
语法
这是 Vue 3 的 Composition API 语法糖,特点:
-
更简洁的代码组织方式。
-
顶层绑定(变量、函数等)自动暴露给模板。
-
默认无法直接配置组件选项(如
name
、inheritAttrs
等),需借助工具。
2. defineOptions
函数
-
作用:在
<script setup>
中定义组件选项(如name
、inheritAttrs
等)。 -
来源:它不是 Vue 核心 API,通常由插件(如
unplugin-vue-define-options
或vite-plugin-vue-setup-extend
)提供。 -
编译时处理:构建工具会在编译阶段将选项注入组件。
3. 代码含义
javascript
复制
defineOptions({ name: 'Home' });
-
设置当前组件的
name
选项为'Home'
。 -
name
的作用:-
递归组件:组件内部调用自身时需命名。
-
开发者工具:在 Vue Devtools 中显示组件名称。
-
<keep-alive>
缓存:通过include/exclude
匹配组件名。
-
4. 对比传统写法
没有 <script setup>
时,需这样写:
vue
复制
<script> export default { name: 'Home', setup() { // 逻辑 } } </script>
而 <script setup>
+ defineOptions
更简洁,适合组合式 API。
5. 注意事项
-
插件依赖:确保项目配置了支持
defineOptions
的插件(如 Vite 项目中安装unplugin-vue-define-options
)。 -
版本兼容:Vue 3.3+ 已实验性支持
defineOptions
,未来可能成为标准。
总结
这段代码通过 defineOptions
为 Vue 组件设置了名称 'Home'
,解决了 <script setup>
无法直接配置选项的限制,依赖构建插件实现,使代码更简洁且符合组合式 API 风格。
操作示例:
需要指定组件名显示为 ProgressCtrl(目前是显示 progress-ctrl ,程序也不报错)
<script setup lang="ts" name="ProgressCtrl">
.vue文件的文件名与组件名不一样
1、按传统写法,增加一个
<script lang="ts">
export default { name: "ProgressCtrl" };
</script>
用来定义组件名称
原来的 <script setup lang="ts" name="progress-ctrl"> 去掉 name 属性
<script lang="ts">
export default { name: "ProgressCtrl" };
</script>
<script setup lang="ts">
import ProgressCtrlTree from "./progress-ctrl/comps/progress-ctrl-tree.vue";
import ProgressCtrlSearch from "./progress-ctrl/comps/progress-ctrl-search.vue";
import ProgressCtrlMain from "./progress-ctrl/comps/progress-ctrl-main.vue";
import ProgressCtrlTabs from "./progress-ctrl/comps/progress-ctrl-tabs.vue";
import ProgressCtrlPagination from "./progress-ctrl/comps/progress-ctrl-pagination.vue";
import useProgressCtrlStore from "./progress-ctrl/stores";
import { onMounted } from "vue";
const progressCtrlStore = useProgressCtrlStore();
onMounted(() => {
// 初始化Store
progressCtrlStore.$reset();
});
</script>
运行效果:
2、安装插件
2.1、安装
npm i vite-plugin-vue-setup-extend -D
2.2、设置,打开vite.config.ts
import VueSetupExtend from "vite-plugin-vue-setup-extend";
plugins: [vue(), VueSetupExtend()],
vite.config.ts 完整代码
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import VueSetupExtend from "vite-plugin-vue-setup-extend";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), VueSetupExtend()],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url))
}
},
server: {
// 指定端口,vite默认 5173
port: 5173,
// 指定服务器监听的 IP 地址,如果将此设置为 0.0.0.0 或者 true 将监听所有地址
host: "0.0.0.0",
proxy: {
// 【代理1】获取路径中包含有 /api 的请求
"/api": {
// 后台服务所在的源
target: "http://localhost:8080",
// 修改源
changeOrigin: true,
// 将 api 替换为 ''
rewrite: (path) => path.replace(/^\/api/, "")
},
// 【代理2】获取路径中包含有 /apu 的请求,【上传数据】用于前端网面对外请求发送数据
"/apu": {
// 后台服务所在的源
target: "http://localhost:8081",
// 修改源
changeOrigin: true,
// 将 apu 替换为 ''
rewrite: (path) => path.replace(/^\/apu/, "")
}
}
}
});
2.3、在<script setup>设置组件名称
<script setup lang="ts" name="ProgressCtrl">
运行效果: