이 문서에서는 다음을 포함하여 구성 요소 라이브러리에서 구성 요소를 개발하는 방법을 소개합니다.
- 로컬에서 실시간으로 구성 요소를 디버깅하는 방법
- 컴포넌트 라이브러리가 전역 가져오기를 지원하도록 만드는 방법
- 설정 구문 설탕에서 구성 요소의 이름을 지정하는 방법
- 컴포넌트를 개발하는 방법
디렉토리 구조
구성 packages
요소가 저장된 디렉토리 아래에 새 패키지 components
와 두 개의 패키지를 만들고 utils 패키지는 일부 공용 메서드 등을 저장합니다. 두 파일에서 각각 @easyest/components @easyest/utils를 실행합니다.utils
components
pnpm init,并将它们的包名改为
和
{
"name": "@easyest/components",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
모든 구성 요소를 저장할 components
디렉터리 아래에 새 디렉터리를 만듭니다 src
. 최종 디렉터리 구조는
물론 현재 구조일 뿐이며 스타일 및 테스트와 같은 파일 디렉터리도 있기 때문에 나중에 조정할 것입니다.
테스트 구성 요소
파일 button.vue
에 간단한 버튼 작성
<template>
<button>测试按钮</button>
</template>
그런 다음 button/index.ts로 내보냅니다.
import Button from "./button.vue";
export {
Button };
export default Button;
나중에 Icon, Upload, Select 등과 같은 많은 구성 요소가 있으므로 components/src/index.ts 세트의 모든 구성 요소를 내보내야 합니다.
export * from "./button";
마지막으로 components/index.ts
외부 사용을 위해 모든 구성 요소를 내보냅니다.
export * from "./src/index";
다음으로 이전 글에서 빌드한 플레이 프로젝트에서 테스트를 진행하겠습니다 먼저 paly 프로젝트 @easyest/components
(컴포넌트 라이브러리 패키지 이름, 후속 릴리스에서 이름을 직접 수정 가능) 에 로컬로 설치합니다.
pnpm add @easyest/components
그런 다음 app.vue
인용Button
<template>
<div>
<Button />
</div>
</template>
<script lang="ts" setup>
import {
Button } from "@easyest/components";
</script>
프로젝트를 시작할 때 Button 컴포넌트를 볼 수 있으며 Button 컴포넌트를 수정하면 핫 업데이트 효과도 있습니다.
app.use 전역 마운트 구성 요소
가끔 컴포넌트를 사용할 때 전체 컴포넌트 라이브러리를 마운트하기 위해 직접 app.use()를 사용하고 싶을 때가 있는데 실제로 app.use()를 사용하면 들어오는 매개변수의 install 메소드를 호출하게 되므로 먼저 각 컴포넌트를 제공합니다. component 설치 방법을 추가한 다음 전체 구성 요소 라이브러리를 내보내고 button/index.ts를 다음으로 변경합니다.
import _Button from "./button.vue";
import type {
App, Plugin } from "vue";
type SFCWithInstall<T> = T & Plugin;
const withInstall = <T>(comp: T) => {
(comp as SFCWithInstall<T>).install = (app: App) => {
const name = (comp as any).name;
//注册组件
app.component(name, comp as SFCWithInstall<T>);
};
return comp as SFCWithInstall<T>;
};
export const Button = withInstall(_Button);
export default Button;
components/index.ts가 다음으로 수정되었습니다.
import * as components from "./src/index";
export * from "./src/index";
import {
App } from "vue";
export default {
install: (app: App) => {
for (let c in components) {
app.use(components[c]);
}
},
};
이 시점에서 전역적으로 마운트할 때 구성 요소 이름으로 사용할 좋은 이름을 button.vue
지정 해야 합니다.name:ea-button
<template>
<button>测试按钮</button>
</template>
<script lang="ts">
import {
defineComponent } from "vue";
export default defineComponent({
name: "ea-button",
setup() {
return {
};
},
});
</script>
이때 play/main.ts
컴포넌트 라이브러리를 전역으로 마운트하십시오.
import {
createApp } from "vue";
import App from "./app.vue";
import easyest from "@easyest/components";
const app = createApp(App);
app.use(easyest);
app.mount("#app");
app.vue에서 구성 요소를 사용하면 ea-button
구성 요소 라이브러리가 성공적으로 마운트된 것을 확인할 수 있습니다.
<template>
<div>
<ea-button />
</div>
</template>
<script lang="ts" setup></script>
하지만 이 전역 구성 요소에는 속성 프롬프트가 없으므로 vscode에서 volar를 사용하여 전역 구성 요소에 프롬프트 효과를 추가해야 합니다.
먼저 설치@vue/runtime-core
pnpm add @vue/runtime-core -D -w
src 아래에 새 항목 만들기components.d.ts
import * as components from "./index";
declare module "@vue/runtime-core" {
export interface GlobalComponents {
EaButton: typeof components.Button;
EaIcon: typeof components.Icon;
}
}
export {
};
이때 글로벌하게 도입된 컴포넌트들도 즉각적인 효과를 발휘한다.
참고: 사용자가 구성 요소 라이브러리를 사용할 때 프롬프트 효과가 나타나기 전에 사용자는 tsconfig.json: ["easyest/lib/src/components"]에서 유형을 구성해야 합니다.
"compilerOptions": {
//...
"types": ["easyest/lib/src/components"]
},
설정 구문 사용
Vue 컴포넌트를 개발할 때 설정 구문을 사용하는 것이 매우 편리하다는 것은 우리 모두 알고 있지만 문제가 있습니다. 즉, 설정 구문을 사용할 때 구성 요소의 이름을 어떻게 지정해야 할까요?
실제로 두 가지 솔루션이 있습니다. 하나는 script
다음과 같은 다른 레이블 이름을 작성하는 것입니다.input.vue
<template>
<button>测试按钮</button>
</template>
<script lang="ts">
import {
defineComponent } from "vue";
export default defineComponent({
name: "ea-button"
});
</script>
<script lang="ts" setup></script>
이 방법은 분명히 이상합니다.
두 번째 방법은 플러그인을 사용하여 unplugin-vue-define-options
해결하는 것입니다. 테스트 환경에서는 플레이 프로젝트에서 구성해야 합니다.
먼저 전역적으로 설치합니다 unplugin-vue-define-options
. 이 플러그인도 사용되므로 나중에 패키징 및 구성을 위해 최신 버전 설치는 프롬프트 오류, 후속 작성자가 해결하는 방법 보기, 일시적으로 // @ts-ignore
무시
pnpm add unplugin-vue-define-options -D -w
그런 다음 play/vite.config.ts
플러그인을 가져옵니다.
import {
defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// @ts-ignore
import DefineOptions from "unplugin-vue-define-options/vite";
export default defineConfig({
plugins: [vue(), DefineOptions()],
});
이 시점에서 defineOptions
함수를 직접 사용하여 구성 요소 이름을 정의 할 수 있습니다.
<template>
<button>测试按钮</button>
</template>
<script lang="ts" setup>
defineOptions({
name: "ea-button" });
</script>
컴포넌트 개발
우리 모두는 구성 요소가 다른 효과를 달성하기 위해 일부 매개 변수를 허용해야 한다는 것을 알고 있습니다. 예를 들어 버튼 구성 요소는 type、size、round
다음과 같은 속성을 받아야 합니다 type
.
수신에 따라 type
Button 구성 요소에 다른 클래스 이름을 지정할 수 있습니다.
// button.vue
<template>
<button class="ea-button" :class="buttonStyle"><slot /></button>
</template>
<script lang="ts" setup>
import "./style/index.less";
import {
computed } from "vue";
defineOptions({
name: "ea-button" });
type ButtonProps = {
type?: string;
};
const buttonProps = defineProps<ButtonProps>();
const buttonStyle = computed(() => {
return {
[`ea-button--${
buttonProps.type}`]: buttonProps.type };
});
</script>
여기서 스타일 파일을 소개하고, Button 컴포넌트의 스타일을 저장할 새로운 style 폴더를 button 디렉토리에 생성합니다.
src/button/style/index.less
다음과 같이
.ea-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
border: 1px solid #dcdfe6;
color: #606266;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: 0.1s;
font-weight: 500;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
}
.ea-button.ea-button--primary {
color: #fff;
background-color: #409eff;
border-color: #409eff;
&:hover {
background: #66b1ff;
border-color: #66b1ff;
color: #fff;
}
}
이때 app.vue에 Button 컴포넌트를 도입하여 원하는 효과를 볼 수 있습니다.
<template>
<div>
<Button type="primary">主要按钮</Button>
</div>
</template>
<script lang="ts" setup>
import {
Button } from "@easyest/components";
</script>
컴포넌트 개발에는 많은 내용이 포함될 수 있으므로 여기서는 자세히 설명하지 않겠습니다. 여기서는 컴포넌트 개발의 일반적인 아이디어만 간략하게 소개하겠습니다. 앞으로 몇 가지 공통적인 컴포넌트가 개발될 것입니다. 환영합니다. 수집하고 주목하십시오!