
[Vue 3] Composition API - Plugins
Vue3에서 플러그인이란 속성, 함수, 라이브러리 등 자주 사용될만한 기능들을 묶어놓은 것을 말합니다. Vue router나 Vuex, Pinia 등 라이브러리 등이 이미 플러그인 형태로 사용되고 있습니다. 어떻게 만들고 사용하는 것인지 알아볼까요?
Plugins
플러그인을 딱 어떻게 사용하라고 정한 건 아니지만 보통 다음과 같은 용도로 사용할 수 있습니다.
app.component()
)app.directive()
)app.provide()
)app.config.globalProperties
)이 글에서는 라이브러리와 연계하는 것 빼고 한 번씩 간략히 다뤄보겠습니다.
플러그인 파일 만들기
보통은 plugin을 위한 별개의 파일을 만들어서 export하는 식으로 합니다. 여기서는 src/plugins/myInput.js
이란 이름으로 파일을 만들겠습니다. 그리고 install이란 함수를 가진 객체 export하면 됩니다.
export default {
install(app, options) {
// ...
}
}
아니면 함수를 반환해도 됩니다.
export default function (app, options) {
// ...
}
플러그인 사용하기
만약 플러그인을 만들었다면 main.js
파일에서 app의 use
함수를 사용합니다.
import { createApp } from "vue";
import App from "./App.vue";
import MyPlugin from "./plugins/myplugin";
const app = createApp(App);
// use 사용!
app.use(MyPlugin);
app.mount("#app");
만약에 플러그인에 전달하고자하는 값이 있다면 두 번째 매개변수로 전달할 수 있습니다.
const options = {
placeholder: 'name',
};
app.use(MyPlugin, options);
글로벌 컴포넌트 등록하기
app.component
함수를 이용하면 글로벌 컴포넌트를 등록할 수 있습니다. 만일 install
함수 내에서 이를 사용하면, 플러그인을 사용할 때 컴포넌트가 등록이 됩니다.
우선 임의로 컴포넌트를 만들어보겠습니다.
<template>
<input type="text" placeholder="Email" />
</template>
그리고 이 컴포넌트를 플러그인에서 글로벌로 등록합니다.
import MyInput from "@/components/MyInput.vue";
export default {
install(app, options) {
app.component("MyInput", MyInput);
},
};
이미 플러그인을 사용하고 있으니 MyInput
컴포넌트가 글로벌로 등록되었겠죠? 그럼 App.vue
에서 사용할 수 있습니다.
<template>
<MyInput />
</template>
글로벌 디렉티브 등록하기
디렉티브는 app.directive()
를 이용해서 등록할 수 있습니다. 예를 들어 알파벳을 대문자로 만들어주는 디렉티브 uppercase
를 만든다고 해볼게요.
import MyInput from "@/components/MyInput.vue";
export default {
install(app, options) {
app.component("MyInput", MyInput);
// 디렉티브 등록!
app.directive("uppercase", (el) => {
el.style.textTransform = "uppercase";
});
},
};
그럼 이 디렉티브를 MyInput에서 사용하면 알파벳이 대문자가 됩니다.
<template>
<MyInput v-uppercase />
</template>
provide 생성
만약 plugin을 등록했을 때 하위 컴포넌트들에 전달하고 싶은 값이 있을 수 있습니다. app.provide
를 이용하면 provide를 생성할 수 있습니다. 예를 들어 플러그인을 사용할 때 options을 전달할 수 있다고 했습니다.
const options = {
placeholder: 'name',
};
app.use(MyPlugin, options);
이 값을 provide로 전달해보겠습니다.
import MyInput from "@/components/MyInput.vue";
export default {
install(app, options) {
app.component("MyInput", MyInput);
app.directive("uppercase", (el) => {
el.style.textTransform = "uppercase";
});
// Provide 생성!
app.provide("myInputOption", options);
},
};
이제 이 값은 하위 컴포넌트 어딘가에서 inject
로 가져와 사용할 수 있습니다. MyInput 컴포넌트에서 가져와볼까요?
<template>
<input type="text" ref="input" placeholder="Email" />
</template>
<script setup>
import { ref, inject, onMounted } from "vue";
const input = ref(null);
// inject로 option 값을 가져옴
const options = inject("myInputOption");
onMounted(() => {
input.value.placeholder = options.placeholder;
});
</script>
그러면 EMAIL이 NAME으로 바뀐 것을 볼 수 있습니다!
글로벌 인스턴스 속성 추가
app.config.globalProperties
을 이용하면 모든 컴포넌트에서 사용할 수 있는 속성(변수 또는 함수 등)을 만들 수 있습니다.
export default {
install(app, options) {
app.config.globalProperties.$sayHello = () => {
console.log("Hello");
};
},
};
이 $sayHello
값은 모든 컴포넌트의 속성처럼 들어가기 때문에 편하게 사용하면 됩니다.
export default {
created() {
this.$sayHello();
}
}
갑자기 Options API를 사용하는 이유는 Composition API에서는 this
를 접근할 수 없기 때문에 $sayHello
함수를 사용할 수가 없습니다. 굳이 사용하려면 provide를 통해 전달하면 됩니다.
app.provide('sayHello', app.config.globalProperties.$sayHello);
그런데 이렇게 할거면 그냥 함수를 여기다가 넣…