3 뷰 리서치

source: categories/study/vue-research/vue-research_3.md


npm init @vitejs/app

@vitejs/create-app is deprecated, use npm init vite instead

✔ Project name: … vue-drag-and-drop
✔ Select a framework: › vue
✔ Select a variant: › vue


npm install


cd vue-drag-and-drop
npm install


cd vue-drag-and-drop
npm run dev

3.1 Can i use … Vue 3?

3.1.1 목차

  • Vue 3의 등장
  • 실무자가 바라본 Vue 3
  • 입문자의 고민
  • 실무자의 고민
  • Vue 3 준비와 도입 시기

3.1.2 Vue 3의 등장

  • 2020년 9월 18일 ‘One Piece'라는 이름으로 Vue3 등장
  • TypeScript의 결합이 좀 더 잘 되어있고, 새로운 API 추가

3.1.3 강화된 타입스크립트 지원

  • 위와 같이 더 강화된 타입스크립트 기능을 지원합니다.
  • Vue2로 타입스크립트를 작성해보신 분이라면 Vue3를 사용하실 때 타입스크립트 지원에 있어서 훨씬 더 잘 되어있다는 느낌을 받으실 겁니다.

3.1.4 코드 재사용을 위한 Composition API



<template>
    <div>{{ message }}</div>
    <button @click="changeMessage">변경</button>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
        // data 속성
        const message = ref('곧 바뀜');

        // 메서드
        const changeMessage = () => message.value = '바꼈다';

        return {
            message,
            changeMessage,
        }
    }
})
</script>


  • Composition API는 코드 재사용을 위한 setup이라고 하는 api를 사용
  • setup API는 옵셔널함
  • 기존에 사용하던 data, methods, watch 같은 속성들을 써도되고, 그렇지않고 setup이라는 API를 사용하셔서 별도의 로직을 작성하실 수 있다.

  • ref라는 속성을 활용해서 message 변수에 reactivity 주입
  • return을 해서 template에서 바로 사용할 수 있는 형태로 만듦
  • changeMessage 같은 경우도 setup 안에서 함수로 정의하셨을 때, return하게되면 기존의 methods 속성처럼 동작하게 된다.

  • template에 최상위 태그가 한개만 되는 것이 아니라 여러개가 될 수 있는 펄규먼테이션도 적용이 되었다.
  • 기존에 개발에 있어 걸리적거리던 부분들이 많이 해소가되었다.

3.1.5 그 외 API

  • Teleport (Vue Portal)
    • Vue2에서 Vue Portal이라고 하는 Community 라이브러리가 Teleport라고 하는 이름으로 공식 라이브러리에 들어오게됨
  • Suspense
    • Suspense라고 하는 로딩 관련된 상태 제어도 들어옴
  • Multi v-model
  • 그 외 템플릿 문법들

3.1.6 그럼 이제 Vue 3를 써도될까?

실무자가 바라본 Vue 3

  • Vue 3 나왔다던데 우리 프로젝트에 넣어보죠.

현재 프로젝트에서 사용 중인 뷰 라이브러리 목록

  1. Vuetify, 스타 32.1K
  2. Vuetable, 스타 2.1K
  3. Vue-datepicker, 스타 1.3K
  4. Vue-lazyload, 스타 7.4K
  5. Vue-chart, 스타 4.5K
  • 서비스 개발에 필요한 커뮤니티 라이브러리
  • 스타 수는 다 천개가 넘는 대중성이 확보되어있는 라이브러리들
  • 2021년 9월 기준 Vue3를 지원하는 위 라이브러리는 아직 없음 (2022년 4월인 지금은 대부분 지원할듯)

Vue 3 - Proposal for dropping ie11 support in Vue 3

  • Evan You가 RFC(Request For Comment) 채널에 IE11을 Vue3에서 지원하지 않는 건 어때? 라고 제안을 함
    • Vue.js 라이브러리 발전 방향을 사용자와 논의하는 채널
    • 마이크로소프트 2022년 6월 IE 지원 끊겠다는 발표 + Vue.js에서 IE를 지원하려면 브릿지 코드가 많아지고.. 유지보수에서 좋지 않다고 판단
  • 실제 프로젝트에서 IE11을 여전히 지원해야된다고 한다면, Vue 3를 당장 사용할 수는 없을 것
  • 그러면 Vue3를 지원하지 못하니까 뭔가 도태되는게 아닌가 라고 생각할 수 있는데,
  • Focus on backport compatible feature라고 해서 기존의 Vue3의 장점이라고 앞에서 보여드렸던
  • 타입스크립트와 Composition에 대한 내용들을 모두 다 Vue 2.7에다가 강화시켜주겠다 라고 이야기를 하고 있습니다.
  • Vue2로 서비스를 운영하고 있는 분들도 Vue3의 장점들을 충분히 사용해볼 수 있는 계기가 됨

  • 링크

선택지가 없는 그들을 위한 은혜

  • 이렇게 IE11을 사용하고 있는 유저들을 배려했던 이유는
  • 아무래도 산업 분야별로 금융업계, 교육업계 그리고 공공기관에서는 IE를 필수로 지원해야 되는 실정이기 때문에
  • 그런 측면에서 아까 말씀드렸던 Composition 이라던가 TypeScript 지원을 강화하는 부분들을 모두 다 지원하겠다고 얘기를 하고있습니다.

  • 링크

한 줄 요약 - 이미 운영중인 서비스와 IE가 필요한 사이트는 Vue2로

Vue 공부

  • Vue School
  • Vue Mastery

  • 서비스 개발을 하고싶으면 일단 Vue2에 대해 공부해야돼


<!-- Vue2 문법 -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">변경</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'hi',
    }
  },
  methods: {
    changeMessage() {
      this.message = 'hi vue 2';
    }
  }
}
</script>




<!-- Vue3 문법 -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">변경</button>
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      message: 'hi',
    }
  },
  methods: {
    changeMessage() {
      this.message = 'hi vue 2';
    }
  }
})
</script>


  • Composition이 Vue3의 특징이라고 말씀드렸는데,
  • 사실 Composition은 Vue2에 원래 있었던 라이브러리이고
  • 그 사용성을 인정받아서 Vue3에서 코어 내부로 들어갔다.


<!-- Vue2 문법 -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">변경</button>
  </div>
</template>

<script>
import { ref } from '@vue/composition-api';

export default {
  setup() {
    const message = ref('hi');
    const changeMessage = () => message.value = 'hi Vue 2';

    return {
      message,
      changeMessage,
    }
  }
}
</script>




<!-- Vue3 문법 -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">변경</button>
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  setup() {
    const message = ref('hi');
    const changeMessage = () => message.value = 'hi Vue 3';

    return {
      message,
      changeMessage,
    }
  }
})
</script>


한 줄 요약 - Vue 2로 배워도 문제 없는 현재의 Vue.js 개발

실무자 고민 - Vue 3에 새로 나온 기능들 써보고 싶은데 어떡하죠?

  • 프론트엔드 개발자는 무언가를 항상 습득하고 사용해보면서 성장해야 되는데 뭔가 운영환경 때문에 Vue2에 머물러야된다면?
  • Vue2에만 멈추고싶지 않아! Vue3의 새로운 기능들을 써보고싶어!
  • Vue2에서도 충분히 Composition API와 타입스크립트를 사용해 보실 수 있습니다.

@vue/composition-api 란?

  • vue 2에서 컴포넌트의 재사용 기능 로직을 작성할 수 있도록 도와주는 라이브러리
  • 함수 기반의 API 작성 방식 기능으로 타입스크립트 추론 이점 극대화
  • 데이터, 로직 목적별로 관심사 분리 가능
    • 하나의 컴포넌트 안에서 유저, 프로덕트, 이미지 등의 데이터가 있을 때, 그런 도메인별로의 로직이 서로 엉켜있을 수가 있습니다.
    • 그러한 부분들을 훨씬 더 깔끔하게 분리할 수 있기 때문에, Composition API의 장점이 이런 부분에서 많이 드러날 것입니다.
  • 리액트 훅의 방식을 채택하여 뒤늦게 나온 만큼 몇 가지 단점을 보완
    • 분기문, 반복문, 중첩 함수 내에서 사용 가능
      • 리액트 훅 같은 경우는 분기문, 반복문, 중첩함수 내에서 훅을 사용하면 작동이되질 않습니다.
    • 컴포넌트 생성 주기에 따라 최초에 한번만 실행
      • 리액트 훅 같은 경우에는 functional 컴포넌트 안에서 state의 변화에 따라서 화면이 다시 그려질 때 훅이 다시 실행될 수 있습니다.
      • 그러한 부분들 때문에 지연된 초기화 라던가 memorization 방법을 써서 좀 더 고민을 해줘야 되는데,
      • Vue 같은 경우는 오히려 Composition API가 컴포넌트의 생성주기에 따라서 컴포넌트가 생성되었을 때 최초에 한 번만 실행된다고 보시면됩니다.
      • 이후에 화면이 다시 그려진다고해도 컴포지션 API 안의 로직들은 다시 실행되지 않는 Vue의 Reactivity 성격이 있다고 보시면 되겠습니다.

@vue/composition-api 예시



<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">변경</button>
  </div>
</template>

<script>
import { ref } from '@vue/composition-api';

export default {
  setup() {
    const message = ref('hi');
    const changeMessage = () => message.value = 'hi composition';

    return {
      message,
      changeMessage,
    }
  }
}
</script>


  • Composition API만으로 모든 코드를 작성하는 것은 추천드리지 않습니다.
  • setup이라고 하는 API 목적 자체가 코드 재사용 목적이기 때문에, 오히려 Vue의 생산성이라던가 낮은 학습장벽을 고려한다라고 하면, 이는 좀 이후에 어플리케이션이 복잡해졌을 때 사용하시면 좋을만한 API인 것 같습니다.

  • 모달은 일반적으로 애플리케이션에서 가장 많이 쓰이는 UI 요소이고, 공통적으로 쓰이는 요소이기 때문에
  • 보통 믹스인이라던가 하이오더 컴포넌트를 이용해서 재사용을 많이 하고 있을 것이다.
  • 그랬을 때 이를 컴포지션으로 어떻게 분리할 수 있는지 같이 코딩을 해보도록 하겠다.


<!-- Vue3 -->
<template>
  <div>
    <button @click="openModal">팝업</button>
    <p>modal is {{ isModalOpen ? 'open' : 'closed' }}</p>
  </div>
</template>

<script>
import { ref } from 'vue';

// composable/useModal.js - export / import 로 사용하시면 훨씬 더 여러군데에서 사용할 수 있는 공통 코드가 됩니다
const useModal = () => {
  const isModalOpen = ref(false); // isModalOpen은 ref에 의해서 reactivity가 주입된 하나의 데이터
  const openModal = () => isModalOpen.value = true;
  return {
    isModalOpen,
    openModal,
  }
}

export default {
  setup() {
    return {
      ...useModal()
    }
  },
  // data() {
  //   return {
  //     isModalOpen: false,
  //   }
  // },
  // methods: {
  //   openModal() {
  //     this.isModalOpen = true;
  //   },
  // }
}
</script>


@vue/composition-api 사용시 주의 사항

  • 기존의 믹스인(mixins)와 HOC를 이용한 코드 재활용 방식은 가급적 지양
    • 뷰 커뮤니티 자체가 컴포지션 API를 기반으로 재사용 코드를 가지고가고 있기 때문에 예전에 추천드렸던 믹스인과 HOC는 더 이상 유효하지 않다.
    • 믹스인으로 주입된 코드와 컴포지션 API가 엮였을 때 오히려 디버깅이 어려울 수 있어서 가급적 기존 코드들을 다 컴포지션 API로 재작성 하는 것을 추천드린다.
  • 타입스크립트와 같이 사용했을 때 효과 상승
    • 훅에서 정의한 파일을 컴포넌트 안에서 재선언 했을 때 덮어쓰는 실수를 피할 수 있음
    • 자바스크립트로 작성했을 때 변수를 다시 선언할 수 있기 때문에 사실 이 부분이 코드 레벨에서 발견되기 어려움
    • 다만, 타입스크립트를 썼을 때 코드 레벨에서 ESLint를 사용해서 잘못된 코드를 바로 잡을 수 있기 때문에, 실행하기 전에 먼저 코드 레벨에서 확인할 수 있어서 훨씬 더 사용성이 뛰어납니다.
  • reactive 보다는 ref 지향
    • ref가 reactive보다 api가 좀 더 간결함
    • ref 같은 경우 보통 primitive 타입으로 선언을 많이 하실 것
    • reactive를 쓰시게되면 보통 객체에 nested되는 형태로 많이 작업을 하실텐데 그렇게 하게되면 Vue.js 어플리케이션이 복잡해졌을 때, 훨씬 더 리액티비티 캐비엇(? 응? 이게 뭔말이지?)에서 어려운 부분이 있어가지고, ref 속성 사용을 추천드린다.
  • Vue3에서 제공되는 API가 모두 지원되지는 않음
    • 당연한 얘기겠지만, Vue Composition API는 Vue 2에 있었던 내용임
    • 그래서 당연히 Vue3에서 지원되는 API가 모두 지원되진 않음
    • 그래도 굳이 비교를 하자면 Vue2 컴포지션 API는 95정도 지원 / Vue 3에선 100정도 지원한다고 보면됨

VueUse 라이브러리

  • VueUse 라이브러리를 통해 얼마만큼 호환되는지 알 수 있음
  • Vue2와 Vue3 모두 사용 가능한 컴포지션 라이브러리
  • 총 148개 유틸 API 지원, 스타수 5.7K 인기 라이브러리
  • Web API, Animation, Electron, Firebase, Router 등

  • 관심있으신 분들은 Composition API 라이브러리 사용하실 때 VueUse도 살펴보시면 좋을 것 같다.

Vue 2의 타입스크립트 지원



<template>
  <p>{{ message }}</p>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  data() {
    return {
      message: '',
    }
  },
  methods: {
    changeMessage() {
      this.message = 10; // x, Type Error
    }
  }
})
</script>


  • 클래스 문법보다는 Vue.extend()를 이용한 객체 문법 지향
    • 나중에 Vue 3로 마이그레이션도 훨씬 쉽다는 장점이 있음
    • Vue.js는 개발자가 쉽게 시작할 수 있다는 장점이 있는데, 클래스 문법 같은 경우 이 장점을 퇴색시킨다.

타입스크립트 추천 사용 방법

  • TS 설정 파일에 noImplicitThis: true 옵션 추가
  • computed 속성 반환 타입은 꼭 정의
  • 스토어 및 기타 타입 정의는 d.ts 파일에 정의

기존 뷰 프로젝트에 타입스크립트 적용하기

  1. CLI 명령어로 타입스크립트 플러그인 추가 or 타입스크립트 기반 새 프로젝트 생성
    1. 보통 후자를 선호
    2. 타입스크립트를 추가한다는 의미는 기존 라이브러리들이 타입스크립트와 호환이 되어야하고 그 호환을 위해서 라이브러리 버전들을 새로 올려줘야할 필요도 있다.
    3. 그런걸 일일히 하기보단 타입스크립트 기반 새 프로젝트에서 하는게 더 수월할 것
  2. 타입스크립트 설정 파일에 allowJS, noImplicitThis 등 옵션 추가
    1. 기존 주요 로직들 자바스크립트 유지 - 다 수정하기 어려우니깐
    2. noImplicitThis 추론, 생산성 높이기위해 필요
  3. 기본적인 타입 에러만 수정하고 any와 같은 약한 타입부터 점진적으로 적용
    1. 약한 타입주터 점진적으로 강한 타입으로 정의
  4. npm run build가 가능한 수준의 타입 정의 및 수정

Tip

  • 프롭스 속성을 먼저 정의하고 컴포넌트 태그에서 자동 완성 지원 받기

한 줄 요약 - Vue 2에서도 사용할 수 있는 Vue 3의 장점들 - Composition & TypeScript

Vue 3 준비와 도입 시기

그럼 Vue 3는 언제 쓰는게 좋을까요?

  • 코어 및 커뮤니티 라이브러리 생태계가 충분히 성숙해졌을 때
  • IE 지원이 끝나는 2022년 하반기 이후
  • 사용자 층과 브라우저를 선택할 수 있는 어드민을 개발할 때

  • www.sli.dev
  • slidev 만든 사람이 컴포지션 API 만든 사람