手把手从零搭建一个 vue3 组件库 (一)

这篇文章会带着你从零搭建一个基于 vue3 的组件库。

github 地址

gitee 地址

话不多说,开搞

项目搭建

  • 新建 vangle 项目
  • cd vangle 进入项目
  • pnpm init -y 初始化 package.json 文件,没安装 pnpm 的需要提前安装一下
npm i pnpm -g
  • 新建 packages 目录,里面存放我们要开发的项目,例如 components、cli 等
  • 创建 pnpm-workspace.yaml 文件,并指定 packages
# pnpm-workspace.yaml
packages:
  - 'packages/*'
  • 安装 typescript 并初始化 tsconfig.json 文件
# -w 表示在要把包下载到根目录
pnpm add typescript -D -w
npx tsc --init
  • 想配啥配啥
{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es2016",
    "sourceMap": false,
    "module": "esnext",
    "esModuleInterop": true,
    "strict": true,
    "jsx": "preserve",
    "types": ["node"],
    "rootDir": "."
  }
}

添加代码规范

prettier

  • 安装依赖
pnpm add prettier -D -w
  • 根目录创建 .prettierrc.js
module.exports = {
  semi: false,
  singleQuote: true,
  printWidth: 80,
  trailingComma: 'none',
  arrowParens: 'avoid'
}

eslint

  • 安装依赖
pnpm add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin -D -w
配合 prettier

当 ESLint 的规则和 Prettier 的规则相冲突时,就会发现一个尴尬的问题,用其中一种来格式化代码,另一种就会报错。prettier 官方提供了一款工具 eslint-config-prettier 来解决这个问题,本质上这个工具其实就是禁用掉了一些不必要的以及和 Prettier 相冲突的 ESLint 规则。

  • 安装依赖
pnpm add eslint-config-prettier eslint-plugin-prettier -D -w
  • 根目录创建 .eslint.js
module.exports = {
  parser: '@typescript-eslint/parser',
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'plugin:prettier/recommended'
  ],
  env: {
    browser: true,
    es2021: true
  },
  extends: ['eslint:recommended'],
  plugins: ['@typescript-eslint', 'prettier'],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  rules: {
    'prettier/prettier': 'error',
    'no-extra-semi': 'off',
    '@typescript-eslint/camelcase': 'off',
    '@typescript-eslint/ban-ts-ignore': 'off',
    '@typescript-eslint/no-var-requires': 'off',
    '@typescript-eslint/no-extra-semi': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/no-empty-function': 'off',
    '@typescript-eslint/no-non-null-assertion': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-empty-interface': 'off'
  }
}
  • package.json 中添加执行命令
"scripts": {
  "prettier": "prettier --write .",
  "lint": "eslint --ext .ts packages/*/**.ts",
  "lint:fix": "eslint --ext .ts packages/*/**.ts --fix"
},

这时我们可以在 packages 下创建 components/index.ts,写一些不符合规则的代码然后运行命令试试效果

husky + lint-staged

husky 哈士奇,代码提交前可以执行自定义 git hooks

在代码提交之前,进行代码规则检查能够确保进入 git 库的代码都是符合代码规则的。但是整个项目上运行 lint 速度会很慢,lint-staged 能够让 lint 只检测暂存区的文件,所以速度很快。

  • 安装依赖
pnpm add husky lint-staged -D -w
  • 执行 npx husky install 创建.husky 目录,该目录下有一个 pre-commit 文件在每次提交代码的时候会执行,可以修改里面的运行脚本,自定义提交需要做的工作,如果没有 pre-commit 文件可以手动创建
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
  • 在 package.json 中添加 lint-staged 配置
{
  "lint-staged": {
    "*.{js,jsx,vue,ts,tsx}": [
      "eslint --ext .ts packages/*/**.ts", // 这里也可以写我们上面定义好的命令,如:pnpm lint
      "eslint --ext .ts packages/*/**.ts --fix" // 这里也可以写我们上面定义好的命令,如:pnpm lint:dix
    ]
  }
}

现在我们可以试着提交一下代码,如果不符合 eslint 校验规则的会自动修复,修复完成后需要再次提交

commitlint

commitlint 统一提交时的 message,官方文档

  • 安装依赖
pnpm add @commitlint/config-conventional @commitlint/cli -D -w
  • 根目录新建 commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
}
  • 添加钩子 .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit $1

现在我们试着提交一下代码

git add .
git commit -m "test"

由于 “test” 不符合提交格式,所以不会通过

在这里插入图片描述

我们再试着使用正确的规则提交,不出意外能成功。。。

git commit -m "style: commitlint"

到此我们项目搭建和代码规范以完毕,目录结构如下

|-- vangle
    |-- .eslintrc.js
    |-- .gitignore
    |-- .prettierrc.js
    |-- commitlint.config.js
    |-- package.json
    |-- pnpm-lock.yaml
    |-- pnpm-workspace.yaml
    |-- README.md
    |-- tsconfig.json
    |-- .husky
    |   |-- commit-msg
    |   |-- pre-commit
    |   |-- _
    |       |-- .gitignore
    |       |-- husky.sh
    |-- packages
        |-- components
            |-- index.ts

编写一个组件

组件环境

  • 在 packages 下新建 components 并初始化 package.json
// packages/components/package.json
{
  "name": "@vangle/components",
  "version": "1.0.0",
  "description": "all components are settled here",
  "main": "index.ts",
  "module": "index.ts",
  "unpkg": "index.js",
  "jsdelivr": "index.js",
  "scripts": {},
  "keywords": [],
  "author": "",
  "license": "ISC",
  "peerDependencies": {
    "vue": "^3.2.0"
  },
  "types": "index.d.ts"
}
  • 项目根目录安装 vue 和 vite 依赖,安装 vite 依赖会有 define/* 提示。
pnpm add vue vite unplugin-vue-define-options -D -w
  • unplugin-vue-define-options 可以在编写组件的时候 通过 defineOptions 方法为组件设置 name
defineOptions({
  name: 'PlayButton'
})
  • 修改 tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es2016",
    "sourceMap": false,
    "module": "esnext",
    "esModuleInterop": true,
    "strict": true,
    "jsx": "preserve",
    "lib": ["esnext", "dom"],
    "types": ["node", "unplugin-vue-define-options"],
    "rootDir": ".",
    "moduleResolution": "node",
    "paths": {
      "@valgle/*": ["packages/*"]
    }
  }
}
  • eslint 添加支持 vue 插件 eslint-plugin-vue
pnpm add eslint-plugin-vue -D -w
  • 修改 .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:vue/recommended', // add
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'plugin:prettier/recommended'
  ],
  plugins: ['@typescript-eslint', 'prettier', 'vue'] // add
}

Button 组件

  • 在 packages/components 目录下创建 button 目录,结构如下

注意:我们这里只编写一个简单的 button 组件,主要是打通整体流程

|-- button
    |-- index.ts
    |-- src
    |   |-- button.ts
    |   |-- button.vue
    |   |-- button.less
    |-- __test__

components/button/src/button.vue

<template>
  <button><slot></slot></button>
</template>

<script lang="ts" setup>
defineOptions({
  name: 'VangleButton'
})
</script>

components/button/index.ts

export * from './src/button'
import type { App } from 'vue'
import Button from './src/button.vue'

Button.install = (app: App) => {
  app.component(Button.name, Button)
}

export { Button }
export default Button

components/index.ts 导出

export * from './button'

使用组件

  • 在根目录 package.json 中添加 组件的依赖
{
  "devDependencies": {
    "@vangle/components": "workspace:*"
  }
}

这里的包名 @vangle/components,就是我们在 pzckages/components/package.json 中设置的 name 属性

  • 执行 pnpm install

play 一下

  • 我们可以在根目录创建使用 vite 创建一个项目,请参考 vite 官网,项目名称就叫 play

  • 创建完后修改 pnpm-workspace.yaml

packages:
  - 'packages/*'
  - 'play' # add
  • 添加启动命令 package.json
{
  "scripts": {
    "play": "pnpm dev --filter ./play", // add
    "prettier": "prettier --write .",
    "lint": "eslint --ext .ts packages/*/**.ts",
    "lint:fix": "eslint --ext .ts packages/*/**.ts --fix"
  }
}
  • 最后在 play 项目中使用我们编写的组件即可

注意事项:

由于我们处于开发环境,需要给 vite.config.ts 添加 unplugin-vue-define-options/vite 插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import DefineOptions from 'unplugin-vue-define-options/vite'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), DefineOptions()]
})

================================= 分割线 =================================

到这里就是本篇文章的全部内容了,如果对大家有用,希望多多支持一下,你们的支持就是我的动力呀 (●’◡’●)

下期准备写一个完整的组件,并详细介绍如何为组件编写文档。组件文档使用 vitepress

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是从开始封装一个基于videojs和vue的视频播放器组件的步骤。 1. 安装依赖 首先需要安装video.js和vue-video-player这两个依赖: ``` npm install video.js vue-video-player --save ``` 2. 创建组件 创建一个名为VideoPlayer.vue组件文件,并在文件中引入video.js和vue-video-player: ```html <template> <div> <video ref="videoPlayer" class="video-js"></video> </div> </template> <script> import videojs from 'video.js' import 'video.js/dist/video-js.css' import VueVideoPlayer from 'vue-video-player' export default { name: 'VideoPlayer', props: { options: { type: Object, default: () => ({}) } }, data() { return { player: null } }, mounted() { this.initPlayer() }, methods: { initPlayer() { this.player = videojs(this.$refs.videoPlayer, this.options, function onPlayerReady() { console.log('player is ready') }) } }, beforeDestroy() { if (this.player) { this.player.dispose() } } } </script> <style> /* video.js样式 */ .video-js { width: 100%; height: 100%; } </style> ``` 在组件中,我们使用了video.js创建了一个video标签,并将其挂载到组件中。同时,我们通过props传递了一些配置项,如autoplay、controls等。 3. 使用组件 使用该组件时,可以通过options属性传递一些配置项,如下所示: ```html <template> <div> <VideoPlayer :options="{ autoplay: false, controls: true, sources: [{ src: 'http://example.com/path/to/video.mp4', type: 'video/mp4' }] }" /> </div> </template> <script> import VideoPlayer from './VideoPlayer.vue' export default { name: 'App', components: { VideoPlayer } } </script> <style> /* 样式 */ </style> ``` 在使用组件时,我们只需要传递一个options属性,其中包含了视频链接、视频类型、是否自动播放等配置即可。这里我们只提供了一个视频链接,实际使用时可以根据需求添加更多的源。 至此,一个基于video.js和vue的视频播放器组件就完成了。需要注意的是,该组件在使用时需要提供video.js的样式文件,并且需要在mounted生命周期函数中初始化播放器,以及在beforeDestroy生命周期函数中销毁播放器实例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值