Vue - 10

핫다리·2023년 12월 20일

VUE

목록 보기
10/10

컴포지션 API

컴포지션를 사용해 같은 기능들끼리 분류해 코드를 정리할 수 있다.

setup()을 사용해 코드를 작성한다.
다만, setup안에 작성된 데이터는 반응성을 가지지 않기 때문에 ref를 사용해 객체 데이터를 사용해야 하고
값을 사용하기 위해선 .value를 사용해야 한다.
그 다음 return 에 반환해 template에서 사용한다.

<template>
  <div @click="increase">{{ count }}</div>
</template>

<script>
import {ref} from 'vue' //반응성을 위해

export default {
  setup() {
    let count = ref(0)     //data() 안에 있던 count를 작성
    function increase() {  //method 안에 있던 함수 작성
      count.value += 1     //ref를 사용해서 .value를 사용해야 값이 변경
    }

    return{                //return 으로 반환해서 사용. count.value로 안해도 댐
      count,
      increase
    }
    
  }
}
</script>

기본 예제와 라이프 싸이클

컴포지션을 적용해보자. 다음 두 예제는 같은 기능을 수행하나, 한쪽은 컴포지션이 추가되었다.

여기서 라이프싸이클도 컴포지션화 할 수 있다.

컴포지션은 DOM 에 연결되고 나서 컴포지션이 가능하다.
따라서 create는 따로 존재하지 않고 그냥 바로 실행하면 된다.

컴포지션 API 적용 안함, 여러 기능이 들어가면 보기 힘들다
<template>

  <h1 @click="increase">
    {{ count }} /{{ doubleCount }}
  </h1>

  <h1 @click="changeMessage">
    {{ Message }} / {{ reverseMessage }}
  </h1>

</template>


<script>
export default {
    components: {
     data() {
      return {
        count:0,
        message: 'hello world!'
      }
     },
     computed: {
      doubleCount() {
        return this.count *2
      },
      reverseMessage() {
        return this.message.split('').reverse.join('')
      }
     },
     watch: {
      message(newValue){
        console.log(newValue)
      }
     },
     created() {
        console.log(this.message)
      },
      mounted() {
        console.log(this.count)
      },
     method: {
      increase() {
        this.count +=1
      },
      changeMessage() {
        this.message = 'Good!'
      }
     }
   }
}
</script>
컴포지션 API 적용
<template>
  <h1 @click="increase">
    {{ count }} /{{ doubleCount }}
  </h1>
  <h1 @click="changeMessage">
    {{ Message }} / {{ reverseMessage }}
  </h1>
</template>

<script>
import {ref, computed, watch, onMounted} from 'vue'

export default {
    setup(){
    //count 관련
      const count = ref(0)
      const doubleCount = computed(()=>{
        return count.value*2
      })
      function increase() {
        count.value
      }
	//msg관련
      const message = ref('hello world!')
      const reverseMessage = computed(()=>{
        return message.value.split('').reverse.join('')
      })
      function changeMessage() {
        message.value='Good?!'
      }

      watch(message, newValue=>{
        console.log(newvalue)
      })
	//라이프 싸이클. mount
      onMounted(() => {
        console.log(count.value)
      })
	//create는 없다. DOM 에 연결되고 나서 컴포지션이 가능하다.
      console.log(message.value) 

      return { // 다 만들고 리턴하면 사용이 가능하다.
        count,
        message,
        increase,
        doubleCount,
        reverseMessage,
        changeMessage
      }
    }
}
</script>

props, context

컴포지션 API안에 사용하는 setup에서는
this.~로 접근할 수 없다. 이를 대신해주기 위해 props, context를 사용한다.

<template>
  <MyBtn
    class = "na"
    style = "color: red;"
    color="#ff0000"
    @hello = "log">
  Apple
  </MyBtn>
</template>

<script>
import MyBtn from './components/MyBtn.vue'

export default {
    components: {
      MyBtn
    },
    method: {
      log() {
        console.log('hello!')
      }
    }
}
</script>
<template>
  <div
      v-bind="$attrs"
      class="btn"
      @click="hello">
      <slot></slot>
  </div>
</template>

<script>
import { onMounted } from 'vue'

export default {
  inheritAttrs:false,
  props:{
      color: {
          type: String,
          default: 'gray'
      }
  },
  //emits: ['hello'],
  //mounted() {
  //    console.log(this.color)
  //    console.log(this.$attrs)
  //},
  //methods: {
  //    hello(){
  //        this.$emit('hello')
  //    }
  //},
  setup(props, context) {
    //this 대신 props, context
    function hello() {
      context.emit('hello')
    }
    onMounted(()=>{
      console.log(props.color)
      console.log(context.attrs)
    })

    return {
      hello
    }
  }
}
</script>
profile
일단 만들고 본다

0개의 댓글