使用 TypeScript 搭建自己的公共组件库并使用 CDN (script)的方式引入详细教程

671 阅读2分钟

首先,为了方便快捷可以直接使用 Vue CLI 去生成一个新的工程,用来进行组件库的开发,按照正常的套路去写组件就行,当然,条件允许或者实力足够可以定制化一些东西,使用 jsx 去开发。

  • 开发完成组件目录如下

    image.png

  • 每个组件导出的时候都要添加 install 方法以便 使用 Vue.use 注册组件

  • 注意:如果组建中用到其他组件,需要 在 components 中注入,全局注册的不好使,而且名字要和模板中使用的组件对应起来

import { Table as ATable } from 'lhd-ant-design-vue';
@Component({ components: { ATable } })
export default class CommonTable extends Vue {}
  • commonTitle/index.ts
import { VueConstructor } from 'vue';
import CommonTitle from './index.vue';


(CommonTitle as any).install = (Vue: VueConstructor) => {
    Vue.component('CommonTitle', CommonTitle);
};


export default CommonTitle;
  • commonTitle/index.vue
<template>
    <div class="common-title">{{ title }}</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class CommonTitle extends Vue {
    @Prop({ default: '' }) title!: string;
}
</script>


<style lang="scss" scoped>
.common-title {
    position: relative;
    padding-left: 12px;
    display: flex;
    align-items: center;
    height: 24px;
    font-size: 16px;
    color: #1d1d1d;
}
</style>
  • index.ts 入口文件导出中开发好的组件
/**
 * 自定义组件
 */
import FixedFooter from './packages/fixedFooter';
import SearchForm from './packages/searchForm';
import CommonTable from './packages/commonTable';
import IconButton from './packages/iconButton';
import CommonTitle from './packages/commonTitle';
import TableForm from './packages/tableForm';
import SelectInput from './packages/selectInput';
import ImagesUpload from './packages/imagesUpload';
import FilesUpload from './packages/filesUpload';
export { FixedFooter, SearchForm, CommonTitle, CommonTable, TableForm, ImagesUpload, FilesUpload, AddressCascader };
  • 添加 index.ts 入口的 install 方法
export { default as LHDAntDesignVue } from 'lhd-ant-design-vue';
export function install(vue: VueConstructor) {
    const components = [
        FixedFooter,
        SearchForm,
        CommonTitle,
        CommonTable,
        TableForm,
        ImagesUpload,
        FilesUpload,
        AddressCascader,
    ];


    vue.component('a-table', Table);
    components.forEach(component => {
        vue.use(component as ComponentInstall);
        // vue.component(component.name, component);
    });


    vue.prototype.$message = message;
    // Vue.prototype.$notification = notification;
    vue.prototype.$info = Modal.info;
    vue.prototype.$success = Modal.success;
    vue.prototype.$error = Modal.error;
    vue.prototype.$warning = Modal.warning;
    vue.prototype.$confirm = Modal.confirm;
    vue.prototype.$destroyAll = Modal.destroyAll;


    vue.component('VueDraggableResizable', VueDraggableResizable);
}


/**
 * 暴露公共配置
 */
export default { version, install, config: Config };
  • vue.config.js 中可以配置相关输出目录,对文件进行拆分等等
  • package.json 中添加打包命令
"scripts": {
    "lib": "vue-cli-service build --target lib --inline-vue --name antdVueBasedComponentssrc/index.ts",
},
// 注意:antdVueBasedComponents 就是导出的模块名称
  • 运行打包命令
yarn lib
  • 生成如下目录,部署到服务器上,拿到 CDN 地址

    image.png

  • 在应用的 vue.config.js 中配置 externals

 chainWebpack: config => {
        // Ignore all locale files of moment.js
        config.plugin('ignore').use(new webpack.IgnorePlugin(/^./locale$/, /moment$/));
        config.set('externals', {
            // 如果在打包期间,发现 import 的一个包名为 vue,就不会把这个包合并到文件中
            // 而是去 window 全局查找 Vue 对象,并直接使用
            'antd-vue-based-components': 'antdVueBasedComponents',
        });
  • 在inde.html 中以 CDN 方式引入
<link rel="stylesheet" href="http://localhost:3000/1.1.1/antdVueBasedComponents.css">
<script src="http://localhost:3000/1.1.1/antdVueBasedComponents.umd.min.js"></script>
  • 完事,可以用了,大功告成

  • ps:由于时间原因,写的很简陋,有问题欢迎提问