4) vue 공식 문서 보면서 메모 3
문서를 순서대로 보는 게 아니라서 꼭지마다 문서 링크를 달았다.
$emit + 커스텀 이벤트
자식 컴포넌트에서 부모 컴포넌트 데이터 수정은 안된다. (데이터가 반응성으로 가지지 않아서 화면 갱신이 안됨)
아래 예시에서 update:msg
라는 커스텀 이벤트를 만들었고 왔다갔다 하면서 데이터 갱신을 시킨다. 요는 데이터 갱신하는 부분의 코드가 부모 컴포넌트에 있어야 한다.
<div id="app">
<comp-a :msg="message" @update:msg="updateMsg"></comp-a>
<h1></h1>
</div>
<script>
// 컴포넌트 지역 등록
const CompA = {
template: '<button @click="addExclamation">Click!</button>',
props: {
msg: String
},
methods: {
addExclamation() {
// 자식 컴포에서 부모 컴포 데이터 바로 수정하면 반응성을 가지지 않음
// this.msg += '!'
this.$emit('update:msg', this.msg + '!')
}
}
}
new Vue({
el: '#app',
components: {
CompA
},
data() {
return {
message: 'Hello Vue'
}
},
methods: {
updateMsg(newMsg) { // 자식 컴포에 있는 this.msg + '!' 부분이 들어옴. 데이터 갱신은 부모 컴포넌트가 해야한다는 것.
this.message = newMsg
}
}
})
</script>
.sync, v-on을 이용한 사용자 지정 이벤트
https://kr.vuejs.org/v2/guide/components.html#sync-수식어
.sync를 이용해 간단하게 표현할 수 있다.
<div id="app">
<comp-a :msg.sync="message"></comp-a>
<h1></h1>
</div>
<script>
// 컴포넌트 지역 등록
const CompA = {
template: '<button @click="addExclamation">Click!</button>',
props: {
msg: String
},
mounted() {
// 생성한 커스텀 이벤트를 청취. 이벤트가 발생할 때 콜백 실행
this.$on('update:msg', newMsg => {
console.log('$on:', newMsg)
})
},
methods: {
addExclamation() {
// .sync를 사용할 때 Event 이름은 update: 로 시작해서 뒤에 prop이름을 붙여야 한다.
this.$emit('update:msg', this.msg + '!')
}
}
}
new Vue({
el: '#app',
components: {
CompA
},
data() {
return {
message: 'Hello Vue'
}
}
})
</script>
존재하는 속성 교체/병합
https://kr.vuejs.org/v2/guide/components.html#존재하는-속성-교체-병합
대부분 컴포넌트에 제공된 값이 설정된 값을 대체한다. class
, style
은 값이 합쳐진다. 해당 컴포넌트의 최상의 요소가 하나일 때 가능하다. 최상의 요소와 컴포넌트의 관계에서 일어나는 일이다.
<div id="app">
<comp-a class="disabled" style="font-weight: normal;" title="Gooooood!"></comp-a>
</div>
<script>
const CompA = {
template: '<h1 class="active" style="color: salmon;" title="Hello Vue">Vue!</h1>',
}
new Vue({
el: '#app',
components: {
CompA
}
})
</script>
결과물
<h1 title="Gooooood!" class="active disabled" style="color: salmon; font-weight: normal;">Vue!</h1>
비 부모-자식간 통신
https://kr.vuejs.org/v2/guide/components.html#비-부모-자식간-통신
데이터를 태워서 보낼 컴포넌트를 만들어서 데이터 이동용으로만 사용한다. 권장되지는 않는 방법이다. 아주 단순한 데이터 이동일 때만 고려해볼 수 있지만 프로젝트 커지면 vuex 도입을 권장.
<div id="app">
<comps>
<comp-a></comp-a>
<comp-b></comp-b>
</comps>
<comp-b></comp-b>
</div>
<script>
// 전역 생성한 컴포넌트를 버스용으로만 쓴다.
const bus = new Vue()
const Comps = {
template: '<div><h1>Components</h1><slot></slot></div>'
}
const CompA = {
template: '<button @click="getOnBus">CompA</button>',
methods: {
getOnBus() {
bus.$emit('nameOnBus', 'JENNIE')
}
}
}
const CompB = {
template: '<h1>Hi~ </h1>',
data() {
return {
user: '...'
}
},
created() {
bus.$on('nameOnBus', userName => {
this.user = userName
})
}
}
new Vue({
el: '#app',
components: {
Comps,
CompA,
CompB
}
})
</script>
범위를 가지는 슬롯
https://kr.vuejs.org/v2/guide/components.html#범위를-가지는-슬롯
유용한 기능이지만 일반적인 환경에서 쓸 일이 없을 수 있다.
<div id="app">
<comp-a>
<template slot-scope="props">
<div> JENNIE!</div>
</template>
</comp-a>
<comp-a>
<!-- 객체 구조분해 할당 활용 -->
<template slot-scope="{ myText }">
<div> JENNIE!</div>
</template>
</comp-a>
</div>
<script>
const CompA = {
template:
`<div>
<h1>CompA</h1>
<slot my-text="Hi~"></slot>
</div>`
}
new Vue({
el: '#app',
components: {
CompA
}
})
</script>
동적 컴포넌트
https://kr.vuejs.org/v2/guide/components.html#동적-컴포넌트
화면에 출력을 했다 안했다 하는 것. <component>
태그와 is
속성을 사용한다.
예시에서 버튼을 눌러서 바뀔 때 이전 컴포넌트는 파괴된다.(destroyed)
keep-alive
엘리먼트로 래핑하면 메모리에 유지된다. (파괴되지 않고 데이터 반응성이 유지된다.)
https://kr.vuejs.org/v2/api/?#keep-alive
api부분 문서에서 보면 keep alive
안에 있으면 라이프사이클에서 activate
와 deactivated
를 사용할 수 있다.
See the Pen vue_keep-alive by kabinny (@kabinny) on CodePen.
Vue CLI
뷰 프로젝트를 빠르게 생성해주는, 리액트의 create-react-vue같은 것. 뷰가 익숙해지고 잘 쓸 수 있게 되고 난 다음 편의를 위해서는 사용할 수 있다.
Leave a comment