封装自定义组件库:vue3
-
思考:如何封装一个像element-ui的组件库?
-
怎么直接在main.js入口文件use该第三方组件库,全局引入或者按需加载,就可以使用到该组件库的组件呢?并且在模板内有相应的代码提示呢?
1. 首先我们解决第一个问题:use注册组件库、全局引入和按需引入
- 我们先来看element-ui如何使用的
// 全局引入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 注册
Vue.use(ElementUI);
// 按需引入
// 第三包组件库按需引入
// 第一步是安装相关的插件,在babel.config.js配置相关信息,可以自行往官网查看文档
// 第二部按需引入组件
import { Button, Select } from 'element-ui';
// 第三步全局注册组件
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
-
接下来先来说明全局引入
-
首先先自己创建一个自定义button组件(components/UI/Button/index.vue)
<template> <button class="xtx-button ellipsis" :class="[size, type]"> <slot></slot> </button> </template> <script setup lang="ts"> import type { PropType } from 'vue'; defineProps({ // 控制按钮大小 size: large middle small mini size: { type: String as PropType<'large' | 'middle' | 'small' | 'mini'>, default: 'middle', }, // 控制按钮类型 type: primary plain gray type: { type: String as PropType<'primary' | 'plain' | 'gray'>, default: 'default', }, }); </script> <style scoped lang="less"> // 基于类名定义一些和定制样式无关的样式 .xtx-button { appearance: none; border: none; outline: none; background: #fff; text-align: center; border: 1px solid transparent; border-radius: 4px; cursor: pointer; } // 大 .large { width: 240px; height: 50px; font-size: 16px; } // 中 .middle { width: 180px; height: 50px; font-size: 16px; } // 小 .small { width: 100px; height: 32px; } //超小 .mini { width: 60px; height: 32px; } .default { border-color: #e4e4e4; color: #666; } // 确认 .primary { border-color: @xtxColor; background: @xtxColor; color: #fff; } // 普通 .plain { border-color: @xtxColor; color: @xtxColor; background: lighten(@xtxColor, 50%); } // 灰色 .gray { border-color: #ccc; background: #ccc; color: #fff; } </style> -
第二步,components/UI文件夹下新建index.ts文件
// 以Button组件为例子 import Button from './Button/index.vue'; // 按需导出组件 export const XtxButton = Button; // 封装成插件形式 export default { insatll(app:APP){ // 全局注册 app.component('XtxButton', Button); } } -
封装组件和按需导出组件、插件形式导出组件完成
// main.ts import { createApp } from 'vue'; import App from '@/App.vue'; // 自定义组件库 import XtxUI from './components/XtxUI'; // 按需导入Button import {BUtton} from './components/XtxUI' const app = createApp(App); // 注册全局组件库,Plugin插件,use了就会立即执行install方法 app.use(XtxUI) // 按需导入自然也是可以的 app.component('MyButton',Button) app.mount('#app'); -
以上完成了导入导出功能。最后还差一步,怎么实现在组件内使用组件有类型提示呢?
-
答案是:为自定义组件库声明类型提示
-
在components/UI文件夹下新建 components.d.ts类型声明文件
-
注意:.d.ts文件仅仅是提供类型声明,并不会编译成js代码
-
// 以Button组件为例 import Button from './Button/index.vue'; // 给Volar去识别 declare module 'vue' { // 全局组件需通过 GlobalComponents 接口定义(Volar文档中说明) export interface GlobalComponents { // vue-router 的两个全局组件,添加类型声明 RouterLink: typeof import('vue-router')['RouterLink']; RouterView: typeof import('vue-router')['RouterView']; // 自己的全局组件注册类型声明, typeof 表示基于获取组件的TS类型 MyButton: typeof Button; } -
声明类型文件之后,在组件内我们就可以使用到跟第三方组件库一样的类型提示啦!