You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Vue3组件库构建为独立可用的原生Web Components?

问题核心原因

你当前配置构建出的产物依赖Vue,核心是两个配置错误:

  • 你在rollupOptions.external中将vue标记为外部依赖,构建时不会把Vue运行时打包进产物
  • 没有使用Vue3官方提供的defineCustomElement能力将Vue组件转换为原生Web Components标准的自定义元素,导出的仍然是Vue框架专属的组件格式,只能在Vue项目中使用。
具体实现方案

1. 修改vite.config.js构建配置

核心调整点:

  • 移除vue的外部依赖标记,将Vue运行时打包进最终产物,保证用户不需要额外引入Vue
  • 配置Vue插件的编译选项,将你自定义前缀的组件标签标记为原生自定义元素,避免Vue编译时解析报错
    完整配置参考:
const path = require('path');
const {defineConfig} = require('vite');
const vue = require('@vitejs/plugin-vue');

export default defineConfig({
    build: {
        lib: {
            entry: path.resolve(__dirname, 'src/components/index.js'),
            name: 'TykaynLib',
            fileName: (format) => `tykayn-lib.${format}.js`,
            formats: ['es', 'umd']
        },
        rollupOptions: {
            // 不要把vue加入external列表,打包进产物实现独立运行
            external: [],
            output: {
                globals: {}
            }
        }
    },
    plugins: [
        vue({
            template: {
                compilerOptions: {
                    // 替换成你自己的组件标签前缀,避免Vue编译冲突
                    isCustomElement: (tag) => tag.startsWith('tykayn-')
                }
            }
        })
    ]
});

2. 改造组件库入口文件

不要导出Vue插件格式,改用Vue3内置的defineCustomElement方法把所有Vue组件包装为原生自定义元素类,直接注册到浏览器的CustomElementRegistry,用户加载脚本后即可直接使用标签。
src/components/index.js参考代码:

import { defineCustomElement } from 'vue'
// 导入你开发的所有Vue单文件组件
import Button from './Button.vue'
import Card from './Card.vue'

// 转换为原生Web Components类
const TykaynButton = defineCustomElement(Button)
const TykaynCard = defineCustomElement(Card)

// 自动注册自定义标签,判断避免重复注册报错
if (!customElements.get('tykayn-button')) {
    customElements.define('tykayn-button', TykaynButton)
}
if (!customElements.get('tykayn-card')) {
    customElements.define('tykayn-card', TykaynCard)
}

// 同时导出类,支持用户按需手动注册场景
export {
    TykaynButton,
    TykaynCard
}
使用验证

构建完成后,在任意纯HTML页面中不需要引入Vue,直接加载构建出的UMD产物即可直接使用自定义标签:

<!DOCTYPE html>
<html>
<head>
    <script src="./dist/tykayn-lib.umd.js"></script>
</head>
<body>
    <tykayn-button type="primary">测试按钮</tykayn-button>
    <tykayn-card title="测试卡片">这是卡片内容</tykayn-card>
    <script>
        // 原生方式绑定事件和普通HTML元素完全一致
        document.querySelector('tykayn-button').addEventListener('click', () => {
            alert('按钮被点击')
        })
    </script>
</body>
</html>
注意事项
  • 最终产物会包含Vue运行时代码,gzip后体积会增加10-16KB左右,这是组件独立运行无依赖的必要成本
  • 转换后的Web Components默认使用Shadow DOM实现样式隔离,不会和页面原有样式互相干扰
  • 组件的props、自定义事件、插槽都会自动适配原生Web Components规范,用原生DOM API即可正常交互,不需要任何框架支持

内容的提问来源于stack exchange,提问作者Ty Kayn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:48:20