DEV Community

Gunwoo
Gunwoo

Posted on

๐Ÿค” VUE.JS?

๐Ÿ“ ๊ถ๊ธˆํ•œ ๋ชจ๋“  ๊ฒƒ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
๐Ÿ˜Ž ๊ธฐ๋ก์—์„œ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ๋‚˜์˜ ๊ฒƒ์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
๐Ÿ™ˆ ์ž˜๋ชป๋œ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๋Œ“๊ธ€์— ๋‚จ๊ฒจ์ฃผ์„ธ์š” :D

์ €๋Š” ์–ธ์ œ๋‚˜ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด์ฉŒ๋‹ค Vue๋ฅผ ๊ณต๋ถ€ํ•  ๊ธฐํšŒ๊ฐ€ ์žˆ์–ด์„œ ๊ณต๋ถ€ํ•œ ๊ธฐ๋ก์„ ๋‚จ๊น๋‹ˆ๋‹ค.

๐Ÿค” VUE.JS?

๊ณต์‹๋ฌธ์„œ์—์„œ ๋ทฐ๋Š” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI)๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋ ˆ์‹œ๋ธŒ ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๊ณ  ์†Œ๊ฐœํ•˜๊ณ  ์žˆ๋‹ค.

๐Ÿง ํŠน์ง•

1. ์œ ์—ฐํ•˜๊ณ  ๊ฐ€๋ณ๋‹ค.

2. ๊ธฐ์กด์˜ ์›น์•ฑ์˜ ์ผ๋ถ€ UI๋งŒ ์ ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

3. SPA๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ผ์šฐํ„ฐ๊ธฐ๋Šฅ๋„ ์ง€์›ํ•œ๋‹ค.

4. ๋ฆฌ์•กํŠธ์ฒ˜๋Ÿผ ๊ฐ€์ƒDOM์„ ์ง€์›ํ•ด์„œ ๋น ๋ฅธ UI ๋ Œ๋”๋ง์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

5. ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜์˜ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

6. ์•ต๊ทค๋Ÿฌ์ฒ˜๋Ÿผ ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ๊ฐ’๊ณผ ๋ชจ๋ธ ๋ฐ์ดํ„ฐ ๊ฐ’์ด ๋™๊ธฐํ™”๋˜์–ด ํ•œ์ชฝ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋‹ค๋ฅธ ํ•œ์ชฝ ๋˜ํ•œ ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค.

7. ๋ฆฌ์•กํŠธ์ฒ˜ํ—˜ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ๋ผ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ํ•ญ์ƒ ์ƒ์œ„์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„์ปดํฌ๋„ŒํŠธ ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ „๋‹ฌ๋œ๋‹ค.

8. MVVM ํŒจํ„ด์ด๋‹ค.


Model - View - ViewModel ๊ตฌ์กฐ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ํ™”๋ฉด์˜ ์š”์†Œ๋ฅผ ์ œ์–ดํ•˜๋Š” ์ฝ”๋“œ์™€ ๋ฐ์ดํ„ฐ ๋กœ์ง์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ์ดํ•ด๋„๋ฅผ ๋†’์ด๊ณ  ์œ ์ง€ ๋ณด์ˆ˜๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
View๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋Š” ํ™”๋ฉด์ด๋‹ค.
ViewModel์€ View์™€ Model์˜ ์ค‘๊ฐ„ ์˜์—ญ์ด๊ณ , DOM ๋ฆฌ์Šค๋„ˆ ์™€ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ์„ ์ œ๊ณตํ•˜๋Š” ๊ณณ์ด๋‹ค.
Model์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ์œ„์น˜๋กœ, ๋ณดํ†ต ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ JS ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ €์žฅํ•œ๋‹ค.
DOM Listener๋Š” DOM์˜ ๋ณ€๊ฒฝ ์ƒํ™ฉ์— ์ฆ‰๊ฐ ๋ฐ˜์‘ํ•ด์„œ ํŠน์ • ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์žฅ์น˜์ด๋‹ค.
Data Binding์€ View์˜ ๋‚ด์šฉ๊ณผ Model์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋™๊ธฐํ™”ํ•ด์ฃผ๋Š” ์žฅ์น˜์ด๋‹ค.

๐Ÿ”ง ์„ค์น˜๋ฐฉ๋ฒ•

ํŽ˜์ด์ง€์— CDN package๋กœ importํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ, npm์„ ์ด์šฉํ•ด ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

// vue ์„ค์น˜ํ•˜๊ธฐ
$ npm install vue@next

// vue cli ์„ค์น˜ํ•˜๊ธฐ
yarn global add @vue/cli
// ์•„๋‹ˆ๋ฉด
npm install -g @vue/cli
Enter fullscreen mode Exit fullscreen mode
// vue cli๋ฅผ ํ†ตํ•œ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐฉ๋ฒ•
vue create my-project
// ํ˜น์€ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ui๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค. 
vue ui
Enter fullscreen mode Exit fullscreen mode

Vue ํŒŒ์ผ ๊ตฌ์กฐ

Vue์˜ ๊ตฌ์กฐ์™€ ๊ฐ ๊ฐœ๋…์„ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

// Home.vue
<template>
<!-- Vue ํŒŒ์ผ์€ ์ปดํฌ๋„ŒํŠธ ํ…œํ”Œ๋ฆฟ์„ ์ •์˜ํ•˜๋Š” template ํŒŒํŠธ, ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” script ํŒŒํŠธ, ๊ทธ๋ฆฌ๊ณ  ์Šคํƒ€์ผ๋ง ์ •๋ณด๋ฅผ ์ž‘์„ฑํ•˜๋Š” style ํŒŒํŠธ๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ๋‹ค. -->
  <div>
      <!-- ์ค‘๊ด„ํ˜ธ๋ฅผ ๋‘๋ฒˆ ์‚ฌ์šฉํ•ด์„œ JS ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค. Mustache bracket-->
    <h1>Welcome to {{title2}}!</h1>
    <!-- v-model ๋ฅผ ์‚ฌ์šฉํ•ด์„œ input ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด๊ธฐ์— data()์— ์ •์˜๋œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.  -->
    <input type="text" v-model="input1" />
    <!-- @click ์„ ์ด์šฉํ•ด์„œ ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ํ—จ๋“ค๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค. -->
    <!-- v-on์˜ ์•ฝ์–ด => v-on:click์„ @click์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. -->
    <button type="button" @click="getData">Get</button>
    <button type="button" @click="setData">Set</button>
    <!-- @change ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ’์˜ ๋ณ€ํ™”๋ฅผ ํ™•์ธํ•˜๊ณ  ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. -->
    <select class="form-control" v-model="region" @change="changeRegion">
        <!-- v-for ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ ํ˜•์‹์ด ๋ฐฐ์—ด๋กœ ์ฃผ์–ด์กŒ์„ ๋•Œ -->
        <!-- :key๋Š” v-bind:key์˜ ์•ฝ์–ด์ด๋‹ค -->
      <option :key="i" :value="d.v" v-for="(d,i) in options">{{d.t}}</option>
    </select>
    <div>
        <!-- v-if ๋ฅผ ์ด์šฉํ•ด ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์œผ ํ•  ์ˆ˜ ์žˆ๋‹ค. -->
        <h3 v-if="awesome"> Vue is awesome! </h3>
        <h1 v-else>Oh no ๐Ÿ˜ข</h1>
    </div>
    <!-- v-show ๋ฅผ ์ด์šฉํ•ด display css ์†์„ฑ์„ none ์ฒ˜๋Ÿผ ํ•  ์ˆ˜ ์žˆ๋‹ค. <์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ Œ๋”๋ง์ด ๋œ๋‹ค.> -->
    <table class="table table-bordered" v-show="tableShow">
      <tr :key="index" v-for="(data,index) in options">
        <td>{{data.v}}</td>
        <td>{{data.t}}</td>
      </tr>
    </table>
  </div>
</template>
<script>
export default {
    // data ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๋‹ค๋ฃจ๊ณ  ์‹ถ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๊ณ , ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. 
    // ์ด๊ณณ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๊ณ , template์— mustache bracket์„ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•  ์ˆ˜ ์žˆ๋‹ค. 
    // ๋˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด(ex. input, select, etc), v-model๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์•„๋ž˜์˜ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค. 
    // ์œ„์ฒ˜๋Ÿผ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค. 
  data() {
    return {
      title: "๋ทฐ ์—ฐ์Šต",
      title2: "Seoul",
      input1: "abcd",
      options: [
        { v: "S", t: "Seoul" },
        { v: "J", t: "Jeju" },
        { v: "B", t: "Busan" },
      ],
      region: "B",
      tableShow: false,
      awesome: false,
    };
  },
  // ๋งŒ์ผ ๋ฐ์ดํ„ฐ์— ์กฐ๊ธˆ์ด๋ผ๋„ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋ฉด ์™“์น˜ ์•ˆ์— ์ •์˜๋œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์ž‘์šฉ๋œ๋‹ค. 
  // ์™“์น˜๋Š” ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์•Œ์•„์„œ ์บ์น˜ํ•ด์ค€๋‹ค. (๋ชจ๋‹ˆํ„ฐ๋ง ๊ธฐ๋Šฅ) ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ํ•ญ์ƒ ์ฃผ์‹œํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€, ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋ฉด ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์น˜ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  // ์ฃผ๋กœ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ์˜ ์ด๋ฒคํŠธ๊ฐ€ ์•„๋‹Œ ํ”„๋กœ๊ทธ๋žจ ์ƒ์—์„œ ์–ด๋– ํ•œ ํŠน์ • ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.  
  watch: {
      // ์™“์น˜์—์„  ๋ฐ์ดํ„ฐ ๋ช…์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ง€๊ณ ์™€์„œ ํ•จ์ˆ˜ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค. 
    input1() {
      console.log(this.input1);
    },
    title() {},
  },
  // Vue์—์„œ๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ์ด๊ณณ์— ์ •์˜๋ฅผ ํ•œ๋‹ค. 
  // ๋ฐ์ดํ„ฐ ์ปจํŠธ๋กค์— ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ฒƒ์„ ์ด๊ณณ์—์„œ ์ •์˜ํ•œ๋‹ค. 
  methods: {
    getData() {
      alert(this.input1);
    },
    setData() {
      this.input1 = "12345";
    },
    changeRegion() {
      alert(this.region);
    },
  },
  // Vue ์ธ์Šคํ„ด์Šค์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด
  // ๋งŒ์ผ ์ฒ˜์Œ ํ™”๋ฉด ๋ Œ๋”๋ง์ด ๋˜๊ธฐ ์ „์— DB์™€ ๊ฐ™์€ ๊ณณ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฟŒ๋ ค์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด ์ด๊ณณ์—์„œ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค. 
  beforeCreate() {
    console.log("beforeCreate");
  },
  created() {
    console.log("created");
  },
  beforeMount() {
    console.log("beforeMount");
  },
  // ํ™”๋ฉด์— ์‹ค์ œ๋กœ html์ด ๋กœ๋”ฉ์ด ๋˜์—ˆ์„ ๋•Œ
  mounted() {
    console.log("mounted");
  },
  // ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „์— ๋ฌด์–ธ๊ฐ€๋ฅผ, ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ด๊ณณ์— ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค. 
  beforeUpdate() {
    console.log("beforeUpdate");
  },
  updated() {
    console.log("updated");
  },
  beforeDestroy() {
    console.log("beforeDestroy");
  },
  destroyed() {
    console.log("beforeDestroy");
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“Œ Vue ๊ฐœ๋ฐœ์— ๋„์›€๋˜๋Š” ํˆด & ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • Vue Devtools

    Vue ์•ฑ์„ ๋ณด๋‹ค ์‚ฌ์šฉ์ž ์นœํ™”์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ๊ฒ€์‚ฌํ•˜๊ณ  ๋””๋ฒ„๊น…ํ•  ์ˆ˜์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค.

  • Vue-cli

    ๋น ๋ฅด๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋„๋ก ๋„์™€์ค€๋‹ค.

  • Vue Router

    ๋ทฐ๋ฅผ ์ด์šฉํ•˜์—ฌ SPA์„ ์ œ์ž‘ํ•  ๋•Œ ์œ ์šฉํ•œ ๋ผ์šฐํŒ… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. npm์œผ๋กœ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ CDN ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘€ References

Top comments (2)

Collapse
 
jream profile image
Jesse

I kind of prefer svelte over vue

Collapse
 
gunwooko profile image
Gunwoo

Oh! I am interested in svelte as well! :D