手摸手带你封装Vue组件库(2)组件库项目搭建在开始之前我们先来捋一下我们需要这个项目中有哪些东西。 组件:肯定首先想到
在开始之前我们先来捋一下我们需要这个项目中有哪些东西。
组件
:肯定首先想到的是要开发的组件的代码预览
:我们开发的组件要有地方可以预览,边开发边查看效果文档
:我们需要撰写组件的属性、方法等相关示例说明以及使用说明
主要分为这三个模块,组件我们基于 Vue3
进行开发。预览的模块做成一个简单的 Vue3 项目,将我们开发的组件注册到上面去进行预览。组件的文档呢我更推荐使用 vitepress
进行搭建,能够让我们更快的搭建出组件库文档,当然你也可以自己写一个文档的项目,这个就根据个人喜好了。
废话不多说,我们开始。
创建项目以及初始化
我们创建一个文件夹为自己组件库的名称,比如 XXX-UI 之类的,然后初始化一个 package.json
文件
npm init -y
创建 packages
、examples
、docs
文件夹分别作为组件模块、示例模块、文档模块,然后在packages
文件夹中分别创建components
、theme-chalk
、utils
三个文件夹划分为组件代码、组件样式、公共方法。
在这个仓库中我们有三个项目,各自之前有一些相同的依赖,比如 Vue3,还有在文档和示例中我们需要导入我们开发的 Vue 组件,所以我们需要做一下工作空间。
设置工作空间
我们在examples
、components
、theme-chalk
、utils
这几个文件夹下初始化 package.json
文件,并将其中的 name
字段分别修改为 @XXXX/examples
、@XXXX/components
、@XXXX/theme-chalk
、@XXXX/utils
,(XXX 代表你的仓库名称),然后在根目录下创建 pnpm-workspace.yaml
文件,写入以下内容
packages:
- packages/**
- examples
然后在根目录下创建 .npmrc
文件,并写入以下内容
shamefully-hoist = true
我们在示例以及文档中会使用到组件以及对应样式,以及组件开发的时候需要一些公共的方法,我们将这些公用的添加进工作空间,在根目录下打开 bash 终端,输入以下指令(@xxx/components 这些就是刚才的 package.json 中的 name):
pnpm i @xxx/examples -w
pnpm i @xxx/components -w
pnpm i @xxx/theme-chalk -w
pnpm i @xxx/utils -w
这时候你会看到根部 package.json
文件中会多下面这些东西,表示你已经添加进去了
{
"dependencies": {
"@xxx/examples": "workspace:^",
"@xxx/components": "workspace:^",
"@xxx/theme-chalk": "workspace:^",
"@xxx/utils": "workspace:^"
}
}
组件相关的代码结构
我们刚才说了,在 components
中放组件代码,theme-chalk
中放组件的样式文件,utils
中放组件的公共方法。我们来想一下安装 Element Plus
组件库在使用的时候需要干什么?
// main.ts
import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import App from "./App.vue";
const app = createApp(App);
app.use(ElementPlus);
app.mount("#app");
重点在于 app.use(ElementPlus)
这行代码,能被 Vue 实例 use
, 说明"element-plus"导出的是一个插件,并且导出的对象中包含 install
方法,请查看官方文档官方 app-use 介绍,这就代表着我们需要将我们的组件库导出的对象作为 Vue 实例的一个插件,那我们来看看 Vue 官方说插件怎么定义的呢?官方 plugins 介绍 并且我们需要通过插件将我们开发的组件注册到这个实例上去,这时候聪明的小伙伴已经大概知道怎么做了,当然我还是需要告诉你们一步步怎么实现。
先在components
文件夹中创建一个 index.js
文件,并 export 出去一个对象,包含install
的一个方法。
export default {
install(app) {},
};
再想想,我们使用Element Plus
,只要 use
就可以直接在全局调用他的所有组件,那他的组件是在什么时候注册的呢?答案就是在我们刚才创建的这个index.js
中,我们可以理解为它大概是这个样子
import ElButton from "./button";
export default {
install(app) {
app.component("el-button", ElButton);
},
};
那我们也来写一个组件试一下。我们在components
文件夹下创建一个button
文件夹用于存放这个 button 组件的相关代码,然后在他下面创建一个如下的文件结构:
其中 vue 文件和 index.js 的内容如下:
<template>
<div class="t-button">
<button>
<slot />
</button>
</div>
</template>
<script setup>
defineOptions({
name: "t-button",
});
</script>
import Button from "./src/button.vue";
Button.install = (app) => {
app.component(Button.name, Button);
};
export const TButton = Button;
export default TButton;
✨ 思考:这块为什么不直接抛出 Button 组件,而是给它上面挂了一个 install 方法再 export 呢?
然后我们创建一个在components
文件夹下创建一个components.js
收集所有的组件
export { TButton } from "./button";
我们修改一下前面的components
入口的 index.js
文件
import * as components from "./components";
export default {
install(app) {
Object.entries(components).forEach(([key, value]) => {
app.component(key, value);
});
},
};
🎉OK,到这我们算是已经简单写完了一个组件的开发以及注册的逻辑,接下来我们看一下我们写的这个 button 组件能不能在 vue 项目中使用呢?
组件预览
我们前面创建了一个examples
文件夹就是为了创建我们开发时预览和测试用的,我们先在根目录下安装一下 vue,并且我们需要使用 vite 这个构建工具来创建一个 vue 项目,那么
pnpm i @vitejs/plugin-vue vite -D -w
注意这个
-w
是添加进工作区
我们在examples
文件夹下创建以下文件
我们先配置一下 vite 让支持解析 vue
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
});
修改package.json
使其支持 es 模块
{
"name": "@test-ui/examples",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module", // 改为module
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
然后在 html 中创建一个 id 为 app
的 div 作为 vue 渲染的入口,并导入 index.js 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script type="module" src="./index.js"></script>
</html>
我们在 app.vue
文件中随便写一写东西:
<template>
<div>
<p>1111</p>
</div>
</template>
<script setup></script>
<style scoped></style>
然后在index.js
中写一下 vue 的渲染
import { createApp } from "vue";
import App from "./app.vue";
const app = createApp(App);
app.mount("#app");
这样,这个 vue 项目算是写完了,我们需要加入启动命令,我们修改一下根目录下的 package.json
文件,添加启动命令
{
"name": "test-ui",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "vite examples", // 添加启动命令
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@test-ui/components": "workspace:^",
"@test-ui/examples": "workspace:^"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
"vite": "^5.3.5"
}
}
来,npm run dev
启动一下,发现 vue 项目是成功启动的,我们现在需要将我们的组件库进行注册,看一下刚才的 button 组件能否在 vue 项目中正常使用。
import { createApp } from "vue";
import App from "./app.vue";
import TestUI from "@test-ui/components";
const app = createApp(App);
app.use(TestUI);
app.mount("#app");
我们在 app.vue 文件中使用一下注册的 button 组件
<template>
<div>
<p>1111</p>
<t-button>222222</t-button>
</div>
</template>
<script setup></script>
<style scoped></style>
出来了,太感动了。
这期先教大家怎么搭建一个简单的组件库,后续会说怎么优化逻辑,以及做一些组件的封装,下节我们带大家来做一下组件库文档的相关开发,关注我,希望与大家一起学习😁有不对的地方还请指出🤝
转载自:https://juejin.cn/post/7400242491779940386