Vue 데이터 바인딩

김득회·2022년 9월 6일
0

Vue.js

목록 보기
9/9
post-thumbnail

뷰 컴포넌트의 역할

뷰 컴포넌트를 보관하는 폴더는 총 2가지로 관리가 된다
1. views
2. components

먼저 views 폴더는 각 페이지 화면 전체 큰 레이아웃을 구성하는 파일을 보관한다.
components에는 화면을 구성할 때 재사용이 가능한 컴포넌트(단위 UI)를 보관한다.

두 폴더에서 사용하는 파일은 모두 .vue를 사용하지만 구별할 수 있는 것 중 하나는 view파일에는 파일이름에 xxxView.vue라고 view라는 단어를 명시하는 명명규칙이 있다.

뷰 파일 구조

뷰의 장점은 하나의 파일 내부어 html, css, javascript 공간이 나누어져 있는 것이 가장 큰 장점이다.
이러한 장점은 서로의 영역을 침범하지 않아서 역할 분리가 명확해진다는 특징이 있다.

javascript

자바스크립트를 선언하기 위해서는 script라는 키워드를 명시하면 되고 하단과 같이 코드가 생기게 된다.

<script>
export default {
    data(){
        return {
            userName : 'deuk'
        }
    }
}
</script>

뷰에서의 자바스크립트는 function이라는 예약어를 사용하지 않는다는 특징이 있다.

css

css는 외부에 선언해 공통으로 사용할 수 있는 css와 파일 내부에서 해당 파일 전용으로 사용할 수 있는 css가 분리되어 있고, 내부에서 사용하는 css는 태그 오른쪽에 scoped라고 명시를 한다.

<style scoped>

</style>

외부에서 공통으로 사용하는 css는 assets파일에 두고 사용하면 좋다.

template

html파일이 들어가는 곳으로 컴포넌트를 제작하는 곳이다.
사용하는 규칙은 template안에서는 반드시 전체를 묶어주는 최상위 태그가 있어야한다. vue3에서는 오류가 나지 않지만, vue2까지는 오류로 처리하여 주의를 할 필요가 있다.
최상위 태그는 대부분 div를 사용한다.

뷰는 데이터 바인딩을 단방향, 양방향 모두 지원하는 장점이 있다.

단방향 데이터 바인딩

단방향 데이터 바인딩은 자바스크립트의 data함수의 return 안에 명시를 하여 값을 선언 하고 template에서 명시하여 사용할 수 있는 기술이다.

<template>
    <div>
        <h1>Hello, {{userName}}</h1>
        <p></p>
    </div>
</template>
<script>
export default {
    data(){
        return {
            userName : 'deuk'
        }
    }
}
</script>

Html 데이터 바인딩

Html 파일을 바인딩 하는 방법은 문자열 데이터 바인딩과는 다르다.
html을 바인딩 하는 방법은 v-html을 사용하는 방식으로 태그 옆의 속성 입력하는 것 처럼 사용한다.

<template>
  <div>
    <div>{{ htmlString }}</div>
    <div v-html="htmlString"></div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      htmlString: '<p style="color:red;">빨간색 문자</p>'
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

template에는 2개의 div 태그가 있다. 하나는 문자열 바인딩 하듯이 {{}}를 사용하는 방식과 v-html을 사용하는 방식이 있다.
innerHTML을 하기 위해서는 아래와 같은 방식을 사용해야 정상적으로 수행이된다.
v-xx 속성은 html뿐만아니라 if, model과 같은 다양한 속성들이 존재한다.

위에서 설명했듯이 문자열 바인딩 처럼 처리한 것은 html원본처럼 보이는 것을 확인 할 수있고 v-html로 제작한 것은 정상적으로 나오는 것을 확인 할 수 있다.

양방향 데이터 바인딩

자바스크립트에서 변경된 값이 화면에도 변경이 되고, 사용자가 html에서 입력한 문자, 데이터도 자동으로 자바스크립트와 연동이 된다.

양방향으로 데이터 바인딩을 위해 사용하는 속성은 v-model이다. 해당 속성을 태그에다 적어주면 되겠다.


이후 data 함수에 정의된 키값과 연결 해주면 양방향 데이터 바인딩을 사용할 수 있게된다.

숫자처리

v-model에서 받은 값들은 기본적으로 문자열 속성을 같는다.
그래서 수 연산 같은 것들을 할 때 산수를 하는 것이 아닌 문자열 합치기를 하는 현상이 발생한다.
이것을 해결하기 위해서 v-model.number를 사용한다.
기존에 parseInt()와 같은 javascript문법으로 변환하는 번거로움을 줄일 수 있다는 것이 큰 장점이다.

<template>
  <div>
    <input type="text" v-model="num1" /> +
    <input type="text" v-model="num2" /> =
    <span>{{ num1 + num2 }}</span>
    <br />
    <input type="text" v-model.number="num3" /> +
    <input type="text" v-model.number="num4" /> =
    <span>{{ num3 + num4 }}</span>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      num1: 0,
      num2: 0,
      num3: 0,
      num4: 0
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

selectBox

셀렉트 박스에서도 v-model을 사용할 수 있다. 사용할 옵션을 v-model을 통하여 미리 선택이 가능하고 변경할 수 있다.

<template>
  <div>
    <select v-model="selectedCity">
      <option value=""></option>
      <option value="02">서울</option>
      <option value="051">부산</option>
      <option value="064">제주</option>
    </select>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      selectedCity: '051'
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

위와 같으 코드를 입력하고 selectedCity를 지정하고 화면을 렌더링하면

위와 같이 부산이 먼저 보이게 된다.

checkbox

체크박스 또한 양방향 데이터 바인딩을 사용할 수 있으며 v-model을 사용할 수 있다.
여기서 v-model은 다른 태그들과는 다르게 값을 입력할 수 없다. 여기서 체크박스의 특징을 잘 알 필요가 있다.
체크 박스는 체크를 했다, 하지 않았다라는 상태를 가질 수 있다. 따라서 v-model은 체크박스에서 checked가 된 체크박스의 value값을 v-model을 통해 바인딩을 하는 것이다.

<template>
  <div>
    <div>
      <input type="checkbox" id="html" value="HTML" v-model="favoriteLang" />
      <label for="html">HTML</label>
    </div>
    <div>
      <input type="checkbox" id="css" value="CSS" v-model="favoriteLang" />
      <label for="css">CSS</label>
    </div>
    <div>
      <input
        type="checkbox"
        id="js"
        value="JavaScript"
        v-model="favoriteLang"
      />
      <label for="js">JavaScript</label>
    </div>
    선택 언어 : {{ favoriteLang }}
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      favoriteLang: []
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

위 코드와 같이 data함수에 배열을 선언하고 v-model에 배열을 연결해주면 선택된 체크박스의 value값이 들어가게 된다.

radiobutton

라디오버튼은 체크박스와 기능은 거의 동일 하지만 하나만 선택할 수 있으므로 v-model로 저장할 수 있는 것이 배열이 아닌 문자열로 관리한다.

<template>
  <div>
    <div>
      <input type="radio" id="html" value="HTML" v-model="favoriteLang" />
      <label for="html">HTML</label>
    </div>
    <div>
      <input type="radio" id="css" value="CSS" v-model="favoriteLang" />
      <label for="css">CSS</label>
    </div>
    <div>
      <input type="radio" id="js" value="JavaScript" v-model="favoriteLang" />
      <label for="js">JavaScript</label>
    </div>
    선택 언어 : {{ favoriteLang }}
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      favoriteLang: ''
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

HTML 속성 바인딩

Vue는 속성을 바인딩하는 기능도 제공을 한다.
v-bind는 태그의 속성을 동적으로 제어하기 위해 사용한다.
기본적으로 원래 지정하는속성 앞에 'v-bind:속성이름'으로 명시를 하지만, 간편하게 ':속성이름'으로 줄여서 사용하기도 한다.

<template>
  <div>
    <input type="text" v-bind:value="userId" readonly />
    <input type="text" :value="userId" readonly />
    <br />
    <img :src="imgSrc" style="width: 100px; height: auto" />
    <br />
    <input type="search" v-model="txt1" />
    <button :disabled="txt1 === ''">조회</button>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      userId: 'asdsad',
      imgSrc: 'https://upload.wikimedia.org/wikipedia/commons/f/f1/Vue.png',
      txt1: ''
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

리스트 동적 생성

뷰에서 리스트를 동적으로 생성하는 방법은 v-for를 사용하는 것이다.
기존 jsp나 thymeleaf, angular, react에서 사용하는 리스트 생성법과 많이 비슷하다.
v-for를 사용하는 방법은 속성넣는 곳에 넣어주면 되는데 여기서 중요한 것은 key를 무조건 바인딩을 해야한다는 것이다.
받은 리스트 중 키가 없으면 v-for="(객체, index) in 객체리스트" 이처럼 index를 for가 동작하면서 생성해 줄 수도 있다.

<template>
  <div>
    <div>
      <select>
        <option :key="city.code" :value="city.code" v-for="city in cities">
          {{ city.title }}
        </option>
      </select>
    </div>
    <div>
      <table>
        <thead>
          <th>주문번호</th>
          <th>상품이름</th>
          <th>가격</th>
          <th>제품수량</th>
          <th>합계</th>
        </thead>
        <tbody>
          <tr :key="drink.drinkId" v-for="drink in drinkList">
            <td>{{ drink.drinkId }}</td>
            <td>{{ drink.drinkName }}</td>
            <td>{{ drink.price }}</td>
            <td><input type="number" v-model="drink.qty" /></td>
            <td>{{ drink.qty * drink.price }}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      cities: [
        {
          title: '서울',
          code: '02'
        },
        {
          title: '부산',
          code: '053'
        },
        {
          title: '제주',
          code: '064'
        }
      ],
      drinkList: [
        {
          drinkId: 1,
          drinkName: '아메리카노',
          price: 2000,
          qty: 1
        },

        {
          drinkId: 2,
          drinkName: '레몬에이드',
          price: 3500,
          qty: 1
        },

        {
          drinkId: 3,
          drinkName: '플레인요거트',
          price: 4000,
          qty: 2
        },

        {
          drinkId: 4,
          drinkName: '초코라떼',
          price: 3500,
          qty: 4
        }
      ]
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

v-for는 단순히 반복을 통해 생성하는 것이면 어디든지 적용하여 사용할 수 있다.
또한 for를 통해 나오는 객체를 바인딩하여 새로운 값으로 변경도 할 수 있다는 장점이 있다.


위 사진처럼 제품 수량을 받아 v-model을 통하여 양방향 바인딩을 통하여 값을 변경하여 동적으로 변경하는 것도 가능하다.

클래스 바인딩

클래스를 바인딩 하는 것은 다른 것들과 다르게 Object형식으로 표시한다.
class는 여러개를 사용할 수 있고 true, false를 통하여 편리하게 on off 할 수 있도록 제공된다.
클래스를 바인딩 하는 방법에는 2가지가 있다.
하나는 속성 부분에 객체 형식으로 정의하는 방법과, 두 번째는 data 부분에 배열 형식으로 클래스이름을 나열하는 방식이 있다.
실무에서는 첫 번째 방법을 많이 쓴다고 한다.

<template>
  <div>
    <div :class="{ 'text-red': hasError, active: isActive }">클래스 바인딩</div>
    <div :class="class2">클래스 바인딩2</div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      isActive: false,
      hasError: true,
      class2: ['active', 'text-red']
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>
<style scoped>
.active {
  background-color: greenyellow;
  font-weight: bold;
}

.text-red {
  color: red;
}
</style>

데이터 바인딩에 강한 뷰답게 data함수에서 특정 클래스를 on off할 수 있도록 키를 선언해 놓으면 특정한 상황이 발생시 동적으로 상태를 변경할 수 있다.

스타일 바인딩

뷰에서는 스타일도 데이터 바인딩을 통하여 변경할 수 있다.
스타일은 여러개를 명시 할 수 있기 때문에 Object형식으로 관리를 한다.

<template>
  <div>
    <div>
      <div style="color: red; font-size: 30px">
        스타일 바인딩 : 글씨는 red, 폰트 크기 : 30px
      </div>
      <div :style="style1">스타일 바인딩 : 글씨는 green, 폰트 크기 : 30px</div>
      <button @click="style1.color = 'blue'">색상바꾸기</button>
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      style1: {
        color: 'green',
        fontSize: '30px'
      }
    }
  },
  setup() {},
  create() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

위코드를 보면 첫번째 div에서는 일반적으로 사용하는 기본 문법을 사용하였고, 두 번째는 v-bind를 사용하여 style을 바인딩 하였다.
여기서 알아두어야할 것은 일반적으로 css에서 font-size처럼 '-' 가 들어가는 문구는 전부 대문자로 변경하여 fontSize처럼 사용한다는 것을 유의해야한다.

또한 양방향 데이터 바인딩이기 때문에 클릭을 통하여 스타일 object에 접근을 하여 속성을 동적으로 변경할 수 있다.

profile
감성 프로그래머 HoduDeuk

0개의 댓글