-
Vue Class Component with DecoratorFrameworks, Platforms and Libraries/Vue.js 2023. 9. 16. 16:00
기존에 Vue 2 버전을 쓰는 경우 TypeScript의 도입이 매끄럽지 않지만 TypeScript와 같이 사용하기 위하여 Vue.extend()를 사용하여 객체로 만들어 사용하는 방법과 Class Component 형태로 만들어 쓰는 두 가지 방법 중 하나를 선택하여 사용합니다. 현재 운영 중인 Vue.js기반의 application의 경우는 이 중에서 Class Component로 만들어 사용하고 있으며 Decorator를 좀 더 활용하기 위해 추가로 라이브러리를 이용하여 구성했습니다. 그래서 어떻게 Decorator를 이용하여 Vue Class Component를 어떻게 구성했는지 소개하려고 합니다.
Vue Class Component Example
기본적인 Vue Class Component 형태는 vue-class-component를 이용하여 구성합니다.
// https://class-component.vuejs.org/ <template> <div> <button v-on:click="decrement">-</button> {{ count }} <button v-on:click="increment">+</button> </div> </template> <script> import Vue from 'vue' import Component from 'vue-class-component' // Define the component in class-style @Component export default class Counter extends Vue { // Data count = 0 // Methods increment() { this.count++ } decrement() { this.count-- } // Computed Properties get countPlusOne() { return this.count + 1; } // Vue lifecycle hooks mounted() { console.log('mounted'); } destroyed() { console.log('destroyed'); } } </script>
Vue Instance를 Vue Class Component 형태로 나타낸 예제입니다.
하지만 vue-property-decorator 라이브러리를 통해 좀 더 Decorator를 활용하려고 합니다. vue-property-decorator는 Vue에서 Class Component 형태로 개발을 도와주는 Decorator를 지원하는 라이브러리이며 vue-class-component 라이브러리를 완전히 의존하지만 Vue에서 정식으로 제공하는 라이브러리는 아닙니다.
vue-property-decorator example
자주 쓰는 Decorator 위주로 예시를 구성했습니다.
// Component.vue <template> <!-- template --> <div ref="divEl"> <AnotherComponent ref="anotherComponent" /> <TestComponent /> </div> </template> <script lang="ts"> import { Vue, Component, Prop, PropSync, Watch, Ref, } from 'vue-property-decorator'; import TestComponent from '@/components/TestComponent.vue'; import AnotherComponent from '@/components/AnotherComponent.vue' @Component({ name: 'Component', components: { TestComponent, }, }) export default class extends Vue { @Prop() readonly num!: number; @PropSync('text', { type: String }) syncedText!: string; @Watch('flag', { immediate: true, deep: true }) onFlagChanged(val: boolean, oldVal: boolean) {}; @Ref() readonly divEl!: HTMLDivElement; @Ref() readonly anotherComponent!: AnotherComponent; private flag = false; } </script> <style lang="scss" scoped> // style </style>
@Component, mixins의 경우 vue-class-component에서 제공하는 Decorator를 그대로 사용하며 그 외 Decorator의 경우 vue-property-decorator에서만 사용 가능한 Decorator입니다.
Vue에서 사용하는 props, watch, ref, emit 등을 Decorator를 이용하여 사용할 수 있고 @PropsSync, @ModelSync 등 기존에 없던 옵션들도 Decorator를 이용하여 사용할 수 있습니다. Decorator의 종류는 vue-property-decorator의 github에서 볼 수 있습니다.
Vuex Class Example
Vue의 Store를 구성할 수 있는 Vuex도 Decorator를 이용하여 Class 형태로 만들 수 있습니다. vuex-module-decorators를 이용하여 구성할 수 있지만 vue-property-decorator와 마찬가지로 Vue에서 정식으로 제공하는 라이브러리는 아닙니다.
vuex-module-decorators example
Vuex를 구성하는 방법은 기존과 동일합니다.
// store/index.ts import Vue from 'vue'; import Vuex from 'vuex'; import ApptModule, { AppState } from './modules/app'; Vue.use(Vuex); export interface RootState { app: AppState; } export default new Vuex.Store<RootState>({ modules: { app: AppModule, }, });
기본적으로 Vuex를 구성하는 State, Mutation, Action, Getters를 Decorator를 이용하여 Class 형태로 구성합니다.
// store/modules/app.ts import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'; export interface AppState { data: string; } @Module({ namespaced: true }) class App extends VuexModule implements AppState { public data: string = 'snippet'; @Mutation private SET_DATA(data: string) { this.data = data; } @Action({ commit: 'SET_DATA', rawError: true }) public setData(data: string) { } get appData(): string { return this.data; } } export default App;
마무리
현재 Vue 3가 나왔지만 아직 Vue 2를 사용하고 있거나 레거시로 남아 있는 경우가 있습니다. Vue 2와 TypeScript를 같이 사용하기 위해 Class Component 형태로 개발을 진행한다면 vue-property-decorator와 vuex-module-decorators를 이용하여 좀 더 수월하게 개발할 수 있겠습니다.
참고 자료
https://class-component.vuejs.org/
'Frameworks, Platforms and Libraries > Vue.js' 카테고리의 다른 글
Vue application with React component (0) 2023.10.08