传送门
约定:npm包名vue3-el-pro-table
,引用vue3-el-pro-table
的包名为“本项目”。
声明:Vue3ProTable.vue
代码是在这个项目的基础上进行修改的。
作者:hans774882968以及hans774882968以及hans774882968
yarn add vue3-el-pro-table
src/main.ts
import 'vue3-el-pro-table/dist/vue3-el-pro-table.css';
import Vue3ProTable from 'vue3-el-pro-table';
createApp(App)
.use(Vue3ProTable)
.mount('#app');
Then use
directly in .vue
file.
Import interface:
import { Vue3ProTableProps } from 'vue3-el-pro-table';
Component props definition:
export declare interface Vue3ProTableProps {
request: (...args: any[]) => Promise<{ data: object[], total: number }>
// 表格标题
title?: string
// 是否隐藏标题栏
hideTitleBar?: boolean
// 搜索表单配置,false表示不显示搜索表单
search?: boolean | object
border?: boolean
// 表头配置
columns?: object[]
// 行数据的Key,同elementUI的table组件的row-key
rowKey?: string
// 分页配置,false表示不显示分页
pagination?: boolean | object
tree?: object
// The above attributes are all from https://github.com/huzhushan/vue3-pro-table. The following properties are added by me.
loadTableDataBeforeMount?: boolean
blockRedundantRequestOnReset?: boolean
paddingLeft?: string | number
paddingRight?: string | number
}
Plz refer to https://github.com/huzhushan/vue3-pro-table for instructions on how to use vue3-el-pro-table
.
根据参考链接3,实际上我们只需要提供一个符合Vue插件格式的入口install.js
,和一个Vue组件。但为了满足npm包迭代过程中的预览、测试等需求,我们仍然需要以组件库的标准来开发这个npm包。因此我采用的方案是:先使用vue-cli
快速创建一个项目,满足组件的预览、测试等需求,在此基础上再新增一个构建流程。
vue-cli
创建一个普通的Vue3 + TS项目。src/components/Vue3ProTable.vue
。src/install.js
:import HelloWorld from './components/HelloWorld.vue';
import Vue3ProTable from './components/Vue3ProTable.vue';
function install(app) {
if (install.installed) return;
install.installed = true;
app.component('test-hello-world', HelloWorld); // 顺便把脚手架生成的组件也注册为全局组件
app.component('vue3-pro-table', Vue3ProTable);
}
Vue3ProTable.install = install;
export default { install };
build-lib
命令并运行yarn build-lib
——这就是vue3-el-pro-table
生成Vue插件的构建命令:{
"scripts": {
"build": "vue-cli-service build", // 作为对比
"build-lib": "vue-cli-service build --target lib --name vue3-el-pro-table ./src/install.js" // 参考:https://cli.vuejs.org/guide/build-targets.html#library
},
}
package.json
修改下入口:{
"main": "dist/vue3-el-pro-table.umd.js",
}
在另一个项目(即本项目)预览最新改动:
yarn add file:../vue3-el-pro-table
接下来开始踩坑了。当引入的组件使用slot的时候会报错:
Cannot read properties of null (reading 'isCE')
根据参考链接2,原因是本项目和vue3-el-pro-table
各有一个vue,即使它们版本相同也会引起冲突。虽然参考链接2的提问说给webpack添加vue配置无济于事,但我的项目用这个配置是可以解决问题的。
在本项目的vue.config.js
禁用symlinks并alias vue:
const { defineConfig } = require('@vue/cli-service');
const path = require('path');
module.exports = defineConfig({
chainWebpack(config) {
config.resolve.symlinks(false);
config.resolve.alias.set('vue', path.resolve('./node_modules/vue'));
},
devServer: {
port: 8090,
},
transpileDependencies: true,
});
为了防止本项目报TS错误,我们的npm包vue3-el-pro-table
需要给出.d.ts
文件。
package.json
指定类型定义文件路径:{
"types": "dist/global.d.ts"
}
tsconfig.json
新增配置:{
"compilerOptions": {
"types": [
"webpack-env",
"jest",
"vue3-el-pro-table/dist/global.d.ts", // 获取 vue3-el-pro-table 注册的全局组件的类型提示
"element-plus/global.d.ts" // 获取 element-plus 组件的类型提示
],
}
}
global.d.ts
不应该放在dist
目录,因此我把它放到了src/global.d.ts
,并配置CopyWebpackPlugin
。vue3-el-pro-table
的vue.config.js
:
const { defineConfig } = require('@vue/cli-service');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = defineConfig({
configureWebpack: {
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src', 'global.d.ts'),
to: path.resolve(__dirname, 'dist'),
},
],
}),
],
},
transpileDependencies: true,
});
最理想的情况下dist/global.d.ts
能在编译时直接生成,但可惜我们参考的Vue3ProTable.vue
不是一个TS组件,且改造为TS组件的工作量过大,因此global.d.ts
是手动维护的,传送门。
我们期望dist/global.d.ts
能够给组件提供类型提示。根据参考链接4,需要以下代码:
declare const CVue3ProTable: import('vue').DefineComponent<......>;
declare const CHelloWorld: import('vue').DefineComponent<{
msg: StringConstructor;
}, unknown, unknown, object, object, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, object, string, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<import('vue').ExtractPropTypes<{
msg: StringConstructor;
}>>, object, object>;
declare module 'vue' {
export interface GlobalComponents {
Vue3ProTable: typeof CVue3ProTable
TestHelloWorld: typeof CHelloWorld
}
}
这里的CVue3ProTable, CHelloWorld
看上去很复杂,不会是手写的吧?的确不是手写的,可以让vue-tsc
生成。首先安装vue-tsc
并新增命令:
{
"gen-declaration": "vue-tsc -p tsconfig.declaration.json"
}
然后新增tsconfig.declaration.json
:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "es",
"declaration": true,
"emitDeclarationOnly": true
},
"include": ["src"],
"exclude": ["node_modules", "**/__tests__/**", "**/__demos__/**", "**/*.md"]
}
最后执行yarn gen-declaration
,把组件的类型定义复制到global.d.ts
即可。