Skip to content
快速预览

项目中组件库引入

✍️ w 🕒 2023-09-28 06:18:45(8 months ago) 🔗 H.各种练习项目

在项目开发使用组件时候,分全量安装 和 按需引入 自动导入三种方式

全局引入

全局引入(Global Import) 全局引入意味着一旦组件被引入,它就可以在整个 Vue 应用中使用,无需在每个单文件组件(SFC)中单独引入。这种使用方式 一般在在你的主入口文件(通常是 main.jsmain.ts)中,以 Element Plus 为例:

js
import ElementPlus from 'element-plus'; // 全部组件导入
import 'element-plus/lib/theme-chalk/index.css'; // 全部样式导入

const app = createApp(App);
app.use(ElementPlus);

如果想让组件有ts 提示可以导入 ElementPlus 的类型声明文件,你需要先使用 Volar,请在 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型:

js
/// <reference types="element-plus/global" />

或者

js
// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": ["element-plus/global"]
  }
}
  • 优点: 简单易用,不需要在每个组件中单独引入。
  • 缺点: 可能会增加最终的打包体积,因为即使你没有使用某个组件,它也会被包括在内

按需引入

按需引入(On-Demand Import)意味着只有当组件实际被使用时,它才会被引入和打包。我们可以手动在页面引入需要的组件 和 组件样式

html
<template>
  <div>
    <Button type="primary">Primary Button</Button>
    <Button>Default Button</Button>
    <Button type="dashed">Dashed Button</Button>
    <!-- 其他Button的使用方式 -->
  </div>
</template>

<script setup>
import { Button } from 'ant-design-vue'; // 注意修改引入路径


</script>
<style lang="scss">
@import 'ant-design-vue/lib/button/style';
// 添加其他样式导入
</style>

当然也可以在入口文件将这个事解决掉,这样就不用在每个页面都引入了

js
import { createApp } from 'vue';
import App from './App.vue';
import { Button, Input, DatePicker, /* 其他组件 */ } from 'ant-design-vue'; // 导入需要的组件
import 'ant-design-vue/lib/button/style'; // 导入组件的样式
import 'ant-design-vue/lib/input/style'; // 导入Input组件的样式
import 'ant-design-vue/lib/date-picker/style'; // 导入DatePicker组件的样式
/* 导入其他组件的样式 */
import router from './router'; // 如果使用了路由,导入路由实例

const app = createApp(App);

// 注册需要的组件
app.use(Button);
app.use(Input);
app.use(DatePicker);
/* 注册其他组件 */

// 如果使用了路由,挂载路由实例
app.use(router);

app.mount('#app');

也可以将这部分注册的方法进行封装

js
import { App } from 'vue';
import { Button, Input, DatePicker, /* 其他组件 */ } from 'ant-design-vue';

// 封装的批量注册方法
function registerAntDesignComponents(app: App): void {
  const components = [
    Button,
    Input,
    DatePicker,
    /* 其他组件 */
  ];

  components.forEach(component => {
    app.use(component);
  });
}

export default registerAntDesignComponents;

在 main.ts 中使用

js
import { createApp } from 'vue';
import App from './App.vue';
import registerAntDesignComponents from './registerAntDesignComponents'; // 导入注册方法
import 'ant-design-vue/lib/button/style'; // 导入组件的样式
import 'ant-design-vue/lib/input/style'; // 导入Input组件的样式
import 'ant-design-vue/lib/date-picker/style'; // 导入DatePicker组件的样式
/* 导入其他组件的样式 */
import router from './router'; // 如果使用了路由,导入路由实例

const app = createApp(App);

// 使用封装的注册方法
registerAntDesignComponents(app);

// 如果使用了路由,挂载路由实例
app.use(router);

app.mount('#app');

也可以自定义组件名导入

js
import { ElButton } from 'element-plus'
app.component(ElButton.name, ElButton)

上面的方法还需要每次都要手动导入css 因此后来诞生了新的方法,通过babel-plugin-import来解决引入组件还需要引入样式 来进行按需加载,加入这个插件后,可以省去 style 的引入。就可以直接写法如下不用引入css

js
import { Button } from 'ant-design-vue';

但这种仍然需要手动引入组件,而且还必须使用 babel

但在element-plus中,可以使用 unplugin-element-plus 插件来替代 babel-plugin-import,当使用插件会自动转换,针对不同打包工具使用可以参考 或者可以使用 vite-plugin-style-import

js
import { ElButton } from 'element-plus'

//    ↓ ↓ ↓ ↓ ↓ ↓

import { ElButton } from 'element-plus'
import 'element-plus/es/components/button/style/css'
  • 优点: 减少了最终的打包体积,只有实际使用的组件会被包括。
  • 缺点: 需要在每个使用组件的文件中单独引入,稍微繁琐。

自动导入(目前主流)

自动导入可以分为两大类自动导入组件第三方库,组件就是我们常见的vue 第三方组件库,至于 第三方库 这里指的是 第三方手动导入的例如 dayjs 等第三方js 工具库

正是这样的两种分类因此自动导入就有了两种功能的自动导入库,unplugin-vue-componentsunplugin-auto-import

unplugin-vue-components

unplugin-vue-components 专为 Vue 组件设计,可以自动导入 支持 Vue2 和 Vue3 组件和指令。可以不需要手动引入组件,能够让开发者就像全局组件那样进行开发,但实际上又是按需引入,且不限制打包工具,不需要使用 babel

安装

bash
npm i unplugin-vue-components -D

# or

pnpm add -D unplugin-vue-components

并且提供了内置的解析器用于流行的 UI 库,比如 Vuetify,Ant Design Vue 和 Element Plus,使用 ElementPlus 为例

bash
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
  
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

如果你是webpack 打包工具

js
module.exports = {
  // The rest of the config here should be left untouched
  plugins: [
    require('unplugin-vue-components/webpack')({ /* plugin config here */ }) // This imports and registers the plugin in Webpack
  ]
}

正常况下,该插件会导入自动导入位于 src/components 路径下的组件,但你也可以通过 dirs 选项进行自定义。如果你使用 TypeScript,该插件能提供自动导入组件的类型支持。

js
import Components from 'unplugin-vue-components/vite'

export default defineConfig(
  plugins: [
    Components({dirs: ["src/example/dir/here","other/example"]})
  ]
})

也可以自定义解析器,如果组件名称以 "Example" 开头,它会将组件的名称去掉前缀 "Example" 并指定组件的导入来源为 "example-package"。这样,在使用这个插件时,当你在代码中引用 "ExampleButton" 组件时,它会自动导入 "example-package" 中的 "Button" 组件。这可以帮助你更灵活地组织和导入组件,特别是在项目中使用了多个包或模块时

js
Components({
  resolvers: [
    (componentName) => {
      if (componentName.startsWith("Example")) {
        return { name: componentName.slice(6), from: "example-package" };
      }
    },
  ],
});

如果为了获得正确的 TypeScript 支持,使用 Volar。Volar 是一个用于 Vue 的语言服务器,它允许你在 IDE/文本编辑器中使用更高级的 Vue 开发特性,比如类型检查、语法突显和自动补全。虽然 Vue 还不支持 TypeScript 的这种用法,但 Volar 已经在这种情况下增加了对类型检查和自动补全的支持,文件以包含 dts 属性,该属性设置为 true,如果安装了 TypeScript,还应该自动启用此选项。您需要做的另一件事是将生成的 components.d.ts(自动导入的组件类型声明文件,这样就可以在ts中使用组件的时候有提示了) 添加到 tsconfig.js include "include": [ "components.d.ts"]列表中。Ts 是包含所有类型的文件,如果您不告诉 TypeScript 包含它,它将不会做任何事情

js
{
  dts: true // put this in the unplugin-vue-components config
}

综合来看提供的所有api 介绍:

  • dirs: 搜索组件的相对路径目录。
  • extensions: 组件的有效文件扩展名。
  • globs: 用于匹配文件名以检测为组件的全局模式。
  • deep: 是否搜索子目录。
  • resolvers: 自定义组件解析器。
  • dts: 生成全局声明的 components.d.ts,默认为 true 如果 TypeScript 已安装。
  • directoryAsNamespace: 允许子目录作为组件的命名空间前缀。
  • collapseSamePrefixes: 折叠相同的前缀(驼峰敏感)以防止命名空间组件名称中的重复。
  • globalNamespaces: 忽略命名空间前缀的子目录路径。
  • directives: 自动导入指令,Vue 3 默认为 true,Vue 2 默认为 false
  • importPathTransform: 在解析之前转换路径。
  • allowOverrides: 允许具有相同名称的组件覆盖其他组件。
  • include: 转换目标的过滤器。
  • exclude: 排除的路径。
  • version: 项目的 Vue 版本,如果未指定,将自动检测。
  • types: 仅提供库中组件的类型(全局注册)。

示例

javascript
Components({
  dirs: ['src/components'],
  extensions: ['vue'],
  deep: true,
  resolvers: [],
  dts: true,
  directoryAsNamespace: false,
  collapseSamePrefixes: false,
  globalNamespaces: [],
  directives: true,
  importPathTransform: v => v,
  allowOverrides: false,
  include: [/\.vue$/, /\.vue\?vue/],
  exclude: [/[\\/]node_modules[\\/]/],
  version: '3',
  types: []
})
  • 关于types数组用于注册全局组件的类型。数组中有一个对象,该对象指定了从 example-package 包中导入两个组件(ExampleComponentOne 和 ExampleComponentTwo)的类型这在你使用某些库(如路由库)提供的全局组件时特别有用。
js
{
  dts: true,
  types: [{
    from: 'example-package',
    names: ['ExampleComponentOne', 'ExampleComponentTwo'],
  }],
}
  • 自定义ui简单实现 resolvers
js
Components({
  resolvers: [
    // ... 其他解析器
    // 自定义xx-ui解析器
    (name) => {
      // name为项目编译时加载到的自定义组件,String类型大驼峰格式的组件名
      // 例如:name = XxButton
      // 判断组件前缀
      if (name.startsWith('Xx')){
        return { 
          // 包名,XxButton -> Button
          importName: name.slice(2), 
          // 路径直接写包名即可,因为我们已经安装了这个包
          path: 'xx-ui'
        }
      }
    }
  ]
})

unplugin-auto-import

unplugin-auto-import 该插件主要用于自动导入 JavaScript 语法和库。它可以自动导入 Vue Composition API、JavaScript 语法、甚至是你自己定义的函数或对象。减少了手动引入的步骤

bash
pnpm add -D unplugin-auto-import
# or
npm i -D unplugin-auto-import

知道这两个库后以element-plus为例,组件可以分为两种,一种就是正常的组件这类组件使用 unplugin-vue-components 就能帮助自动导入,一种事反馈组件,这类组件需要使用 unplugin-auto-import 来帮助自动导入 整体最基本使用如下

js
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()], // 解决 import { ElMessage } from 'element-plus' 这类组件的导入
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

使用的是ts 版本那么他会 生成文件 auto-imports.d.ts 和 是自动导入api声明文件,这样就可以在ts中使用组件的时候有提示了,需要将这两个文件 配置在 tsconfig.json 中的 include 中,这样就可以在ts中使用组件的时候有提示了 "include": [ "auto-imports.d.ts"]

一些常用的其他属性配置

  • include:中指定的文件类型或文件路径才会被 unplugin-auto-import 插件处理,从而进行自动导入,例如 .ts, .tsx, .js, .jsx, .vue, .md 等。如果只有配置 .vue 文件会被 unplugin-auto-import 插件处理,其他类型的文件(如 .js, .ts, .jsx, .tsx 等)将不会进行自动导入

  • imports: 定义全局导入的模块和别名。支持预设(如 'vue', 'vue-router')和自定义设置。

  • defaultExportByFilename: 是否根据文件名自动导入默认模块。

  • dirs: 指定目录来自动导入模块。

  • dts: 生成对应的 .d.ts 文件,用于 TypeScript 支持。

  • vueTemplate: 是否在 Vue 模板内进行自动导入。

  • resolvers: 自定义解析器,与 unplugin-vue-components 兼容。

  • injectAtEnd: 是否在其他导入语句的末尾注入自动导入。

  • eslintrc: 生成对应的 .eslintrc-auto-import.json 文件,用于 ESLint 配置。

示例配置

javascript
AutoImport({
  include: [
    /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
    /\.vue$/, /\.vue\?vue/, // .vue
    /\.md$/, // .md
  ],
  imports: [
    'vue',
    'vue-router',
    {
      '@vueuse/core': [
        'useMouse',
        ['useFetch', 'useMyFetch'],
      ],
      'axios': [
        ['default', 'axios'],
      ],
    },
  ],
  dts: './auto-imports.d.ts', // dts: path.resolve(pathSrc, 'types', 'components.d.ts') // (false) 配置文件生成位置,默认是根目录 /components.d.ts

  vueTemplate: false,
  resolvers: [/* ... */],
  injectAtEnd: true,
  eslintrc: {
    enabled: false,
    filepath: './.eslintrc-auto-import.json',
    globalsPropValue: true,
  },
})

为什么配置 eslintrc 字段,当使用 unplugin-auto-import这个自动导入功能时,有一个小问题:有些代码检查工具(比如ESLint)可能不知道这些自动导入的内容,它们可能会误认为你使用了一些 未定义 的变量或函数,从而给你报错

为了解决这个问题,unplugin-auto-import 提供了一个 eslintrc 设置。这个设置可以帮助你自动生成一个特殊的配置文件,告诉 ESLint:“嘿,这些自动导入的内容是已经定义好的,不要给我报错哦!”

具体来说,这个 eslintrc 设置有几个选项

  • enabled: 这个选项决定是否要生成那个特殊的配置文件。默认是不生成的,但如果你想生成,就把它设置为 true。

  • filepath: 这是那个特殊配置文件的保存位置。默认是在项目的根目录下,名为 .eslintrc-auto-import.json。

  • globalsPropValue: 这个选项决定在配置文件中,如何描述那些自动导入的内容。大多数情况下,你不需要改这个设置。

json
eslintrc: {
  enabled: true,  // 启用这个功能
  filepath: './.eslintrc-auto-import.json',  // 配置文件路径
  globalsPropValue: 'readonly',  // 设置全局变量为只读
}

eslintrc 配置完后要在 eslint 配置文件的 extends 中进行声明

json
extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-typescript',
    '@vue/eslint-config-prettier/skip-formatting',
    './.eslintrc-auto-import.json',
  ]

有关 两者使用的注意事项

提供了 unplugin-vue-components 中 resolvers 属性的ui 库 会存在 css icon 等图标库的配置

unplugin-auto-import 和 unplugin-vue-components 的正确使用方式

unplugin-vue-components 源码原理分析

更多

unplugin-vue-components-resolvers

使用按需引入时,首次启动服务会依赖预构建style

解决案例参考使用按需引入时,首次启动服务会依赖预构建style

Released under the MIT License.