vue.js

vue3 문법[클래스와 스타일 바인딩, 조건부 렌더링, 리스트 렌더링]

youngseokim_kr 2021. 11. 7. 15:19

클래스와 스타일 바인딩

<template>
  <h1
    :class="{active: isActive}"   <!-- isActive 가 true 이면 class가 active 이고 false면 아니다. -->
    @click="activate">
    Hello?!({{ isActive }})
  </h1>
</template>

<script>
export default {
  data() {
    return {
      isActive:false
    }
  },
  methods:{
    activate() {
      this.isActive =true
    }
  }
}
</script>

<style scoped> 
/* scoped 는 app.vue 를 제외하고 영향을 미치지 않는다. */
.active {
  color :red;
  font-weight :bold;
}
</style>

class에 객체 데이터를 사용하기 위해서 v-bind를 사용해 주는데 h1 v-bind: class  -> h1 :class 으로 생략 가능하다.

isActive는 처음에는 false지만 클릭하면 true로 변하기 때문에 true가 되면 style 부분에 선언된 .active가 실행되어 글씨가 강조되고 붉은색으로 변하는걸 확인할 수 있다.

인라인 스타일 바인딩하기

<template>
  <h1
    :style="[fonstyle, backgroundStyle]"
    @click="changeStyle">
    Hello?!
  </h1>
</template>

<script>
export default {
  data() {
    return {
     fonstyle : {
        color: 'orange',
      fontSize:'30px'
     },
     backgroundStyle : {
       backgroundColor:'black'
     }
    }
  },
  methods:{
    changeStyle() {
      this.fonstyle.color='red'
      this.fonstyle.fontSize='50px'
    }
  }
}
</script>

style 안에 직접 css를 작성할 수도 있고 여러가지 스타일을 적용시킬때는 배열을 이용할 수도 있습니다.

조건부 렌더링

v-if 디렉티브는 조건에 따라 블록을 렌더링할 때 사용합니다. 블록은 디렉티브의 표현식이 true 값을 반환할 때만 렌더링됩니다.

<template>
  <button @click="handler">
    Click me!
  </button>
  <h1 v-if="isShow">        //if
    Hello?!
  </h1>
  <h1 v-else-if="count > 3"> //else if
    Count > 3
  </h1>
  <h1 v-else>                //else
    Good~
  </h1>
</template>

<script>
export default {
  data() {
    return {
      isShow : true,
      count:0
    }
  },
  methods: {
    handler(){
      this.isShow = !this.isShow      //true면 false false 면 true
      this.count +=1                  //클릭시 +1
    }
  }
}
</script>
 <!-- template으로 묶으면 브라우저 코드에서 div가 안보인다. -->
  <template v-if="isShow"> 
    <h1>Title</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
  </template>

div로 묶으면 브라우저에서 코드를 보면 div로 묶인것이 확인되지만 template으로 묶으면 아무것도 없는것으로 보인다.

v-show

v-if는 "실제(real)" 조건부 렌더링입니다. 전환 도중 조건부 블록 내부의 이벤트 리스너 및 자식 컴포넌트들이 올바르게 제거되고 다시 생성되기 때문입니다.

또한 v-if는 게으릅니다(lazy). 초기 렌더링 시, 조건이 거짓(false)이면 아무 작업도 하지 않습니다. 조건부 블록은 조건이 처음으로 참(true)이 될 때까지 렌더링되지 않습니다.

이에 비해 v-show는 훨씬 간단합니다. 엘리먼트는 CSS 기반 전환으로 초기 조건과 관계 없이 항상 렌더링됩니다. (역자 주: v-show는 엘리먼트를 DOM에 우선 렌더링하고 조건에 따라 CSS display:block/display:none 속성을 전환합니다.)

일반적으로 v-if는 전환 비용이 높은 반면, v-show는 초기 렌더링 비용이 높습니다. 그러므로 무언가를 자주 전환해야 한다면 v-show를 사용하는 게 좋고, 런타임 시 조건이 변경되지 않는다면 v-if를 사용하는 게 더 낫습니다.

사용자가 계속 반복적으로 true와 false를 바꾸는 경우에는 v-show를 사용하는게 좋고 아니면 v-if를 사용하는게 좋다.

리스트 렌더링

<template>
  <ul>
    <li
      v-for="(fruit, index) in fruits"
      :key="fruit">
      {{ fruit }}-{{ index+1 }}
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      fruits : ['Apple','Banana','Cherry']
    }
  },
}
</script>

결과

npm i -D shortid 아이디를 고유하게 만들어줄 수 있는 패키지를 설치해주고

<template>
  <button @click="handler">
    Click me!
  </button>
  <ul>
    <li
      v-for="{id, name} in newFruits"
      :key="id">
      {{ name }}-{{ id }}
    </li>
  </ul>
</template>

<script>
import shortid from 'shortid'

export default {
  data() {
    return {
      fruits : ['Apple','Banana','Cherry'],
    }
  },
  computed:{
    newFruits() {
      return this.fruits.map(fruit => {
        return {
          id:shortid.generate(), //간단한 고유한 id 생성
          name:fruit
        }
      })
    }
  },
  methods : {
    handler() {
      this.fruits.push('Orange')  //push라는 메소드로 아이템을 변경
    }
  }
}
</script>

결과

변이 메소드

Vue는 감시중인 배열의 변이 메소드를 래핑하여 뷰 갱신을 트리거합니다. 래핑된 메소드는 다음과 같습니다.

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

콘솔을 열고 변형 메소드를 호출하여 이전의 예제의 items 배열로 사용할 수 있습니다.
예: example1.items.push({ message: 'Baz' })