Front-end/Vue.js

[Vue.js] 데이터 바인딩 Data Binding

ImYena 2021. 11. 9. 21:43
728x90

데이터 바인딩(Data Binding)

단방향 바인딩(One-way binding)

  • 컴포넌트의 데이터가 변경되면 UI요소 내용 변경

양방향 바인딩(two-way binding)

  • 컴포넌트의 데이터 변경 ↔ UI 요소의 변경
  • 주로 폼 데이터와 폼 양식 간의 바인딩

콧수염 표현식 데이터 바인딩(Mustache Data Binding)

{{...}}
  • {{ 데이터 객체 속성명 }} : {{data}}
  • {{ 삼항연산식 }} : {{(data>0)?"Yes":"No"}}
  • {{ 하나의 값을 산출하는 연산식 }} : {{data+1}}
  • {{ 하나의 값을 리턴하는 메소드 호출 }} : {{getMethod()}}
  • {{ computed 속성명 }} : {{getMethod}}

디렉티브 데이터 바인딩(Directive Data Binding)

 

API — Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

v-*="..."
  • 태그 내부 속성으로 작성
Directives
v-text,
{{ }}
▪ 문자열 그대로 출력
▪ <태그>{{...}}</태그>와 동일
v-html ▪ 문자열 안에 HTML태그가 포함되어 있을 경우 문자로 인식하는 것이 아닌 태그 그대로 인식
▪ 임의의 HTML을 동적으로 렌더링하는 것으로 XSS 공격에 취약함으로 사용 자제
▪ 해당 디렉티브 안에 HTML은 <style scoped>의 스타일이 적용되지 않음으로 <style>과 같은 전역 요소 사용해야 함
v-show 요소 숨김 여부
▪ v-if와 다르게 보이지만 않을 뿐 항상 렌더링되어 DOM에 남아있음
v-if 요소 제거 여부
조건문
▪ v-show와 다른게 조건부로 렌더링
v-else ▪ v-if나 v-else-if와 함께 사용
v-else-if ▪ v-if와 함께 사용
v-for 반복문
v-bind,
:
▪ 하나 이상의 attrivutes 또는 prop을 바인딩
속성 값 데이터 바인딩, 속성의 값으로 바인딩하기 위해서는 {{..}} 표현식 사용 불가능
v-model 양방향 바인딩
▪ Form 입력 데이터 바인딩
▪ <input>, <select>, <textarea>, components에 한해 한정
▪ .number을 통해 숫자(문자)를 자로 변경
v-pre  
v-cloak  
v-once ▪ 요소와 컴포넌트를 한 번만 렌더링, 이후 렌더링은 건너뜀
▪ 정적 요소

 

디렉티브 사용 예시

v-for

<태그 v-for="(item, index) in 배열" :key="식별값|index">...</태그>

<태그 v-for="(val, key) in 객체" :key="식별값|index">...</태그>
<태그 v-for="(val, name, index) in 객체" :key="식별값|index">...</태그>
  • index는 자동 생성되는 index
  • 객체(key-value)에 대한 val은 value, keyname은 key를 의미함
<태그 v-for="n in 10" :key="n">...</태그>
  • "n in 10"은 1부터 10까지 반복하는 반복문

*JS는 in 객체, of 배열 / 뷰는 in, of 상관x

 

v-bind, :

<img  v-bind:src="require(`@/assets/photos/${image}`)" height="300px" />

<img :src="require(`@/assets/photos/${image}`)" height="300px" />
  • @ 사용을 위해서는  require()와 백틱(`) 사용 필수
<p :class="className">아름다운 풍경</p>
<p :style="css">아름다운 풍경</p>
  • class나 style 속성의 속성값을 바인딩으로 주는 경우
<script>
export default {
  name:"AttrBinding",
  data() {
    return {
      image: "photo1.jpg",
      className: "className",
      css: "color: blue;"
    };
  }
}
</script>

<style scoped>
	.className {color: green}
</style>

 

v-model

<template>
  <div class="card">
    <div class="card-header">
      FormBinding
    </div>
    <div class="card-body">
      <form v-on:submit.prevent="handleSubmit">
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Name</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" v-model="product.name" />
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Company</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" v-model="product.company" />
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Price</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" v-model.number="product.price" />
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Info</label>
          <div class="col-sm-10">
            <textarea class="form-control" v-model="product.info"></textarea>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Madein</label>
          <div class="col-sm-10">
            <select class="form-control" v-model="product.madein">
              <option value="한국">한국</option>
              <option value="미국">미국</option>
              <option value="독일">독일</option>
            </select>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Colors</label>
          <div class="col-sm-10">
            <div class="form-check">
              <input type="checkbox" class="form-check-input"  v-model="product.colors" value="black" />
              <label class="form-check-label">Black</label>
            </div>
            <div class="form-check">
              <input type="checkbox" class="form-check-input"  v-model="product.colors" value="white" />
              <label class="form-check-label">White</label>
            </div>
            <div class="form-check">
              <input type="checkbox" class="form-check-input"  v-model="product.colors" value="red" />
              <label class="form-check-label">Red</label>
            </div>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Sale1</label>
          <div class="col-sm-10">
            <div class="form-check">
              <input type="checkbox" class="form-check-input"  v-model="product.sale1" />
              <label class="form-check-label">판매여부</label>
            </div>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Sale2</label>
          <div class="col-sm-10">
            <div class="form-check">
              <input type="checkbox" class="form-check-input"  v-model="product.sale2" true-value="yes" false-value="no" />
              <label class="form-check-label">판매여부</label>
            </div>
          </div>
        </div>
        <div class="form-group row">
          <label class="col-sm-2 col-form-label">Sex</label>
          <div class="col-sm-10">
            <div class="form-check">
              <input type="radio" class="form-check-input" v-model="product.sex" value="man" />
              <label class="form-check-label">Man</label>
            </div>
            <div class="form-check">
              <input type="radio" class="form-check-input" v-model="product.sex" value="woman" />
              <label class="form-check-label">Woman</label>
            </div>
          </div>
        </div>

        <div>
          <button class="btn btn-info btn-sm mr-2" v-bind:disabled="disabledRegButton">등록</button>
        </div>
      </form>
    </div>
  </div>
</template>
  • <form v-on:submit.prevent="handleSubmit"> .prevent 필수! 아니면 SPA 위반
<script>
export default {
  name:"FormBinding",
  data() {
    return {
      product: {
        name: "홍길동",
        company: "",
        price: 0,
        colors: [],
        info: "",
        madein: "한국",
        sale1: false,
        sale2: "no",
        sex: "woman"
      }
    };
  },
  computed: {
    disabledRegButton() {
      var result = this.product.name === "" || this.product.company === "";
      return result;
    }
  }
}
</script>
728x90
반응형