[ Frontend ]/Vue.js & Nuxt.js

[Vue.js] 기본 문법 알아보기 / Vue 인스턴스, 컴포넌트 / Vue 디렉티브

HSRyuuu 2024. 8. 12. 11:10

Vue 인스턴스: new Vue()


new Vue()로 생성한 Vue 인스턴스는 화면에 뿌려지는 최상위(Root) 컴포넌트를 말한다. 

해당 Vue Instance에서 여러 컴포넌트를 호출에서 사용하는 것이 Vue의 기본 문법이다.

 

아래의 5가지 요소들을 가장 많이 사용한다.

<div id="app"></div>

<script>
new Vue({
          el: "#app", // Vue 인스턴스를 DOM의 어떤 부분에 연결할지 지정
          data: {
           // Vue 인스턴스에서 관리하는 데이터
          },
          methods: {
            //Vue 인스턴스에서 사용할 함수들
          },
          computed: {
            //연산된 데이터를 정의
          },
          components: {
            // 재사용 가능한 컴포넌트를 정의
          },
        });
</script>

el: '#app'

Vue 인스턴스가 관리할 DOM 요소를 지정한다. 위쪽에 id=app인 <div>에 Vue 인스턴스를 연결한다.

해당 Vue 인스턴스는 위에 id=app인 <div> 태그만을 관리한다.


data

Vue 인스턴스에서 관리할 데이터를 정의한다. 

    <div id="app">
      <h1>{{ message }}</h1>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
      new Vue({
        el: "#app",
        data: {
          message: "Hello, Vue.js!", // Vue 인스턴스에서 관리하는 데이터
        },
      });
    </script>

 

message란 이름의 데이터를 Vue 인스턴스 내에서 this.message로 사용 가능하고,
DOM 요소에서는 {{message}}로 가능하다.

methods

Vue 인스턴스 내에서 사용할 수 있는 메서드들을 정의한다. 여러 가지 방법으로 메서드를 호출할 수 있다.

    <div id="app">
      <h1>{{ message }}</h1>
      <button @click="reverseMessage">Reverse Message</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
      new Vue({
        el: "#app",
        data: {
          message: "Hello, Vue.js!",
        },
        methods: {
          reverseMessage: function () {
            this.message = this.message.split("").reverse().join("");
          },
        },
      });
    </script>
버튼을 클릭하는 이벤트 발생 시 @click="reverseMessage"로 reverseMessage 메서드가 호출된다.
해당 Vue Instatnce의 데이터 message를 뒤집은 연산을 수행하고, this.message에 할당하는 것을 볼 수 있다.

computed

계산된 속성을 정의한다.

여기서 computed로 지정된 변수는  data에 지정된 변수처럼 사용할 수 있다. 

    <div id="app">
      <h1>{{ message }}</h1>
      <p>Computed reversed message: {{ reversedMessage }}</p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
      new Vue({
        el: "#app",
        data: {
          message: "Hello, Vue.js!",
        },
        computed: {
          reversedMessage: function () {
            // computed 속성은 캐시된 연산된 속성으로, 연산된 데이터를 정의
            return this.message.split("").reverse().join("");
          },
        },
      });
    </script>
reversedMessage라는 변수는 message를 뒤집은 값을 저장한다.
만약 message 값이 변한다면 reversedMessage 값도 변하게 된다. 

components

재사용 가능한 요소를 component로 정의하여 대체한다.

아래에서 만들어 놓은 요소를 <app-footer></app-footer>와 같이 불러와서 사용할 수 있다.

아래에서 조금 더 자세히 다룬다.
    <div id="app">
      <h1>{{ message }}</h1>
      <app-footer></app-footer>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script>
      new Vue({
        el: "#app",
        components: {
          "app-footer": {
            template: "<footer><p>Footer content goes here.</p></footer>",
          },
        },
      });
    </script>

 

<app-footer></app-footer> 부분은 <footer><p> Footer content goes here. </p></footer>로 그대로 대체된다.

 

뷰 컴포넌트


뷰 컴포넌트에도 여러 가지 속성을 추가하여 동적으로 데이터를 다룰 수 있다.

위에서 <div id="app"> 태그 내에 <app-footer></app-footer>와 같이 컴포넌트를 불러다 쓰는 것을 확인할 수 있다.

여기에도 동적으로 데이터를 주고받는 등의 동작을 할 수 있다.

<div id="app">
      <some-component></some-component>
</div>
<script>
// 컴포넌트
	var someComponent = {
        template: "<div></div>", // 상위 컴포넌트에서 출력할 html
        props: [
          // 상위 컴포넌트에서 전달받은 data 정의
        ],
        methods: {
          //해당 컴포넌트에서 사용할 메서드 정의
        },
      };

//Vue 인스턴스
      new Vue({
        el: "#app",
        components: {
          "some-component": someComponent,
        },
      });
</script>

props, v-bind

상위 컴포넌트의 데이터를 하위 컴포넌트에서 받아서 사용할 수 있다.

v-bind:{하위 컴포넌트 props 명}="{상위 컴포넌트 data 명}"

상위 컴포넌트의 data하위 컴포넌트의 props가 받아서 사용한다.


v-on, $emit

하위 컴포넌트에서 발생한 이벤트를 상위 컴포넌트로 넘길 때 사용한다.

v-on:{하위 컴포넌트에서 발생시킨 event 명}="{상위 컴포넌트에서 실행시킬 method 명}

하위 컴포넌트에서 $emit으로 발생시킨 이벤트를 상위에서 v-on으로 받아서 사용한다.

this.$emit('hello'); //이벤트 발생


v-bind / v-on 예제

(화면 로드 시)

  1. Vue 컴포넌트의 data(num)이 하위 컴포넌트(someComponent)의 props: propsData로 전달된다.
  2. 하위 컴포넌트의 {{propsData}}로 해당 값이 세팅된다.

(버튼 클릭 시)

  1. v-on:click -> click 이벤트 발생 시 해당 컴포넌트의 incEvent가 실행된다.
  2. $emit을 통해 상위 컴포넌트로 'inc-num'이라는 이벤트를 전달한다.
  3. 상위 컴포넌트에서 'inc-num' 이라는 이벤트가 발생한 것으로 인식한다.
  4. "increaseNum"이 실행된다.
  5. num 값이 바뀌었으므로 Vue의 reactivity 속성으로 인해 하위 컴포넌트로 값이 전달되어 propsData 값도 수정된다.

 

뷰 디렉티브(view directive , v-xxx)


위에서 v-bind, v-on을 언급했다. 

이외에도 v-로 시작하는 요소들을 이용해서 Vue  도움을 받아 DOM을 조작할 수 있다.

 

아래의 Vue.js 공식 문서에서 검색을 통해 여러 요소들을 활용하는 방법을 쉽게 찾을 수 있다.

(공식문서가 정말 잘 되어있다.)

https://vuejs.org/

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 

v-bind

v-bind는 위의 예제에서 사용한 것들 이외에도 id, class 등 많은 요소들을 동적으로 바꿔줄 수 있다.

말 그대로 값을 binding 하는 기능이다.

<div id="app">
      <div>
        <p v-bind:id="uuid" v-bind:class="name">{{num}}</p>
      </div>
</div>
<script>
      new Vue({
        el: "#app",
        components: {},
        data: {
          num: 10,
          uuid: "abc1234",
          name: "text-blue",
        },
      });
</script>
위와 같이 id, class 등을 조작할 수 있다.
methods를 통해 해당 uuid, name 등의 값을 변경하면 해당 <p> 태그의 속성을 바꿀 수 있다.

v-if / v-else

true, false 조건에 따라 해당 화면에 출력할 DOM 요소를 선택할 수 있다.

    <div id="app">
      <div v-if="loading">Loading...</div>
      <div v-else>test user has been logged in</div>
      <button v-on:click="loadingToggle">loading?</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      new Vue({
        el: "#app",
        components: {},
        data: {
          loading: true
        },
        methods: {
          loadingToggle: function () {
            this.loading = this.loading?false:true
          },
        },
      });
    </script>
버튼에 따라 loading의 값이 true, false로 변환된다. 이에 따라 <div v-if="loading>이 출력될지, <div v-else>가 출력될지 바뀌게 된다.

v-show

v-if, v-else와 비슷하지만, v-show의 경우에는 display: none css를 추가하여 화면에 보여줄지 말지를 선택할 수 있다.

    <div id="app">
      <button v-on:click="loadingToggle">loading?</button>
      <!-- v-show: false일 경우, display: none으로 설정 -->
      <div v-show="loading">
        <p>loading: true</p>
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      new Vue({
        el: "#app",
        components: {},
        data: {
          loading: true
        },
        methods: {
          loadingToggle: function () {
            this.loading = this.loading?false:true
          },
        },
      });
    </script>
마찬가지로 버튼으로 loading 값이 true, false가 변환된다.
v-show의 경우에는 display: none 속성만 추가할지 말지가 결졍된다.

v-model

HTML의 입력요소(<input> , <textarea> , <select>) 와 Vue 인스턴스의 데이터 간에 동기화가 자동으로 이루어진다.

    <div id="app">
       <div>
          <input v-model="text">
          <p>input=> {{text}}</p>
       </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      new Vue({
        el: "#app",
        data: {
          text:''
        }
      });
    </script>

 

1. Vue 인스턴스가 초기화될 때, data 객체에 정의된 text 값이 <input> 요소의 value 속성에 바인딩된다.
2. 사용자가 <input> 필드에 입력을 하면, input 이벤트가 발생한다.
3. v-model은 input 이벤트를 감지해서, 해당 값을 Vue 인스턴스의 text 데이터 속성에 업데이트한다.
4. text 값의 업데이트를 감지해서 해당 데이터가 바인딩된 DOM 요소의 {{ text }} 표현식을 자동으로 업데이트한다.
반응형