记录一下vue3+typescript开发公共组件的注意事项

我的项目构造

|-- examples 搁置用于测试组件的代码|   |-- App.vue|   |-- main.ts|-- packages 搁置组件的代码|   |-- index.ts|   |-- shims-vue.d.ts|   |-- assets|   |   |-- logo.png|   |-- components|       |-- helloWorld|           |-- HelloWorld.tsx 组件的定义|           |-- index.ts 组件裸露以及全局申明|-- public|   |-- favicon.ico|   |-- index.html|-- tests|   |-- unit|       |-- example.spec.ts|-- .browserslistrc|-- .eslintrc.js|-- .gitignore|-- babel.config.js|-- jest.config.js|-- package-lock.json|-- package.json|-- README.md|-- tsconfig.json|-- vue.config.js

组件编写

组件定义

// packages/components/helloWorld/HelloWorld.tsximport { defineComponent, type ExtractPropTypes } from "vue";const props = {  /** 姓名 */  name: String,  /** 年龄 */  age: Number,};// ExtractPropTypes:承受一个类型,返回vue3解决后的类型export type HelloWorldProps = ExtractPropTypes<typeof props>;export default defineComponent({  name: "HelloWorld",  props: props,  emits: ["click"],  setup(props, { emit }) {    const onClick = (event: MouseEvent) => {      emit("click", event);    };    return () => {      return (        <tag>          <div onClick={onClick}>            HelloWorld, {props.name}, {props.age}          </div>        </tag>      );    };  },});

组件申明,裸露

// packages/components/helloWorld/index.tsimport HelloWorld from "./HelloWorld";export { type HelloWorldProps } from "./HelloWorld";export default HelloWorld;// 组件调用时,提供代码提醒declare module "vue" {  export interface GlobalComponents {    HelloWorld: typeof HelloWorld;  }}

组件注册

// packages/index.tsimport type { App } from "vue";import HelloWorld from "./components/helloWorld";// 定义install办法,供内部调用const install = (Vue: App) => {  Vue.component("HelloWorld", HelloWorld);};export default { install };

编译插件

npm i -D vue-ts

配置文件

package.json

"scripts": {    "lib": "vue-cli-service build --target lib --name xxx --dest lib packages/index.ts && vue-tsc --declaration --emitDeclarationOnly",}

tsconfig.json

{  "compilerOptions": {    "outDir": "lib/types", // 指定编译后的文件门路    "target": "esnext",    "module": "CommonJS",    "strict": true,    "jsx": "preserve",    "moduleResolution": "node",    "skipLibCheck": true,    "esModuleInterop": true,    "allowSyntheticDefaultImports": true,    "forceConsistentCasingInFileNames": true,    "useDefineForClassFields": true,    "sourceMap": true,    "baseUrl": ".",    "types": [      "webpack-env",      "jest"    ],    "paths": {      "@/*": [        "packages/*"      ]    },    "lib": [      "esnext",      "dom",      "dom.iterable",      "scripthost"    ]  },  "include": [    "packages/**/*.ts",    "packages/**/*.tsx"  ],  "exclude": [    "node_modules"  ]}