Vue.js 3 ref vs reactive

|

ref vs reactive

refreactive의 사용법 예제입니다.

Vue에서 변수들의 값이 변경되었을 때 화면이 자동으로 갱신되지 않습니다. 데이터 변경에 반응형으로 자동 갱신을 하기 위해서는 ref 또는 reactive를 사용해야 합니다.

ref 값을 변경할 때는 변수명.value 값을 변경하면 되며, reactive는 일반 구조체처럼 값을 변경하면 됩니다.

<template>
  <h1>ref vs reactive</h1>
  <div>
    <h2>ref: </h2>
    <h2>reactive: , </h2>
  </div>
  <button @click="update">Update</button>
</template>

<script>
import { reactive, ref } from "@vue/reactivity";
export default {
  setup() {
    const refData = ref("snowdeer");
    const reactiveData = reactive({
      name: "snowdeer",
      address: "Seoul",
    });

    const update = () => {
      refData.value = "snowdeer-ref";
      reactiveData.name = "snowdeer-reactive";
    };

    return {
      refData,
      reactiveData,
      update,
    };
  },
};
</script>

<style>
</style>

ref, reactive 차이

  • ref변수명.value로 값을 변경하며, reactive는 데이터 구조체처럼 값을 변경하면 됩니다.
  • reactiveprimitive 값에 대해서는 반응형을 갖지 않습니다. 다만 구조체 형태로 선언하면 반응형으로 동작합니다.

Vue.js 3 Hello World

|

Hello World

Vue.js 3에서 도입된 Composition API를 이용해서 Hello World를 출력하는 예제입니다.

<template>
  <h1>, </h1>
</template>

<script>
export default {
  setup() {
    const name = "snowdeer";

    const greeting = () => {
      return "Hello";
    };

    return {
      name,
      greeting,
    };
  },
};
</script>

<style>
</style>

위의 예제에서는 name이라는 변수, greeting 이라는 메소드를 작성한 예제입니다. export default 내에 setup 함수 안에 변수, 메소드 등을 선언할 수 있으며, setup의 리턴 값으로 html에서 사용할 변수 또는 메소드를 반환해주면 됩니다.

Vue.js 프로젝트 디렉토리 구성

|

Vue.js 프로젝트 디렉토리 구성

프로젝트 만들기

터미널에서 vue create 명령어를 통해 Vue.js 프로젝트를 하나 생성합니다.

$ vue create snowdeer-vue-sample

Vue CLI v5.0.4
? Please pick a preset: Default ([Vue 3] babel, eslint)


Vue CLI v5.0.4
✨  Creating project in /Users/snowdeer/Workspace/vue/snowdeer-vue-sample.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...

yarn install v1.22.17
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 8.84s.
🚀  Invoking generators...
📦  Installing additional dependencies...

yarn install v1.22.17
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 23.39s.
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project snowdeer-vue-sample.
👉  Get started with the following commands:

 $ cd snowdeer-vue-sample
 $ yarn serve

프로젝트 구조

package.json

프로젝트에 필요한 패키지들은 package.json에 설치됩니다. 대략적인 내용은 다음과 같습니다.

{
  "name": "snowdeer-vue-sample",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3"
  },

  ...

위 프로젝트에서 필요한 패키지들은 dependenciesdevDependencies를 보면 되며 yarn add 또는 npm install 등의 명령어로 필요 패키지들이 하나씩 추가됩니다.

public/index.html

해당 프로젝트를 실행하면 public/index.html이 실행되며, 특별히 건드릴 부분은 거의 없습니다.

<body> 태그 내의 <div id="app">에 Vue.js가 렌더링해서 보여줍니다.

<body>
    ...
    <div id="app"></div>
    <!-- built files will be auto injected -->
    ...
</body>

src/main.js

가장 먼저 실행되는 파일이라고 볼 수 있습니다. createApp 함수를 통해 프로젝트 전체 인스턴스에 대한 설정이 들어갑니다.

import { createApp } from 'vue'
import App from './App.vue'

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

src/App.vue

본격적인 Vue 파일입니다. Vue 파일은 크게 다음의 3부분으로 이루어져 있습니다.

  • <template> : html 코드가 작성됨
  • <script> : vue.js 코드가 작성됨
  • <style> : css 스타일 코드가 작성됨

이와 같이 하나의 파일에 html, script, css가 모두 작성되기 때문에 Vue.js는 SFC(Single-File Components)라고 합니다.

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Vue.js Lifecycle

|

Vue.js Lifecycle

라이프사이클 순서

Vue의 라이프사이클은 아래와 같은 순서로 이루어집니다.

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmount
  • unmounted

beforeCreate

인스턴스가 생성된 후 가장 처음 실행되는 단계입니다. datamethods 속성이 아직 인스턴스에 정의되지 않았으며, DOM 요소에도 접근할 수 없습니다.

created

datamethods 속성이 정의되었습니다. 하지만 인스턴스가 화면에 마운트되지 않았기 때문에 DOM 요소에는 접근할 수 없습니다.

beforeMount

인스턴스가 DOM에 마운트되기 직전에 호출되는 단계입니다. render() 함수가 호출되기 직전의 로직을 넣기 적합합니다.

mounted

DOM에 인스턴스가 마운트되고나서 호출되는 함수입니다.

App.vue 예제 코드

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
</template>

<script>
export default {
  name: "App",
  components: {},
  beforeCreate() {
    console.log("[snowdeer] beforeCreate()");
  },
  created() {
    console.log("[snowdeer] created()");
  },
  beforeMount() {
    console.log("[snowdeer] beforeMount()");
  },
  mounted() {
    console.log("[snowdeer] mounted()");
  },
  beforeUpdate() {
    console.log("[snowdeer] beforeUpdate()");
  },
  updated() {
    console.log("[snowdeer] updated()");
  },
  beforeUnmount() {
    console.log("[snowdeer] beforeUnmount()");
  },
  unmounted() {
    console.log("[snowdeer] unmounted()");
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

예제 코드를 실행하면 모든 로그가 출력되는 것이 아니라 beforeCreate, created, beforeMount, mounted 까지만 출력됩니다. 그 이유는 updated는 데이터 변경이 발생했을 때 화면 갱신을 위해 호출되는 로직이기 때문입니다.

따라서 아래와 같이 코드를 조금 수정해서 데이터를 변경하면 updated 까지 로그가 출력되는 것을 확인할 수 있습니다.

수정된 App.vue 예제 코드

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <h1></h1>
</template>

<script>
export default {
  name: "App",
  components: {},
  data() {
    return {
      message: `hello, snowdeer`,
    };
  },
  beforeCreate() {
    console.log("[snowdeer] beforeCreate()");
  },
  created() {
    console.log("[snowdeer] created()");
  },
  beforeMount() {
    console.log("[snowdeer] beforeMount()");
  },
  mounted() {
    console.log("[snowdeer] mounted()");
    this.message = `hello, snowdeer +_+`;
  },
  beforeUpdate() {
    console.log("[snowdeer] beforeUpdate()");
  },
  updated() {
    console.log("[snowdeer] updated()");
  },
  beforeUnmount() {
    console.log("[snowdeer] beforeUnmount()");
  },
  unmounted() {
    console.log("[snowdeer] unmounted()");
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Vue.js 설치 방법(MacOS)

|

Vue.js 설치 방법

Node.js 설치

$ brew install node

$ node -v
v17.7.1

$ npm -v
8.5.2

Yarn 설치

위에서 Node.js를 이미 설치했기 때문에 --ignore-dependencies 옵션을 주고 설치합니다.

$ brew install yarn --ignore-dependencies

$ yarn -v
1.22.17

Vue-Cli 설치

npm install @vue/cli -g

또는 

yarn global add @vue/cli

샘플 프로젝트 생성해보기

$ vue create snow-vue-sample

?  Your connection to the default yarn registry seems to be slow.
   Use https://registry.npmmirror.com for faster installation? Yes


Vue CLI v5.0.3
? Please pick a preset: Default ([Vue 3] babel, eslint)
? Pick the package manager to use when installing dependencies: Yarn


Vue CLI v5.0.3
✨  Creating project in /Users/snowdeer/Workspace/snow-vue-sample.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...

yarn install v1.22.17
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...

success Saved lockfile.
✨  Done in 45.85s.
🚀  Invoking generators...
📦  Installing additional dependencies...

yarn install v1.22.17
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

success Saved lockfile.
✨  Done in 9.32s.
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project snow-vue-sample.
👉  Get started with the following commands:

 $ cd snow-vue-sample
 $ yarn serve

Chrome의 Vue.js devtools 설치

Chrome 웹스토어에서 Vue.js devtools 플러그인을 설치합니다.