# 🧩 csit-vue3 组件库

> **一个基于 Vue 3 + Element Plus 封装的业务组件库，提供统一的 UI 规范和业务逻辑组件，提升团队开发效率。**

## 1. 安装方式

```bash
# 使用 npm
npm install csit-vue3

# 或 yarn
yarn add csit-vue3

# 或 pnpm
pnpm add csit-vue3

```

⚠️ 注意：该组件库依赖以下环境，请确保你的项目已安装(如果你使用Vue 3项目脚手架，请忽略)

> 版本可自行升级，无影响

- "vue": "^3.5.12"
- "echarts": "^5.5.1"
- "echarts-map": "^3.0.1"
- "element-plus": "^2.9.7"
- "@element-plus/icons-vue": "^2.3.1"
- "axios": "^1.7.7"
- "nanoid": "^5.0.8"
- "pinia": "^2.2.6"
- "vue-router": "^4.4.5"
- "moment": "^2.30.1"
- "lodash": "^4.17.21"

## 2. 快速开始

> **本节将介绍如何在项目中使用 cist-vue3。**

### 2.1. 完整引入

如果你对打包后的文件大小不是很在乎，那么使用完整导入会更方便。

在 main.ts 中写入以下内容：

```ts
import { createApp } from "vue";
import App from "./App.vue";

// 引入组件库
import CsitVue3 from "csit-vue3";
// 引入 csit-vue3 样式
import "csit-vue3/dist/index.css";

const app = createApp(App);

app.use(CsitVue3);

app.mount("#app");
```

以上代码便完成了 cist-vue3 的引入。需要注意的是，样式文件需要单独引入。

### 2.2. 按需导入

> **组件库默认支持按需引入，你可以只引入你所需要的组件，而无需引入整个组件库。**

#### 2.2.1. 示例: `main.ts`按需导入

接下来，如果你只希望引入部分组件，比如 CiUpload  和 CiCommonListLayout 和 CiPageHeader，那么需要在 main.ts 中写入以下内容：

```ts
// main.ts
import CiUpload from 'csit-vue3/ci-upload';
// 单一组件样式支持按需导入
import "csit-vue3/ci-upload/style/index.css;

import CiCommonListLayout from 'csit-vue3/ci-common-list-layout';
// 单一组件样式支持按需导入
import "csit-vue3/ci-common-list-layout/style/index.css;

import CiPageHeader from 'csit-vue3/ci-page-header';
// 单一组件样式支持按需导入
import "csit-vue3/ci-page-header/style/index.css;

app.component(CiUpload.name, CiUpload);
app.component(CiCommonListLayout.name, CiCommonListLayout);
app.component(CiPageHeader.name, CiPageHeader);
// ...

/* 或写为
 * app.use(CiUpload)
 * app.use(CiCommonListLayout)
 * app.use(CiPageHeader)
 * ...
 */

// 单个组件中使用某个组件 - 直接引入 无需注册
import CiUpload from 'csit-vue3/ci-upload'

// 单个组件中使用某个组件 - 直接引入 无需注册
import CiPageHeader from 'csit-vue3/ci-page-header'
```

#### 2.2.2. 示例: `.vue`单组件中使用某个组件

```html
<template>
  <CiBlueLineTitle title="自定义标题"></CiBlueLineTitle>
</template>

<script lang="ts" setup>
// 直接引入 无需注册
import  CiBlueLineTitle  from 'csit-vue3/ci-blue-line-title'
</script>

<style lang="less" scoped>
</style>
```

#### 2.2.3. 按需导入规则和建议

相信细心的小伙伴们会有疑问了❓ 按需导入时 import xxx from 'csit-vue3/yyy'; 后面的yyy是什么值呢❓

##### 2.2.3.1. 规则解释如下

```ts
// 组件导入模版
import xxx from 'csit-vue3/yyy';
// 示例
import CiCommonListLayout from 'csit-vue3/ci-common-list-layout';

// xxx: xxx值建议为大驼峰命名法;且值为 Vue3组件库文档 站点中你看到的示例名字; 比如: CiUpload、CiPageHeader 做到大家行业约定俗成的见名知意;

// yyy: 值为 Vue3组件库文档 站点中你看到的示例名字的 “kebab-case”（短横线连接命名）又称:（烤肉串命名法）比如你使用: CiPageHeader, 则 from 'csit-vue3/ci-page-header'; 使用: CiCommonListLayout, 则: from 'csit-vue3/ci-common-list-layout';

// 样式导入模版
import "csit-vue3/zzz/style/index.css;
//示例
import "csit-vue3/ci-common-list-layout/style/index.css;

// zzz: zzz值同理yyy值解释
```

##### 2.2.3.2. 建议📢

```ts
// 样式不建议按需导入, 建议 main.ts 中直接全量导入, 清晰且不易出现问题

// main.ts
import "csit-vue3/dist/index.css";
```

##### `番外：`  **常见命名风格比较**

| **风格**   | **示例**           | **常见场景**                             |
| ---------- | ------------------ | ---------------------------------------- |
| camelCase  | ciBlueLineTitle    | JS 变量、函数名                          |
| PascalCase | CiBlueLineTitle    | Vue/React 组件名                         |
| snake_case | ci_blue_line_title | Python变量、文件名、数据库字段           |
| kebab-case | ci-blue-line-title | 文件/文件夹、HTML/CSS 类名、自定义组件名 |

### 2.3. "优雅的"按需导入(自动导入)【！！！推荐】

> 为你使用的 csit-vue3 组件库提供一个 unplugin-vue-components 的 Resolver，就像 ElementPlusResolver 一样，支持按名称自动引入组件。

#### 2.3.1. 背景介绍

`Element Plus`按需导入之自动导入写法（点击查看[官方文档🔗](https://element-plus.org/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5)）

```ts
// 官网中有这么一句, 但是我们项目中不能 从 unplugin-vue-components 插件中导出 csit-vue3 的解析器
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
```

**为什么ElementPlusResolver能直接用？**

因为：

- `unplugin-vue-components` 官方内置了 **对主流 UI 框架（如 `Element Plus`、`Ant Design Vue`、`Vuetify`）的解析器**
- 这些内置的 resolver 都在 `unplugin-vue-components/resolvers` 中暴露了出来
- `Element Plus` 官方团队也专门配合封装了 ElementPlusResolver

🔗 官方文档：<https://github.com/antfu/unplugin-vue-components#resolvers>

**如何让你自己使用的 csit-vue3 组件库也能像ElementPlusResolver那样？**

- 很简单，你只需要自己手动写一个 Resolver

#### 2.3.2. 实战代码示例

##### 2.3.2.1 完成如下步骤即可

1. 你需要使用额外的插件来导入要使用的组件，你需要安装`unplugin-vue-components` 这款插件。
2. 你需要手写一个 Resolver。
3. 把`unplugin-vue-components`插件配置到 `Vite`  的配置文件中

##### 2.3.2.2. 安装插件

```bash
npm install -D unplugin-vue-components
```

##### 2.3.2.3. 在你的项目中手写 Resolver

```ts
/**
 * 自定义组件库解析器：CsitComponentResolver
 * 用于配合 unplugin-vue-components 实现按名称自动导入
 * 比如：使用 <CiUpload /> 会自动解析为 csit-vue3/ci-upload
 */
export function CsitComponentResolver() {
  return {
    type: 'component',

    /**
     * name 是你在模板中写的组件名，比如 <CiUpload />，这里接收到的是 "CiUpload"
     */
    resolve(name: string) {
      // 判断组件名是否符合 ci- 开头的组件，比如：CiUpload -> ci-upload
      if (!/^Ci[A-Z]/.test(name)) return

      // 将 PascalCase 转为 kebab-case（CiUpload → ci-upload）
      const kebabName = name
        .replace(/^Ci/, 'ci-')               // 去掉首字母 Ci
        .replace(/([a-z0-9])([A-Z])/g, '$1-$2') // 大写转短横线
        .toLowerCase()

      // 返回路径：配合 exports 字段实现自动导入
      return {
        name, // 保持原组件名
        from: `csit-vue3/${kebabName}`, // 自动解析导入路径
      }
    },
  }
}
```

##### 2.3.2.4. 把`unplugin-vue-components`插件配置到 `Vite`  的配置文件中

```ts
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
import { CsitComponentResolver } from './path/to/your-resolver' // 你定义的 Resolver 放在哪里了就从哪里导入

export default defineConfig({
  plugins: [
    Components({
      resolvers: [CsitComponentResolver()],
    }),
  ],
})
```

> [!WARNING]
>
> ⚠️ 注意：样式文件我们就不支持按需导入了，我们建议：在 main.ts 中全量引入所有组件样式

```ts
// 样式不建议按需导入, 建议 main.ts 中直接全量导入, 清晰且不易出现问题

// main.ts
import "csit-vue3/dist/index.css";
```

至此结束，你应该在某个页面写下：

运行后应该不报错且能渲染。至此 验证结束 大功告成✅。

```vue
<template>
  <CiUpload />
  <CiBlueLineTitle />
</template>
```

>
> ❗注意：
>
> 不要在当前vue页面手动 import，不要在当前vue页面手动注册。
>
> 不要在main.ts中全量注册组件，按需注册组件。
>

**当然，我们会把解析器内置到 `csit-vue3`中，开发者无需关心解析器实现，因为解析器实现要遵循一定的组件库设计规则，开发者只需从 `csit-vue3`中导出使用即可。**

如果使用`csit-vue3`内置解析器，实战第二步不需要你做，第三步参考如下。

```ts
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'

// 导出 csit-vue3 解析器
import { CsitComponentResolver } from 'csit-vue3/resolvers'

export default defineConfig({
  plugins: [
    Components({
      resolvers: [CsitComponentResolver()],
    }),
  ],
})
```

## 3. 示例组件使用

```html
<template>
  <CiUpload
    class="demo-page-ci-upload"
    v-model:file-list="fileList"
    :accept="'.jpg,.png,.jpeg,.xls,.xlsx,.doc,.docx,.pdf,.zip'"
    :limit="10"
    :max-size="10 * 1024 * 1024"
    :multiple="true"
  >
  </CiUpload>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

const fileList = ref<any[]>([
  {
    fileSize: 1024 * 1024 * 1.3,
    fileKey: 'key-0',
    fileName: 'element-plus-logo-0.svg',
  },
  {
    fileSize: 1024 * 1024 * 1.3,
    fileKey: 'key-0',
    fileName: 'element-plus-logo-0.svg',
  },
])
```
