ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Vue Class Component with Decorator
    Frameworks, 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/

    https://github.com/kaorun343/vue-property-decorator

    https://github.com/championswimmer/vuex-module-decorators

    'Frameworks, Platforms and Libraries > Vue.js' 카테고리의 다른 글

    Vue application with React component  (0) 2023.10.08
Designed by Tistory.