Vue2 vs Vue3 차이점

웹/Vue.js 2024. 1. 14. 21:20

Vue2와 Vue3의 간단한 차이점 비교.

 

* 공식문서

https://ko.vuejs.org/guide/introduction.html

 

 

1. 성능 개선:

  • Vue.js 3는 가상 돔(Virtual DOM) 업데이트 알고리즘을 개선하여 성능을 향상시켰습니다. 렌더링 성능이 개선되어 더 효율적인 업데이트를 가능케 합니다.

2. Composition API:

  • Vue.js 3에서는 Composition API가 도입되었습니다. 이는 코드를 더 모듈화하고 재사용 가능한 로직을 쉽게 추상화할 수 있도록 하는 새로운 방식의 API입니다.
  • Vue.js 2에서는 Options API가 주로 사용되었지만, Composition API는 더 유연하고 강력한 코드 구조를 제공합니다.
Vue.js2 Options API 
<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue.js 2!',
    };
  },
  methods: {
    changeMessage() {
      this.message = 'Message changed!';
    },
  },
};
</script>

 - data 속성과 methods 옵션을 사용하여 상태와 메서드를 정의하고, 템플릿에서 해당 데이터와 메서드를 사용합니다.

Vue.js 3 Cpmposition API 
<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

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

export default {
  setup() {
    const message = ref('Hello, Vue.js 3!');

    function changeMessage() {
      message.value = 'Message changed!';
    }

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

 - setup 함수를 사용하여 상태와 메서드를 정의합니다.

 - ref 함수를 사용하여 반응적인 데이터를 만들고, setup 함수에서 해당 데이터와 메서드를 반환합니다.

 - 이를 사용하여 템플릿에서 데이터와 메서드를 사용합니다.

 

3. 퍼포먼스 최적화:

  • Vue.js 3는 더 작은 번들 크기와 빠른 초기 로딩을 위해 모듈화된 설계와 Tree-shaking을 통한 최적화가 이루어졌습니다.
<!-- main.js -->
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');

 

 

4. 타입스크립트 지원:

  • Vue.js 3는 타입스크립트를 공식적으로 지원합니다. 이는 개발자에게 코드를 더 안정적이고 유지보수하기 쉽게 만들어주는 장점을 제공합니다.
// App.vue
<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      message: 'Hello, Vue.js 3 with TypeScript!',
    };
  },
});
</script>

 

5. Fragment:

  • Vue.js 3에서는 더 이상 불필요한 DOM 래퍼 요소가 필요하지 않고 여러 노드를 그룹화하기 위한 Fragment 문법이 도입되었습니다.
Vue.js 3 Fragment:
<template>
  <div>
    <h1>Main App</h1>
    <FragmentExample />
  </div>
</template>

<script>
import FragmentExample from './FragmentExample.vue';

export default {
  components: {
    FragmentExample,
  },
};
</script>
// FragmentExample.vue
<template>
  <>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
  </>
</template>

 - <></>를 사용하여 Fragment를 생성하고 여러 요소를 묶어서 사용합니다.

 - 이를 통해 불필요한 래퍼 요소를 생성하지 않고 여러 요소를 그룹화합니다.

 

6.  Teleport:

  • Vue.js 3에는 Portal의 개념을 기반으로 하는 Teleport라는 새로운 컴포넌트가 추가되었습니다. 이를 사용하면 DOM 트리에서 자식을 특정 위치로 이동시킬 수 있습니다.
Vue.js 3 Teleport:
<template>
  <div>
    <h1>Main App</h1>
    <TeleportDestination />
  </div>
</template>

<script>
import TeleportDestination from './TeleportDestination.vue';

export default {
  components: {
    TeleportDestination,
  },
};
</script>
// TeleportDestination.vue
<template>
  <Teleport to="#destination">
    <h2>Teleported Heading</h2>
  </Teleport>
</template>

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

export default {
  components: {
    Teleport,
  },
};
</script>

 - Teleport 컴포넌트를 사용하여 자식 컴포넌트의 요소를 다른 위치로 이동시킵니다.

 

7.  데이터 반응성( Reactivity ) 개선:

  • Vue.js 3는 반응성을 개선하여 더 많은 상황에서 반응적인 데이터를 더 효과적으로 처리할 수 있게 되었습니다.
<!-- App.vue -->
<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="changeMessage">Change Message</button>
  </div>
</template>

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

export default {
  setup() {
    const state = reactive({
      message: 'Hello, Vue.js 3!',
    });

    function changeMessage() {
      state.message = 'Message changed!';
    }

    return {
      message: state.message,
      changeMessage,
    };
  },
};
</script>

 

 - reactive 함수를 사용하여 상태를 만들고, setup 함수에서 해당 상태를 반환합니다.

 - 함수형 API를 사용하여 상태를 조작하고 템플릿에서 사용할 수 있습니다.

[CodingApple] Vue 로 만드는 웹앱 3

웹/Vue.js 2024. 1. 12. 23:08

Coding Apple 강의 4일차.

심심해서 만들어보는 Vue JS 강의 수강 1

 

Vue로 간단한 웹앱 만들어보기.

  1. 준비물

     > nodejs 설치

     > vs code 설치

     > vetur 설치 (vscode 확장 프로그램, vue 2 버전)

     > voloar 설치 (vscode 확장 프로그램, vue 3 버전)

     > HTML Css Surpport (vscode 확장 프로그램)

     > vue 3 snippets (vscode 확장 프로그램)

     > vue.js 설치

 

   2. App.vue (데이터 export, import를 통해 상품 리스트 구현)

<template>
  <!-- 
    * 동적인 UI 만드는법
    1. UI의 현재 상테를 데이터로 저장해둠
    2. 데이터에 따라 UI가 어떻게 보일지 작성
    v-if: 해당 HTML 을 보여줄지말지 결정
   -->
  <div class="black-bg" v-if="모달창열렸니">
    <div class="white-bg">
      <h4>상세페이지임</h4>
      <p>상세페이지 내용임</p>
      <button @click="모달창열렸니 = false">닫기</button>
    </div>
  </div>
  <div class="menu">
    <!-- Vue의 HTML 반복문 => <태그 v-for="변수명 in (몇회 혹은 Object)" :key="유니크값(보통 인덱스 사용)">-->
    <a v-for="(변수명, i) in 메뉴들" :key="i">{{ 변수명 }}</a>
  </div>
  <div v-for="(원룸, i) in 원룸들" :key="i">
    <img :src="원룸.image" class="room-img" />
    <h4>{{ 원룸.title }}</h4>
    <p>{{ 원룸.content }}</p>
    <p>{{ 원룸.price }}</p>
  </div>
</template>

<script>
//oneroom.js에서 export한 데이터 가져오기 export 하는 방법에 따라 {}로 감싸거나 단일 변수를 사용하면 된다
import 원룸데이터 from "./assets/oneroom.js"; //export default 로 했을 때 가져오는 방법
// import { a, b, ... } from "./assets/oneroom.js";  //export {a, b, ... }로 했을 때 가져오는 방법

export default {
  name: "App",
  data() {
    //데이터 보관함
    return {
      원룸들: 원룸데이터,
      모달창열렸니: false,
      신고수: [0, 0, 0],
      //변수 선언 영역 (Object 자료형으로 저장해야함)
      메뉴들: ["Home", "Shop", "About"],
      스타일: "color: blue",
      products: ["역삼동원룸", "천호동원룸", "마포구원룸"],
      prices: ["50만원", "70만원", "80만원"],
      이미지경로: ["assets/room0.jpg", "assets/room1.jpg", "assets/room2.jpg"],
      이미지파일명: ["room0.jpg", "room1.jpg", "room2.jpg"],
    };
  },
  //Vue 에서 함수를 만들고 싶으면 methods:{} 안에 선언하면 됨
  methods: {
    increase(i) {
      this.신고수[i] += 1;
    },
  },
  components: {},
};
</script>

<style>
body {
  margin: 0;
}
div {
  box-sizing: border-box;
}
.black-bg {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  position: fixed;
  padding: 20px;
}
.white-bg {
  width: 100%;
  background: white;
  border-radius: 8px;
  padding: 20px;
}

.room-img {
  width: 100%;
  margin-top: 40px;
}

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.menu {
  background: darkslateblue;
  padding: 15px;
  border-radius: 5px;
}

.menu a {
  color: white;
  padding: 10px;
}
</style>

 

    3. oneroom.js (외부 데이터)

const data = [
  {
    id: 0,
    title: "Sinrim station 30 meters away",
    image: "https://codingapple1.github.io/vue/room0.jpg",
    content: "18년 신축공사한 남향 원룸 ☀️, 공기청정기 제공",
    price: 340000,
  },
  {
    id: 1,
    title: "Changdong Aurora Bedroom(Queen-size)",
    image: "https://codingapple1.github.io/vue/room1.jpg",
    content: "침실만 따로 있는 공용 셰어하우스입니다. 최대 2인 가능",
    price: 450000,
  },
  {
    id: 2,
    title: "Geumsan Apartment Flat",
    image: "https://codingapple1.github.io/vue/room2.jpg",
    content: "금산오거리 역세권 아파트입니다. 애완동물 불가능 ?",
    price: 780000,
  },
  {
    id: 3,
    title: "Double styled beds Studio Apt",
    image: "https://codingapple1.github.io/vue/room3.jpg",
    content: "무암동인근 2인용 원룸입니다. 전세 전환가능",
    price: 550000,
  },
  {
    id: 4,
    title: "MyeongIl Apartment flat",
    image: "https://codingapple1.github.io/vue/room4.jpg",
    content: "탄천동 아파트 월세, 남향, 역 5분거리, 허위매물아님",
    price: 680000,
  },
  {
    id: 5,
    title: "Banziha One Room",
    image: "https://codingapple1.github.io/vue/room5.jpg",
    content: "반지하 원룸입니다. 비올 때 물가끔 새는거 빼면 좋아요",
    price: 370000,
  },
];

// var apple = 10;

export default data; //data 변수 export
// export { data, apple }; //2개 이상의 변수 혹은 함수 export

 

 

[CodingApple] Vue 로 만드는 웹앱 2

웹/Vue.js 2024. 1. 11. 22:56

Coding Apple 강의 3일차.

심심해서 만들어보는 Vue JS 강의 수강 1

 

Vue로 간단한 웹앱 만들어보기.

  1. 준비물

     > nodejs 설치

     > vs code 설치

     > vetur 설치 (vscode 확장 프로그램, vue 2 버전)

     > voloar 설치 (vscode 확장 프로그램, vue 3 버전)

     > HTML Css Surpport (vscode 확장 프로그램)

     > vue 3 snippets (vscode 확장 프로그램)

     > vue.js 설치

 

   2. App.vue (허위매물신고 버튼, img 추가, 제목 클릭 시 modal 열고 닫기 추가)

<template>
  <!-- 
    * 동적인 UI 만드는법
    1. UI의 현재 상테를 데이터로 저장해둠
    2. 데이터에 따라 UI가 어떻게 보일지 작성
    v-if: 해당 HTML 을 보여줄지말지 결정
   -->
  <div class="black-bg" v-if="모달창열렸니">
    <div class="white-bg">
      <h4>상세페이지임</h4>
      <p>상세페이지 내용임</p>
      <button @click="모달창열렸니 = false">닫기</button>
    </div>
  </div>
  <img alt="Vue logo" src="./assets/logo.png" />
  <div class="menu">
    <!-- Vue의 HTML 반복문 => <태그 v-for="변수명 in (몇회 혹은 Object)" :key="유니크값(보통 인덱스 사용)">-->
    <a v-for="(변수명, i) in 메뉴들" :key="i">{{ 변수명 }}</a>
    <!-- <a>Home</a>
    <a>Products</a>
    <a>About</a> -->
  </div>
  <div v-for="(제품명, i) in products" :key="i">
    <!-- 
      * vue에서 html 속성 데이터 바인딩 방법 => :속성="데이터이름"
      * img src의 경우 webpack 으로 배포됨에 따라 실제 서버에 배포되는 절대경로가 다르다. (/image 로 시작됨) 
        그렇기 때문에 단순히 workspace내 상대경로로 지정하는 것이 아닌 require()를 사용해야한다. 
      -->
    <img
      :src="require(`@/${이미지경로[i]}`)"
      :alt="`room${i}`"
      class="room-img"
    />
    <!-- 파일명으로 세팅하는 법 <img :src="require(`@/assets/${이미지파일명[i]}`)" :alt="`room${i}`" class="room-img"/> -->
    <h4 @click="모달창열렸니 = true" class="red" :style="스타일">
      {{ 제품명 }}
    </h4>
    <p>{{ prices[i] }}</p>
    <!-- onclick vue 문법 => v-on:click 혹은 @click -->
    <button @click="increase(i)">허위매물신고</button>
    <span>신고수 : {{ 신고수[i] }}</span>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    //데이터 보관함
    return {
      모달창열렸니: false,
      신고수: [0, 0, 0],
      //변수 선언 영역 (Object 자료형으로 저장해야함)
      메뉴들: ["Home", "Shop", "About"],
      스타일: "color: blue",
      products: ["역삼동원룸", "천호동원룸", "마포구원룸"],
      prices: ["50만원", "70만원", "80만원"],
      이미지경로: ["assets/room0.jpg", "assets/room1.jpg", "assets/room2.jpg"],
      이미지파일명: ["room0.jpg", "room1.jpg", "room2.jpg"],
    };
  },
  //Vue 에서 함수를 만들고 싶으면 methods:{} 안에 선언하면 됨
  methods: {
    increase(i) {
      this.신고수[i] += 1;
    },
  },
  components: {},
};
</script>

<style>
body {
  margin: 0;
}
div {
  box-sizing: border-box;
}
.black-bg {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  position: fixed;
  padding: 20px;
}
.white-bg {
  width: 100%;
  background: white;
  border-radius: 8px;
  padding: 20px;
}

.room-img {
  width: 100%;
  margin-top: 40px;
}

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.menu {
  background: darkslateblue;
  padding: 15px;
  border-radius: 5px;
}

.menu a {
  color: white;
  padding: 10px;
}
</style>