寻雾启示

V1

2023/01/15阅读:12主题:全栈蓝

vue3+typescript开发公共组件

记录一下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.tsx
import { 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.ts
import HelloWorld from "./HelloWorld";
export { type HelloWorldProps } from "./HelloWorld";
export default HelloWorld;

// 组件调用时,提供代码提示
declare module "vue" {
  export interface GlobalComponents {
    HelloWorld: typeof HelloWorld;
  }
}

组件注册

// packages/index.ts
import 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"
  ]
}

分类:

前端

标签:

Vue.js

作者介绍

寻雾启示
V1