Vue/Vue 2023

Vue 003 데이터 바인딩 002

salalsksjwnn 2023. 1. 31. 03:22
728x90

vue가 가진 가장 큰 장점중 하나인 양방향 데이터 바인딩을 합시다

양방향 데이터 바인딩

DataBindingInputView.vue

<template>
  <div>
    <input type="text"> 
  </div>
</template>

vue에서는 name="" id=""를 쓸 일이 없다.

  • v-model 을 사용해 데이터값을 받아온다
<template>
  <div>
    <input type="text" v-model="userId" />
  </div>
</template>
<script>
export default {
  components: {}, 
  data() {
    return {
      userId: 'SLOTH'
    }
  },
  .
  .
  .
  • 라우터 등록
  ...
  {
    path: '/databinding/input',
    name: 'DataBindingInputView',
    component: () => import(/* webpackChunkName: "databinding", webpackPrefetch:true */ '../views/1_databinding/DataBindingInputView.vue')
  }
  ...

나옵니다

v-model

양방향 데이터 바인딩이 가능하다 

사용자가 화면상에서 바꾸게 되면 그 값이 서버에도 바뀌게 된다.

  • 값이 바뀌는지 확인하기 위해 간단하게 버튼을 만들어 확인해보자
<template>
  <div>
    <input type="text" v-model="userId" />
    <button @click="myFunction">클릭</button>
  </div>
</template>
<script>
.
.
.
  methods: {
    myFunction() {
      console.log(this.userId) 
//this키워드를 사용해서 object안의 특정 키값을 불러오기
.
.
.

결과

내가 넣은 값이 콘솔에 출력된다.

  • js에서 변경한 값을 출력하기
...
<button @click="changeData">변경</button>
  </div>
</template>
<script>
...
    changeData() {
      this.userId = 'Yuki'
    }
...

바뀜

  • 숫자를 주고 받아보자 (.number의 활용)
<template>
  <div>
   ...
    <!-- string으로 더해져서 num1값과 num2값이 옆으로 붙은 값이 나온다 ex num1='1'+num2='2' result:12 -->
    <input type="text" v-model="num1" />+
    <input type="text" v-model="num2" />=
    <span>{{num1+num2}}</span>
    <br>
    <!-- v-model.number를 사용해 string값을 number로 바꿔준다. 산술연산이 된다. -->
    <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
    }
  },
  ...
  </script>

결과

  • select box
    • 사용자가 입력하는 개념이 아닌 옵션에 있는 아이템을 선택해 밸류값을 변경시킬 수 있다.
    • 밸류값을 변경시킬 수 있으니 v-model을 이용
  • DataBindingSelectView.vue
<template>
  <div>
    <select name="" id="" v-model="selectdCity">
      <option value="">선택</option>
      <option value="02">서울</option>
      <option value="031">경기</option>
      <option value="051">부산</option>
    </select>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      selectdCity: '02' //서울을 기본값으로
    }
  },
  ...

결과

선택 값을 변경시 다른 지역이 나옴

  • Checkbox
    • label과 연결을 위해서 id를 사용한다.
    • 똑같은 그룹으로 묶기위해서 name을 사용할 필요가 없다. v-model과 배열을 사용하면된다.
  • DataBindingCheckboxview.vue
<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="JS" v-model="favoriteLang">
      <label for="js">JavaScript</label>
    </div>
    <div>선택한 언어:{{favoriteLang}}</div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      favoriteLang: []
    }
  },
  ...

결과

v-model 배열로 지정해줘서 묶인다.

checkbox의 경우 value값과 양방향 데이터 바인딩이 되는 것이 아니고 checked라는 속성을 바인딩 하는 것

  • RadioButton
    • 체크박스와 비슷하지만 여러개 선택 불가능
    • 데이터를 배열로 선언하면 안되고 문자열로 선언해야함
  • DataBindingRadioView.vue
<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="JS" v-model="favoriteLang">
      <label for="js">JavaScript</label>
    </div>
    <div>선택한 언어:{{favoriteLang}}</div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      favoriteLang: ''
    }
  },
  ...

결과

  • 속성 바인딩
    • readonly의 경우에는 사용자가 값을 바꾸지 못하게 한 것이기 때문에 v-model 할 필요가 없다.
    • v-bind를 사용해 밸류값을 직접 데이터 바인딩을 해준다
    • v-bind는 : 로 대체가 가능하다
  • DataBindingAttributeView.vue
<template>
  <div>
    <!-- v-bind를 사용해 요소를 직접 바인딩 -->
    <input type="text" v-bind:value="userId" readonly/>
    <!-- v-bind 생략 -->
    <input type="text" :value="userId" readonly/>
    <br>
    <!-- :src 로 요소를 직접 바인딩 -->
    <img :src="imgSrc" alt="" style="width:300px; height:auto;">
    <br>
    <!-- 어떤 값이라도 무조건 들어와야 하는 searchbar -->
    <input type="search" v-model="txt1" />
    <!-- searchbar에 입력이 안되어 있으면 버튼 비활성화  txt1이 비어있냐?-->
    <button :disabled="txt1 === ''">조회</button>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      userId: 'Sloth',
      imgSrc: 'https://ichef.bbci.co.uk/images/ic/1008xn/p07rdf0q.jpg',
      txt1: ''
    }
  },
  ...

비어있다면 버튼 불가능
입력이 되어있다면 가능!

  • list 바인딩
    • 받아오게 될 데이터로 바인딩해서 갯수만큼 뿌려주기 v-for
  • DataBindingListView.vue
<template>
  <div>
    <div>
      <select name="" id="">
        <!--
          옵션이 cities의 갯수만큼 존재해야 한다. v-for를 사용한다.
          for in 사용하는 것 처럼 city in cities로 사용하는데
          cities의 데이터에서 뽑아온 각각의 오브젝트데이터가 city로 저장되는 것
          유니크한 key를 무조건 잡아주어야 한다. 여기서는 code가 유일한 키값이 된다. city의 code
          보여주는 화면에는 city의 title을 보여준다.
        -->
        <option value="" :key="city.code" v-for="city in cities">{{city.title}}</option>
      </select>
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      cities: [
        { title: '서울', code: '02' },
        { title: '경기', code: '031' },
        { title: '부산', code: '051' }
      ]
    }
  },
  ...

결과

  • v-for 사용해 테이블 표 구성하기
<template>
  <div>
...
    <div>
      <table>
        <thead>
          <tr>
            <th>제품번호</th>
            <th>제품명</th>
            <th>가격</th>
            <th>주문수량</th>
            <th>합계</th>
          </tr>
        </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.price * drink.qty}}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
...
      drinkList: [
        { drinkId: '1', drinkName: '코카콜라', price: 700, qty: 1 },
        { drinkId: '2', drinkName: '오렌지주스', price: 1200, qty: 1 },
        { drinkId: '3', drinkName: '커피', price: 500, qty: 1 },
        { drinkId: '4', drinkName: '물', price: 700, qty: 1 },
        { drinkId: '5', drinkName: '보리차', price: 1200, qty: 1 },
        { drinkId: '6', drinkName: '포카리', price: 1000, qty: 1 },
        { drinkId: '7', drinkName: '뽀로로', price: 1300, qty: 1 }
      ]
    }
  },
...

key값으로 쓸만한 요소가 없다면 i를 선언해 index를 주면 된다.

꽤 빠르네

  • class 바인딩
  •  
<template>
  <div>
    <!--
      클래스에 오브젝트를 선언해서 넣을 수 있다. 변수를 설정해 동적으로 만들 수 있다.
      키는 클래스 이름, 값은 불리언
      클래스 명이 한단어로 되어있으면 따옴표 안붙여도 됨
    -->
    <div :class="{ 'text_navy':hasError, 'active':isActive }">클래스 바인딩</div>
    <!-- 배열로도 가능 -->
    <div :class="class2">클래스 바인딩2</div>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      isActive: false,
      hasError: false,
      class2: ['active', 'hadError']
    }
  },
...
</script>
<style scoped>
  .active{
    font-weight: bolder;
    border: 1px solid black;
  }
  .text_navy{
    background-color: yellow;
    color: navy;
  }
</style>

결과

 

  • 스타일 바인딩
    • 오브젝트 형식으로 지정해 줄 수 있다.
<template>
  <div>
    <!-- 마치 오브젝트 키:밸류 를 보는 것 같다. -->
    <div style="color:red;font-size:30px">스타일 바인딩: 글씨는 red, 폰트크기:30px</div>
    <!-- 그럼 오브젝트로 적용하자! -->
    <div :style="style1"> 스타일 바인딩: 글씨는 green, 폰트크기:30px</div>
    <button @click="style1.color='blue'">색상 바꾸기</button>
  </div>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      style1: {
        color: 'green',
        fontSize: '30px' // 카멜케이스를 써야한다.
      }
    }
  },
...
</script>
<style scoped>

</style>

결과

버튼을 누르면 바뀐다.

 

 

state는 집에가 엄마는 vue 할거야

 

728x90