2022-07-26

조지성·2022년 7월 26일
0

TIL

목록 보기
62/78
post-thumbnail

Computed

템플릿 문법 ({{ }})은 편하지만 코드가 길어지면 가독성이 떨어지고 유지보수가 어려움 , 따라서 이럴 때 사용하는 것이 계산된 속성 computed property

computed vs method

메서드와 동일 한 결과를 얻을 수 있지만 computed는 결과가 캐쉬되기 때문에 computed내 반응형 데이터가 변경된 경우에만 다시 계산된다.

writable computed

computed는 기본적으로 getter전용, 즉 readonly기 때문에 새 값을 할당하기 위해서는 gettersetter를 이용

코드

<template>
  <div> 
    <h2>{{teacher.name}}</h2>
    <h3>강의가 있습니까?</h3>
    <!-- 수정에 복잡하다. -->
    <!-- <p>{{ teacher.lectures.length > 0 ? "있음":"없음"}}</p> -->
    
    <!-- 결과는 같지만 computed가 비용이 적게듬 -->
    <!-- computed는 변경되지 않은 경우 캐쉬되었기 때문에 계속 로드되지 않음 -->
    <h3>{{hasLecture}}</h3>
    <h3>{{hasLecture}}</h3>
    <h3>{{hasLecture}}</h3>
    <!-- 메서드는 계속 로드 -->
    <h3>{{existLecture()}}</h3>
    <h3>{{existLecture()}}</h3>
    <h3>{{existLecture()}}</h3>
    <button v-on:click="counter++">Counter : {{counter}}</button>
  
    <h2>이름</h2>
    <p>{{fullName}}</p>
  
  </div>
</template>

<script>
import { computed , ref} from '@vue/reactivity'
import { reactive } from 'vue'

export default {
  setup () {
    const teacher = reactive({
      name : "짐코딩",
      lectures : [
        'html/css',
        'javascript',
        'vue3'
      ]
    })

    //computed는 한번 호출하면 캐쉬로 저장해둠
    // 다시 계산되는 경우는 반응형 데이터가 변화될때 
    const hasLecture = computed(()=>{
      console.log('computed');
      return teacher.lectures.length > 0 ? "있음":"없음"
    })
    // 메서드로 computed 같은 출력 만들기
    const existLecture = ()=>{
      console.log('method');
      return teacher.lectures.length > 0 ? "있음":"없음";
    };

    const counter = ref(0);

    const firstName = ref('홍');
    const lastName = ref('길동');

    // const fullName = computed(()=>{
    //   return firstName.value + ' '+lastName.value;
    // })
    // console.log('console.log : ',fullName.value);
    // fullName.value = '짐 코딩';

    //getter와 setter로 새로운 값 할당
    const fullName = computed({
      get(){
         return firstName.value + ' '+lastName.value;
      },
      set(value){
        console.log('value ',value);
        [firstName.value , lastName.value] = value.split(' ');
      }
    })
    fullName.value = '짐 코딩';
    return {
      teacher,
      hasLecture,
      existLecture,
      counter,
      fullName
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

클래스와 Style 바인딩

클래스 바인딩

  • 객체 바인딩

    • :class를 사용해서 바인딩
    • 일반 html class속성과 공존 가능
    • 객체를 computed에 바인딩 가능
  • 배열에 바인딩

    • 배열을 :class 에 바인딩

코드

<template>
  <div>
    <!-- class 와 v-bind가 공존 -->
    <!-- :class는 여러개 가능 -->
    <div class="text"  :class="{active: isActive , 'text-danger': hasError}">텍스트입니다.</div>
     <div class="text"  :class="classObject">텍스트입니다.</div>
      <div class="text"  :class="[activeClass,errorClass,classObject]">배열.</div>
    <button v-on:click="toggle">toggle</button>
    <button v-on:click="hasError = !hasError">toggle Error</button>
  </div>
</template>

<script>
import { computed } from '@vue/reactivity';
import { reactive, ref } from 'vue'

export default {
  setup () {
    
    const isActive = ref(true);

    const toggle = ()=>{
      isActive.value = !isActive.value;
    }

    const hasError = ref(false);

    // const classObject = reactive({
    //   active:true,
    //   'text-danger':false
    // })

    const classObject = computed(()=>{
      return {
        active:true,
        'text-danger':false,
        'text-blue':true,
      }
    })

    const activeClass = ref('active');
    const errorClass = ref('error');

    return {
      isActive,
      toggle,
      hasError,
      classObject,
      activeClass,
      errorClass}
  }
}
</script>

<style scoped>
.active{
  font-weight: bold
}
.text-danger{
  color: red;
}
</style>

인라인 스타일 바인딩

  • :style로 바인딩

    • 객체로 바인딩 할 수 있음
  • 배열에 :style바인딩 가능

코드

<template>
  <div>
    <div :style="styleObject">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequuntur iure error enim incidunt dolor nihil ipsam, similique modi amet, earum eum facere voluptatem. Animi enim nulla asperiores, in fugit voluptate!
    </div>
    <button v-on:click="fontSize--">-</button>
    <button v-on:click="fontSize++">+</button>
  </div>
</template>
 
<script>
import { computed } from '@vue/reactivity'
import { reactive ,ref} from 'vue'

export default {
  setup () {
    
    // const styleObject = reactive({
    //   color:'red',
    //   // 카멜케이스로
    //   fontSize: '13px'
    // })

    const styleObject = computed(()=>{
      return {
        color:'red',
        // 카멜케이스로
        fontSize: fontSize.value+ 'px',
      }
    })

    const fontSize = ref(13);

    return {
      styleObject,
      fontSize,
    }
  }
}
</script>

<style lang="scss" scoped>

</style>
profile
초보 개발자의 성장기💻

0개의 댓글