๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ปWEB FrontEnd/ํ”„๋ ˆ์ž„์›Œํฌ Vue

Vue Componets ํ†ต์‹ 

<Do it! Vue.js ์ž…๋ฌธ>์„ ๊ธฐ๋ณธ์œผ๋กœ ๋ฐฐ์šด ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

๋ชฉ์ฐจ

  • 1. ์ƒ·ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ 
  • 2. ๊ฐ™์€ ๋ ˆ๋ฒจ์˜ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ 
  • 3. ๊ด€๊ณ„ ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹  

 

<Vue Componets ํ†ต์‹ >

ํ•œ ํ™”๋ฉด์— ์žˆ๋”๋ผ๋„ ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ์œ ํšจ๋ฒ”์œ„๋Š” ๋…๋ฆฝ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ’์„ ์ง์ ‘์ ์œผ๋กœ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค.

 

1. ์ƒ·ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ 

์ง€์—ญ ๋˜๋Š” ์ „์—ญ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๋“ฑ๋ก๋œ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋˜๊ณ , ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋“ฑ๋กํ•œ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋œ๋‹ค.

 

1) ์ƒ์œ„์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ(Pass Props)

ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ์†์„ฑ์— props์†์„ฑ์„ ์ •์˜ํ•˜๊ณ ,

Vue.component('child-component', {
    props: ['props์†์„ฑ์ด๋ฆ„']
});

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ HTML์ฝ”๋“œ์— ๋“ฑ๋ก๋œ child-component์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ์— v-bind์†์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

<child-component v-bind:props ์†์„ฑ์ด๋ฆ„ = "์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ data ์†์„ฑ"></child-component>

ex) ์•„๋ž˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ์ธ์Šคํ„ด์Šค(root ์ปดํฌ๋„ŒํŠธ)์— ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๊ธฐ์กด์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒ์œ„(๋ถ€๋ชจ)์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋˜๊ณ , ์ƒˆ๋กœ ๋“ฑ๋ก๋œ ์ปดํฌ๋„ŒํŠธ๋Š” ํ•˜์œ„(์ž์‹)์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋œ๋‹ค.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue Props Sample</title>
  </head>
  <body>
    <div id="app">
      <!-- ํŒ : ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์œผ๋กœ ์†์„ฑ์„ ์ฝ์œผ๋ฉด ๋” ์ˆ˜์›”ํ•ฉ๋‹ˆ๋‹ค. -->
      <child-component v-bind:propsdata="message"></child-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      Vue.component('child-component', {
        props: ['propsdata'],
        template: '<p>{{ propsdata }}</p>',
      });

      new Vue({
        el: '#app',
        data: {
          message: 'Hello Vue! passed from Parent Component'
        }
      });
    </script>
  </body>
</html>

 

2) ํ•˜์œ„์—์„œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋ฒคํŠธ ์ „๋‹ฌ(Emit Events)

ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด

this.$emit('์ด๋ฒคํŠธ๋ช…');  //์ด๋ฒคํŠธ ๋ฐœ์ƒ

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜์—ฌ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

<child-component v-on:์ด๋ฒคํŠธ๋ช…="์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฉ”์„œ๋“œ๋ช…"></child-component>  //์ด๋ฒคํŠธ ์ˆ˜์‹ 

ex)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue Event Emit Sample</title>
  </head>
  <body>
    <div id="app">
      <child-component v-on:show-log="printText"></child-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      Vue.component('child-component', {
        template: '<button v-on:click="showLog">show</button>',
        methods: {
          showLog: function() {
            this.$emit('show-log');
          }
        }
      });

      new Vue({
        el: '#app',
        data: {
          message: 'Hello Vue! passed from Parent Component'
        },
        methods: {
          printText: function() {
            console.log("received an event");
          }
        }
      });
    </script>
  </body>
</html>


2. ๊ฐ™์€ ๋ ˆ๋ฒจ์˜ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ 

  • ๋ทฐ๋Š” ์ƒ์œ„์—์„œ ํ•˜์œ„๋กœ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ ํ†ต์‹ ๊ทœ์น™์„ ๋”ฐ๋ฅธ๋‹ค.
  • ๋ฐ”๋กœ ์˜† ์ปดํฌ๋„ŒํŠธ์— ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ ค๋ฉด ํ•˜์œ„์—์„œ ๊ณตํ†ต ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•œ ํ›„ ๊ณตํ†ต ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ 2๊ฐœ์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— props์„ ๋‚ด๋ ค์•ผํ•œ๋‹ค.

 


3. ๊ด€๊ณ„ ์—†๋Š” ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ (์ด๋ฒคํŠธ ๋ฒ„์Šค)

1) ์ด๋ฒคํŠธ ๋ฒ„์Šค

  • ์ค‘๊ฐ„ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ B์—์„œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ A๋กœ ๋ฐ”๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๋ฐฉ์‹
  • ์ด๋ฒคํŠธ ๋ฒ„์Šค๋ฅผ ํ™œ์šฉํ•˜๋ฉด props์†์„ฑ์„ ์ด์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ์ง์ ‘์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์–ด ํŽธ๋ฆฌํ•˜์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์–ด๋””์„œ ์–ด๋””๋กœ ๋ณด๋ƒˆ๋Š”์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋ฅผ Vuex๋ผ๋Š” ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. 

 

2) ์ด๋ฒคํŠธ ๋ฒ„์Šค ํ˜•์‹

์ด๋ฒคํŠธ ๋ฒ„์Šค๋ฅผ ์œ„ํ•œ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ 1๊ฐœ ์ƒ์„ฑํ•˜๊ณ ,

var eventBus = new Vue();

์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด๊ณ  ๋ฐ›๋Š”๋‹ค.

//์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด๋Š” ์ปดํฌ๋„ŒํŠธ
methods: {
    ๋ฉ”์„œ๋“œ๋ช…: function() {
        eventBus.$emit('์ด๋ฒคํŠธ๋ช…', ๋ฐ์ดํ„ฐ);
    }
}

//์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๋Š” ์ปดํฌ๋„ŒํŠธ
methods: {
    created: function() {
        eventBus.$on('์ด๋ฒคํŠธ๋ช…', funtion(๋ฐ์ดํ„ฐ){
            ...
        });
    }
}

ex)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue Event Bus Sample</title>
  </head>
  <body>
    <div id="app">
      <child-component></child-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      var eventBus = new Vue();

      Vue.component('child-component', {
        template: '<div>ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ์˜์—ญ์ž…๋‹ˆ๋‹ค.<button v-on:click="showLog">show</button></div>',
        methods: {
          showLog: function() {
            eventBus.$emit('triggerEventBus', 100);
          }
        }
      });

      var app = new Vue({
        el: '#app',
        created: function() {
          eventBus.$on('triggerEventBus', function(value){
            console.log("์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌ ๋ฐ›์Œ. ์ „๋‹ฌ ๋ฐ›์€ ๊ฐ’ : ", value);
          });
        }
      });
    </script>
  </body>
</html>

show๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ consoleํ™”๋ฉด์ด ๋‚˜์˜จ๋‹ค.

 

 

 

'๐Ÿ’ปWEB FrontEnd > ํ”„๋ ˆ์ž„์›Œํฌ Vue' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๋ทฐ HTTP ํ†ต์‹   (0) 2020.07.02
Vue Router  (0) 2020.07.02
Vue Componets  (0) 2020.07.02
Vue Instance  (0) 2020.07.01
Vue ์‹œ์ž‘ํ•˜๊ธฐ (+๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •)  (0) 2020.06.30