elementui上传组件-如何编写自己的Vue3组件库

加入我们一起学习,每天进步

环境搭建

目前流行的构建组件库的方法是使用monorepo的方法,这种方法有很多用途。 它可以在一个代码仓库中管理多个项目,并且可以实现项目之间的资源共享。 这里也使用了这些方法。

使用 pnpm 创建 monorepo

首先全局安装pnpm

npm install pnpm -g
复制代码

pnpm 初始化

pnpm init
复制代码

获取package.json的初始内容后,删除package.json中的名称并添加“private”:true属性,因为这个整体不需要发布。 组件是写在包中的。

{
  "private"true,
  "version""1.0.0",
  "description""",
  "main""index.js",
  "scripts": {
    "test""echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author""",
  "license""ISC"
}
复制代码

配置pnpm的monorepo工作区

这是我当前的结构目录。 Docs用来存放组件库文档,examples用来调试编译好的组件,packages中的组件用来存放自己的组件。

例如,我使用包和示例,因此我在 pnpm-workspace.yaml 中配置它们。

packages:
  - 'packages/**'
  - 'examples'
复制代码

每个子模块都有自己的 package.json 文件

图片.png

以组件包的package.json为例。 "@uv-ui/hooks":"workspace:^1.0.0" 和 "@uv-ui/utils":"workspace:^1.0.0" 依赖于其他目录。 包,如果组件包需要使用这两个包,需要安装在这个目录下,然后去掉工作空间:^发布npm包时elementui上传组件,这两个依赖包也需要独立发布npm包,那些是发布组件中有完整描述。

{
  "name""uv-ui",
  "private"false,
  "version""1.0.11",
  "main""dist/es/index.js",
  "module""dist/es/index.js",
  "style""dist/es/style.css",
  "description""基于vue3的移动端组件库",
  "scripts": {
    "build""vite build",
    "lint""eslint ./src/**/*.{js,jsx,vue,ts,tsx} --fix"
  },
  "repository": {
    "type""git",
    "url""https://github.com/monsterxwx/uv-ui",
    "directory""packages/uv-ui"
  },
  "keywords": [
    "uv-ui",
    "vue3组件库",
    "mobile",
    "frontend",
    "components"
  ],
  "files": [
    "dist"
  ],
  "author""coderxwx",
  "license""MIT",
  "dependencies": {
    "@uv-ui/hooks""workspace:^1.0.0",
    "@uv-ui/utils""workspace:^1.0.0"
  }
}
复制代码

另外两个的包名是:@uv-ui/hooks 和 @uv-ui/utils。 创建过程与上面相同。

仓库项目中的包互相调用

hooks、utils、components这三个包如何相互调用? 我们只需要将这三个包安装到仓库根目录下的node_modules目录中即可。 所有依赖项都安装在根目录中。 安装在根目录需要加上-w,意思是安装在public模块的packages.json中。

pnpm install uv-ui -w
pnpm install @uv-ui/hooks -w
pnpm install @uv-ui/utils -w
复制代码

根目录中的package.json将具有以下依赖项。 这三个是我们刚刚安装的包。

image.png组件编译

如果我们的组件库包需要支持按需引入,那么每个组件都需要通过vue app.component(comp.name,comp)进行注册。 每一个都写起来会比较麻烦,所以可以封装成一个函数。

上传组件上传前清空_上传组件封装_elementui上传组件

export const withInstall = (comp) => {
  comp.install = (app) => {
    // 注册组件
    app.component(comp.name, comp)
  }
  return comp
}
复制代码

以按钮组件为例。 首先,目录结构如下。 编译src目录下的各个组件,在components目录下有一个索引,用于导入所有组件

图片.png

按钮的index.js代码如下:导入编译好的按钮组件,然后导入即可实现各个组件的按需加载。

import Button from './button.vue'
import {withInstall} from '@uv-ui/utils'

const UvButton = withInstall(Button)

export default UvButton

复制代码

我们再看一下components目录下的index.js文件。 根据需要导入尽可能多的组件,然后将它们全部导入。 这样做的目的是全量导出的时候直接导入组件,然后vue.use(uv-ui)注册所有组件

import uvButton from './button'

const components = [
  uvButton
]

const install = (Vue) => {
  components.forEach(component => {
    Vue.component(component.name, component)
  })
}

export {
  uvButton
}

export default install

复制代码

我们再看一下button.vue 文件。 由于写的比较多,这里省略了部分代码,只保留关键代码。

elementui上传组件_上传组件上传前清空_上传组件封装

可见,需要给每个组件起一个名字,方便在vue中注册,exportdefault{name:'UvButton'},然后通过css变量提取样式,方便样式修改。 样式不需要添加作用域范围,只需命名一个好的样式名称就足够了。 其他组件相同。


  <div class="uv-button">
    
  




// 代码


export default {
  name: 'UvButton'
}


<style lang="scss">
:root {
  --uv-button-primary: #409eff;
  --uv-button-success: #67c23a;
  --uv-button-warning: #e6a23c;
  --uv-button-error: #f56c6c;
  --uv-button-info: #909399;
  --uv-button-text: #303133;
}

$primary: var(--uv-button-primary);
$success: var(--uv-button-success);
$warning: var(--uv-button-warning) ;
$error: var(--uv-button-error) ;
$info: var(--uv-button-info) ;
$text: var(--uv-button-text) ;
.uv-button {
  font-size: var(--uv-button-font-size);
  border: 0;
  border-radius: var(--uv-button-border-radius);
  white-space: nowrap;
  color: #ffffff;
  background: none;
  outline: none;
  cursor: pointer;
}



复制代码

元件封装

组件打包采用vite的库模式进行打包。 它没有使用gulp,这是一种相对简单的包装形式。 只需简单的配置即可实现各个组件的单独封装。 目前,打包后,所有组件样式都会合并为一种样式。 css文件,所有样式都需要导入,组件按需引入。 如果想要分离样式elementui上传组件,需要使用gulp等工具将所有样式去掉,打包成theme-chalk,然后像element-ui方式导入,比较麻烦,就不描述了详细的在这里。 您可以查找相关文章来了解更多信息。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
  build: {
    target: 'modules',
    // 压缩
    minify: true,
    rollupOptions: {
      // 忽略打包vue文件
      external: ['vue'],
      input: ['src/index.js'],
      output: [
        {
          format: 'es',
          entryFileNames: '[name].js',
          preserveModules: true,
          // 配置打包根目录
          dir: 'dist/es',
          preserveModulesRoot: 'src'
        },
        {
          format: 'cjs',
          entryFileNames: '[name].js',
          preserveModules: true,
          dir: 'dist/lib',
          preserveModulesRoot: 'src'
        }
      ]
    },
    lib: {
      entry: './index.js',
      formats: ['es''cjs']
    }
  },
  plugins: [
    vue()
  ]
})
复制代码

以下是打包后的结构,分别分为es和lib。 样式位于es目录下的style.css中。

图片.png

使用方法比较简单

第一种:在main.js中使用完整导出

import uvUI from 'uv-ui'
import 'uv-ui/dist/es/style.css'

app.use(uvUI)
复制代码

第二种:按需导出,在main.js中引入样式文件

import 'uv-ui/dist/es/style.css'
复制代码

在其他用到的地方引入相关组件


  

    <uvButton type="primary">切换
  




import { uvButton } from 'uv-ui'


复制代码

组件发布编译package.json

Package.json重要数组说明:

package.json完整代码

{
  "name""uv-ui",
  "private"false,
  "version""1.0.11",
  "main""dist/es/index.js",
  "module""dist/es/index.js",
  "style""dist/es/style.css",
  "description""基于vue3的移动端组件库",
  "scripts": {
    "build""vite build",
    "lint""eslint ./src/**/*.{js,jsx,vue,ts,tsx} --fix"
  },
  "repository": {
    "type""git",
    "url""https://github.com/monsterxwx/uv-ui",
    "directory""packages/uv-ui"
  },
  "keywords": [
    "uv-ui",
    "vue3组件库",
    "mobile",
    "frontend",
    "components"
  ],
  "files": [
    "dist"
  ],
  "author""coderxwx",
  "license""MIT",
  "dependencies": {
    "@coderxwx/uv-ui-hooks""1.0.0",
    "@coderxwx/uv-ui-utils""1.0.0"
  }
}
复制代码

添加许可证