安装与接入 ​
从同一份固定包产物选择一种组件导入方式:全量注册、手动按需、自动按需(推荐)。三种方式共享 Vue、Element Plus、样式和 provider 初始化。本页以 Vue 3 + TypeScript + Vite 的 ESM 项目为例。
| 方式 | 组件使用 | 适合场景 | 模板类型 |
|---|---|---|---|
| 全量注册 | app.use(AsamUIFull),模板直接写组件 |
快速接入、接受全量 JS | @asam-ui/ui/global |
| 手动按需 | 在 SFC 显式 import |
希望逐项控制导入 | 跟随组件 import |
| 自动按需(推荐) | resolver 按模板用量生成 import | 多页面 Vue/Vite 项目 | 插件生成 components.d.ts |
1. 安装固定产物与依赖 ​
首批三个包 @asam-ui/ui、@asam-ui/icons-vue 和 @asam-ui/ui-yudao 均已在 npmjs 发布 1.0.0。核心包已提供 ./full 与 ./global 出口。公共安装使用已发布的精确版本,保留消费锁文件;图标与芋道 adapter 按需安装。
在消费项目中运行:
pnpm add @asam-ui/ui@1.0.0 vue@3.5.34 element-plus@2.14.7
pnpm add -D vite@8.0.10 @vitejs/plugin-vue@6.0.9 typescript@6.0.3 vue-tsc@3.3.11
已有项目保留锁文件和工程配置,使用 pnpm 补齐缺项并检查兼容范围。已发布核心包的 peers 是 vue >=3.5.34 <3.6.0、element-plus 2.14.7;自动按需另需可选 peer unplugin-vue-components >=32.1.0 <33。上述精确版本是本仓验证组合,Node.js 为 22.19.0,pnpm 为 11.9.0。核心包内已声明编辑器等运行依赖,勿把它们复制成宿主必装 peers。
当前 Tiptap Vue 适配包的可选菜单依赖使用范围版本,新锁可能解析到与核心不同的补丁。pnpm 11 消费项目在自己的 pnpm-workspace.yaml 合并以下定向约束,再运行 pnpm install 和 pnpm peers check;已有同名约束先核对,不覆盖。已有固定锁已解析为 3.31.3 时不需重复调整。
overrides:
'@tiptap/vue-3@3.31.3>@tiptap/extension-bubble-menu': '3.31.3'
'@tiptap/vue-3@3.31.3>@tiptap/extension-floating-menu': '3.31.3'
这两项是已观察到的上游可选依赖补丁漂移修正,不是 ASAM 新增 peers。保留消费锁文件,后续 CI 使用 pnpm install --frozen-lockfile。
需要验证本地源码改动时,也可从固定 checkout 构建独立 tarball(仓库根目录执行):
pnpm install --frozen-lockfile
pnpm --filter @asam-ui/ui run build
pnpm --dir packages/ui pack --pack-destination ../../artifacts
本地验证包按交付清单核对来源提交与 SHA256,在 PowerShell 可用 Get-FileHash ./artifacts/asam-ui-ui-1.0.0.tgz -Algorithm SHA256。更新同版本本地包时必须核对安装内容,不能仅按版本号将它视为 registry 原发布产物;公共消费继续使用上面的精确版本和锁文件。
独立图标包(按需) ​
需要图标时,额外安装已发布的独立图标包;图标不随核心 CSS 或全量插件自动注册:
pnpm add @asam-ui/icons-vue@1.0.0
@asam-ui/icons-vue 使用相同的 Vue peer 范围,不依赖 Element Plus,也不提供 CSS。可从根入口具名导入,或从大小写精确的单图标子路径默认导入,二者选一种:
import { Search } from '@asam-ui/icons-vue';
// 或:import Search from '@asam-ui/icons-vue/Search';
将显式导入的图标传给 ASAM 控件,例如 <AsamButton :icon="Search">查询</AsamButton>。图标根入口没有默认导出;已有上游图标 import 应迁移到实际存在的 ASAM 图标名,不能只替换包名并假定全部名字一致。自动按需组件 resolver 不负责图标导入。
2. 共用 Vue/Vite 基线 ​
手动和全量模式的 vite.config.ts:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({ plugins: [vue()] });
index.html 包含 <div id="app"></div> 和 <script type="module" src="/src/main.ts"></script>。消费端 tsconfig.json 最小配置如下;在既有项目中合并到实际负责应用的 tsconfig,不覆盖现有 paths、types、include 或项目引用。
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
"noEmit": true,
"lib": ["ESNext", "DOM"],
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.vue", "components.d.ts", "vite.config.ts"]
}
3. 全量注册 ​
src/main.ts 使用独立全量入口,注册固定候选的公开组件清单,并安装主题和数据运行时:
import { createApp } from 'vue';
import AsamUIFull from '@asam-ui/ui/full';
import 'element-plus/dist/index.css';
import '@asam-ui/ui/style.css';
import App from './App.vue';
createApp(App).use(AsamUIFull).mount('#app');
在应用 tsconfig 的 compilerOptions.types 中追加 "@asam-ui/ui/global",例如 ["vite/client", "@asam-ui/ui/global"]。这是可选模板类型入口,不生成运行时注册,不要在 main.ts 中把它作为 JS import。
src/App.vue 无需逐个导入 ASAM 组件:
<template>
<AsamButton @click="count++">已点击 {{ count }} 次</AsamButton>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const count = ref(0);
</script>
AsamUIFull 也支持具名导出,接收与 AsamUIOptions 相同的 theme、target、dataProvider、dataScope。根入口 AsamUI 继续只初始化主题与运行时,不全量注册组件;现有根入口默认/具名导出保持兼容。一个 app 选择一种安装插件,在首次安装时传入选项,不重复安装两个插件来覆盖配置。全量模式会保留未使用的已注册组件 JS;若需按用量裁剪,请选择 手动 或 自动。
4. 手动按需 ​
src/main.ts 显式加载两份样式;需要运行时配置时安装根插件:
import { createApp } from 'vue';
import { AsamUI } from '@asam-ui/ui';
import 'element-plus/dist/index.css';
import '@asam-ui/ui/style.css';
import App from './App.vue';
createApp(App).use(AsamUI).mount('#app');
src/App.vue 显式导入使用的组件与类型:
<template>
<AsamButton @click="count++">已点击 {{ count }} 次</AsamButton>
<AsamInput ref="input" v-model="name" placeholder="输入名称" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { AsamButton, AsamInput } from '@asam-ui/ui';
import type { AsamInputExpose } from '@asam-ui/ui';
const count = ref(0);
const name = ref('');
const input = ref<AsamInputExpose>();
</script>
默认样式配合静态组件可以不安装 AsamUI;自定义主题、URL 请求或字典能力按 provider 初始化 配置。手动模式不需要 unplugin-vue-components 或全局组件类型声明。包是 ESM,构建器可以剔除未引用组件 JS;CSS 仍是完整样式入口。
5. 自动按需(推荐) ​
在消费项目安装模板组件插件:
pnpm add -D unplugin-vue-components@32.1.0
完整 vite.config.ts 示例;已有插件数组中合并 Components 配置,已有 resolver 保留,不重复创建同类插件:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { AsamUIResolver } from '@asam-ui/ui/resolver';
export default defineConfig({
plugins: [
vue(),
Components({
dirs: [],
resolvers: [AsamUIResolver()],
dts: 'components.d.ts'
})
]
});
dirs: [] 让这个最小示例只使用 resolver;已有本地组件扫描时保留宿主 dirs。无需扫描 ASAM 包源码。src/main.ts:
import { createApp } from 'vue';
import { AsamUI } from '@asam-ui/ui';
import App from './App.vue';
createApp(App).use(AsamUI).mount('#app');
src/App.vue:
<template>
<AsamButton @click="count++">已点击 {{ count }} 次</AsamButton>
<asam-input v-model="name" placeholder="输入名称" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const count = ref(0);
const name = ref('');
</script>
插件把 PascalCase 和 kebab-case 模板名称转换后交给 AsamUIResolver(),只匹配固定候选的公开组件清单。未知名称(例如 AsamUnknown)返回 undefined,不会生成不存在的导入。函数、类型、provider、主题 API、JS/TS 中直接使用的组件仍需显式 import;本配置不负责 Vue 函数自动导入。
先运行 pnpm exec vite build(或开发服务器编译使用组件的页面),生成 components.d.ts,再运行 pnpm exec vue-tsc --noEmit。生成文件必须包含在应用 tsconfig 中;CI 从干净 checkout 开始时也应先生成再检查。不要手改该文件,也不要通过全量 global 类型掩盖 resolver 未工作的情况。
resolver 为每个匹配返回 element-plus/dist/index.css、@asam-ui/ui/style.css 两项 sideEffects,因此这个纯模板示例无需再次手写 CSS import。只有脚本导入或没有任何匹配模板时,仍须显式加载两份 CSS。若宿主有最后加载的覆盖样式,可集中显式导入两份库 CSS 后再加载覆盖样式,并检查最终 CSS 顺序。当前没有关闭 resolver 样式注入的选项。
指令按需导入 ​
指令与组件 resolver 分开。需要模板指令自动导入时,在上述配置的 resolvers 中同时加入 AsamUIDirectiveResolver(),并启用 directives: true:
import { AsamUIResolver, AsamUIDirectiveResolver } from '@asam-ui/ui/resolver';
Components({
dirs: [],
directives: true,
resolvers: [AsamUIResolver(), AsamUIDirectiveResolver()],
dts: 'components.d.ts'
});
例如模板 v-asam-loading 匹配公开 vAsamLoading。固定候选还匹配 asam-infinite-scroll、asam-popover、asam-click-outside、asam-mousewheel、asam-trap-focus、asam-repeat-click;未知名称返回 undefined。手动导入指令时仍从根公开出口使用实际名称,并按 Vue 的本地指令命名或 app.directive 注册。组件按需导入不会自动启用指令 resolver。
6. 样式、主题与 provider ​
三种模式都必须加载 Element Plus 完整 CSS,再加载 ASAM 完整 CSS,最后加载宿主覆盖样式。@asam-ui/ui/style.css 不含 Element Plus CSS、页面 reset、字体或图标资产;目前没有逐组件 CSS 出口。包的 sideEffects: ["**/*.css"] 防止生产构建把已导入 CSS 摇掉,不表示组件 JS 全量加载。ASAM 组件内部显式导入 Element Plus 组件,无需为渲染 ASAM 再 app.use(ElementPlus);宿主自己的 El* 组件按宿主策略导入。
以下 src/provider.ts 是可运行的本地演示,不请求真实后端:
import type { AsamDataProvider } from '@asam-ui/ui';
export const dataProvider: AsamDataProvider = {
async request() {
return [{ label: '已就绪', value: 'ready' }];
},
dict: {
async get() {
return [{ label: '已就绪', value: 'ready' }];
}
}
};
在上述 main.ts 中显式导入后,将所选插件的首次安装改成:
import { dataProvider } from './provider';
// 全量使用 AsamUIFull;手动/自动使用 AsamUI。
app.use(AsamUI, {
dataProvider,
dataScope: 'demo-session',
theme: { color: { primary: '#345678' } }
});
这里的 app 是 const app = createApp(App);先 use 再 app.mount('#app')。URL 请求和字典依赖注入,静态数组与 API 函数不要求 provider。真实宿主负责 HTTP、认证、AbortSignal 传递、响应适配和错误通知。也可使用 provideAsamData(app, provider, { scope }) 单独安装;登录/租户切换通过 setAsamDataScope 更新上下文。
只有芋道宿主才需要运行 pnpm add @asam-ui/ui-yudao@1.0.0,再从 @asam-ui/ui-yudao 显式导入 createYudaoProvider,注入既有请求与字典 store。adapter 不包含 CSS,也不是运行所有组件的必需依赖。
7. 验证与迁移 ​
包版本、公开组件与指令清单、图标子路径及全量出口均以同一固定候选的实际 package.json、声明文件和交付指纹为准。旧版本示例中的固定组件数量不用于判断新候选是否完整。
三条路径都运行 pnpm exec vite build 与 pnpm exec vue-tsc --noEmit,再预览检查按钮点击、输入、样式和 provider。仓库内 tests/doc-007/verify.mjs 会将同一份真实 tarball 安装到三个独立消费目录,执行构建、类型与浏览器检查;不使用包源码 alias。完整复现命令及浏览器环境要求见该目录 README。
- 从根
AsamUI切换到全量时,只替换插件 import/use,并追加 global 类型;不要移除 provider/theme 选项。 - 从全量切换到按需时,移除全量插件与 global 类型;手动模式补全组件 import,自动模式先生成声明。两者按需保留根
AsamUI初始化。 - 既有 CL 的 Vite 配置是 CommonJS,获取 ESM resolver 使用
await import('@asam-ui/ui/resolver');不要直接粘贴这里的 ESM 配置覆盖它。保留 CL 已有函数自动导入与业务设置。 - 这里验证的是 Vue/Vite 三种路径,不扩展为 Nuxt、CDN、Webpack 或函数自动导入支持。
信息结构参考 Element Plus 官方快速开始;ASAM 的出口、初始化和整包 CSS 行为以本页及实际交付产物为准。
继续接入数据
异步选项和字典由宿主注入 provider。阅读数据 provider与数据驱动指南,再返回组件目录查看对应示例。