Vue(1)

WorldWannyWeb.·2021년 8월 18일
0

Vue

목록 보기
1/1
post-thumbnail

2021-08-18

React를 논할때 항상 비교대상이 되는 존재가 있다. 바로 Vue이다. React를 접할 때 Vue와는 무엇이 다르고 어떻게 다른지 비교하고 공부하게 된다. 그렇다면 이번에 React말고 Vue에 대해서 공부해보자.

1. Vue?

Vue의 공식문서를 먼저 살펴보면 아래와 같이 정의되어있는 것을 볼 수 있다.

Vue(/vjuː/ 로 발음, view 와 발음이 같습니다.)는 사용자 인터페이스를 만들기 위한 프로그레시브 프레임워크 입니다.

필자는 정해진 틀이 있어 그 틀에 맞게 작성해주면 알아서 착착 routing을 해주거나 하는 기능이 다 들어있는 것이 프레임워크인 것으로 알고있는데 Vue는 틀에 맞춰 개발을 한다기엔 React처럼 내맘대로 폴더 만들고 개발할 수 있는 환경이라는 생각에 라이브러리에 더 가깝지 않나 싶다. 점진적으로 선택해서 만들 수 있어서 progressive를 붙인 것 같다.

2. Vue 시작

2-1. Vue 프로젝트생성하기

npm install -g @vue/cli 로 vue시작
vue create <프젝이름> 으로 생성( (ex): vue create wanny )
vue2, vue3 중 하나 고르기

2-2. Vue 구성요소

처음 Vue Cli를 통해 Vue 프로젝트를 만들었다면 src파일 안에 assets,components,App.vue,main.js 등이 보일 것이다.

assets : application에 사용되는 정적 resource가 들어있는 폴더. 이미지파일이 들어갈 수 있다.
components : Vue 또한 React와 같이 component기반으로 만들어진다. 컴포넌트들이 들어간다.
App.vue : Vue의 Root 컴포넌트다. 컴포넌트들이 App.vue를 중심으로 트리형태 구조를 가지게 된다.
main.js : Webpack이 build를 할때 가장 먼저 불러오는 Entry Point이다. 우리가 만든 application이 이 파일을 실행하면서 시작된다.

처음 Vue를 열어보면 template, script,style 세가지를 볼 수 있다.


<template>
  // 아래와 같이 html요소나 component가 들어간다.
  <Header /> //component
    <div id="content" class="content"> //html
      <router-view></router-view>
    </div>
</template>

<script>
  // 아래와같이 js가 들어간다. import로 component를 불러올 수 도 있고
  // export 안에 다양한 속성이 들어간다.
  import Header from './components/layout/Header.vue'

  export default {
    name: 'App',
    components: {
      Header,
      /*import로 Header를 가져온 후 사용하기 위해서는 components안에 Header를 넣어주어야함 */
    }
  }
</script>

<style>
  //아래와 같이 style이 들어간다. css,scss부분이라고 보면된다.
  //reset.css는 기본스타일을 0으로 만들고 시작하기 위함이다.
  @import "./styles/reset.css";
  #app {
    width: 560px;
    margin: 0 auto;
  }
</style>

2-3. Vue의 문법과 인스턴스옵션

Vue의 코드를 보다보면 {{}}와 v-for,v-if,:title, @click 과 같은 것이 태그안에 들어가있는 것을 볼 수 있다. 코드를 보면서 알아보자

아래 코드는 메모를 적을 수 있는 MemoForm 컴포넌트다. 하나하나 뜯어서 살펴보도록하자.

<template>
  <div class="memo-form">
    //form에 submit이벤트가 발생하면 이벤트의 기본동작을 방지 후, 아래 선언한
    //addMemo함수가 callback func로 실행된다.
    <form @submit.prevent="addMemo">
      <fieldset>
        <div>
          <input
            class="memo-form__title-form"
            type="text"
            v-model="title"
            placeholder="제목을 입력하세요"
          />
          //추가한 데이터 title을 v-model을 이용해 연결
          <textarea
            class="memo-form__content-form"
            v-model="content"
            placeholder="내용을 입력하세요"
          />
          //추가한 데이터 content를 v-model을 이용해 연결
          <button type="reset">
            <i class="fas fa-redo"></i>
          </button>
        </div>

        <button type="submit">등록</button>
      </fieldset>
    </form>
  </div>
</template>

<script>
export default {
  name: "MemoForm",
  data() {
    return {
      // 사용자가 입력할 제목과 내용이 저장될 데이터의 key와 value
      title: "",
      content: "",
    };
  },
  methods: {
    //title, content에 입력, 저장한 후 초기화시켜주는 코드
    resetFields() {
      this.title = "";
      this.content = "";
    },
    addMemo() {
      //destructureing assignment를 이용해 변수선언
      const { title, content } = this;
      //데이터의 고유한 식별자 생성
      const id = new Date().getTime();
      //제목이나 내용을 입력하지 않은 경우
      const isEmpty = title.length <= 0 || content.length <= 0;
      if (isEmpty) {
        return false;
      }
      //addMemo 이벤트를 발생시키고 payload로 사용자가 입력한 데이터를 넣어준다.
      this.$emit("addMemo", { id, title, content });
      this.resetFields();
    },
  },
};
</script>

우선 첫번째부터 살펴보면 form 태그에 @를 사용해 뭐라고 적혀있다. Vue에서는 자체태그안에 디렉티브를 사용하거나 태그에 mustash문법({{}})을 사용해 data가 view와 연동되도록 할 수 있다.

  • mustash
    {{}} 로 사용하고, DOM에 js내 data를 바인딩할 때 사용한다.
    ex) <p>{{message}}</p>

  • directive
    지시문이라는 뜻의 directive는 v-라는 접두사를 가지고 있는 특수속성이다. DOM의 모든 것을 관리할 수 있는 지시 나 명령이라고 할 수 있다. 속성값으로는 표현식을 사용할 수 있다.
    ex) v-bind, v-on, v-if, v-else, v-show, v-for, v-model, v-once

: 나 @같이 디렉티브는 약어를 사용할 수 있다.
v-bind = :
ex) v-bind:href="url" === :href="url"
v-on = @
ex) v-on:click="onClick" === @click="onClick"

template안에 form태그를 봐보자. 저 form태그 부분은 등록버튼을 누르면 addMemo()가 실행되어야한다. 이때, submit이라는 이벤트가 발생하고, submit이벤트가 발생했을때 자동으로 브라우저 새로고침이나 input field에 커서를 위치한 상태에서 키보드를 입력하면 텍스트가 입력되는 등의 브라우저가 기본적으로 제공해주는 기능을 방지하기 위해서 prevent 수식어를 같이 사용했다.

여기서 사용되어진 @는 v-on디렉티브의 약어이며 DOM element나 component에 이벤트리스너를 연결할 수 있는 디렉티브이다.

<template>
  <div class="memo-form">
    // form에 submit이벤트가 발생하면 이벤트의 기본동작을 방지 후, 아래 선언한
    // addMemo함수가 callback func로 실행된다.
    <form @submit.prevent="addMemo"> // === v-on:submit.prevent="addMemo"
    //
    //
</template>

그렇다면 submit이벤트가 발생했을때 실행되야하는 addMemo는 어디에 넣어줘야할까?
아래 코드를 살펴보자.

<template>
  <div class="memo-form">
    <form @submit.prevent="addMemo">
      <fieldset>
        //
        //
</template>

<script>
export default {
  name: "MemoForm",
  data() {
    return {
      //
    };
  },
  methods: {
    resetFields() {
      ///
    },
    addMemo() {
      const { title, content } = this;
      const id = new Date().getTime();
      const isEmpty = title.length <= 0 || content.length <= 0;
      if (isEmpty) {
        return false;
      }
      this.$emit("addMemo", { id, title, content });
      this.resetFields();
    },
  },
};
</script>

위 코드를 살펴보니 script태그 안에 있는 methods안에 addMemo()가 구현되어있다. methods위에는 data가 있다. 이 둘은 무엇일까?

앞서 우리는 Vue는 인스턴스를 만드는 것부터 시작한다고 배웠다. 이 인스턴스에는 확장된 컴포넌트에서 사용할 수 있는 data 관련 기능 및 옵션들이 존재한다.


  • data
    data속성은 반응형모델을 선언할때 사용한다. 인스턴스가 생성된 후 this.$data로 접근할 수 있다. Vue 인스턴스는 데이터 객체 내부의 값을 Proxying하기 때문에 this.$data.athis.a는 같은 값이다.
    (반응형모델: 어떤 액션으로 인해 값이 변경되었을때 js와 사용자가 보는 view에서 보이는 값도 같이 연동되어 변경되는 것)
//뷰 인스턴스
const data = {a:1}
new Vue({
data : data
})
//뷰 컴포넌트
const myComponent = Vue.extend({
  name:'MyComponent',
  data(){
    return {a:1}
  }
})

(Proxying: 대신하다 라는 의미인데 내가 접근하고자하는 대상에 직접 접근하지 않더라도 proxy구현체가 대상에 접금해 접근과정의 일부를 프락시 구현체가 대신 처리해준다. this.a(Vue인스턴스)에 접근함으로써 this.$data.a에 담겨있는 값이 접근할 수 있으므로 this.$data내부의 값에 this가 대신 접근해준다고 할 수 있다. )

위에 코드를 보면 뷰인스턴스와 뷰컴포넌트에서의 data속성 선언문법이 다른것을 볼 수 있다. 컴포넌트를 정의할 때 data속성은 반드시 Object자료형을 반환하는 함수로 선언되어야한다. 컴포넌트에서 data속성을 일반객체로 선언하면 같은 주소를 참조하는 데이터들을 공유하게 된다. 컴포넌트는 여러개일 경우가 많아 각각 컴포넌트가 독립적으로 data속성을 가지고 있게 해야한다.


  • props
    props속성은 부모 component로부터 data를 받아올 수 있게 노출된 속성들이다. 자식component 내부에서 props의 data를 다뤄야하는 경우 data속성 내에서 해당 props를 this로 접근해 참조하도록 다시 언언해 사용하거나 vm.$emit속성을 사용해 부모 component의 data를 변경해줘야한다.
Vue.component('mycomponent',{
  props:['size','myMessage']
})
Vue.component('mycomponent2',{
  props: {
    height: number,
    width: {
      type:number,
      required: true,
      default: 1,
    }
  },
  data(){
    return{ //props속성을 반응형으로 사용하는 방법
      dataHeight: this.height
    }
  }
})
// HTML 요소의 attribute처럼 작성해 값을 할당
<my-component :width='3' :height='3'></my-component>

  • computed
    computed는 계산된 데이터이다. computed 내부에서 사용된 data가 변경되면 자동으로 computed값도 갱신된다. 가장 큰 장점은 한번 계산되고 나면 caching이 된다. computed내부에서 사용된 데이터가 갱신되기 전에는 다시 계산되지 않으므로 한수를 선언해서 호출하는 것보다 효율적이다. 인자를 받지 않는 함수로 선언해 사용한다. 기본적으로 getter함수를 가지고 있다. setter함수를 통해 값을 쓰기 기능을 지원할 수 도 있다.
Vue.component('MyComponent',{
  template: '<div>{{doubleAge}}</div>'
  data(){
    return {age:29}
  },
  computed:{
    doubleAge(){
      return this.age*2 //58이 반환
    },
    //get,set
    doubleAge2(){
      get: function(){
        return this.age*2
      },
      set: function(newAge){
        thisae = newAge;
      }
    }
  }
})

  • methods
    인스턴스에 추가되는 메소드이다. methods에 선언된 메소드를 실행시킬 때는 this를 통해 직접 접근해 실행시키거나 디렉티브를 통해 사용할 수 있다. 선언된 모든 메소드는 this 컨텍스트를 Vue 인스턴스에 바인딩한다. 그렇기 때문에 Arrow function을 사용해 메소드를 정의하면 this가 부모컨텍스트를 의미하게 되므로 메소드 내부에서 현재 인스턴스의 data나 props에 접근할 수 없게 된다.
Vue.componet('MyComponent',{
  template: `<div @click="plusNumber"></div>`,
  data(){
    return {age:29}
  },
  methods:{
    plusNumber(){
      this.age++;
    }
  },
})

  • watch
    뷰 인스턴스 내의 데이터 변화를 감지하며 특정 로직을 수행해야할떄 사용하는 감시자속성이다. watch에서 사용되는 메소드의 이름은 감시하는 데이터 이름이다. 해당데이터가 변경되었을때 메소드 내부에 작성한 코드가 실행되는 방식으로 작동한다. watch 속성을 선언할때 첫번째 인자는 새로운 value 두번째 인자는 변경되기 전 value를 받을 수 있다.
Vue.component('MyComponent',{
 data(){
   return{ a:'Hello World', b:1}
 },
 watch:{
   a(nextValue, prevValue){
     console.log(`new: ${nextValue} old:${prevValue}`)
   }
 }
})

즉 addMemo는 인스턴스에 추가되는 메소드이므로 methods안에 만들어 사용할 수 있다.

참고: 커피한잔마시며끝내는Vue.js

profile
와니완의 월드와이드와니웹🐥

0개의 댓글