- watch
- props
- emit
watch 사용법
const message = ref('변경전 입니다.')
watch(message, (newValue, oldValue) => {
console.log(newValue, oldValue)
})
message가 변경하면, 변경 후 값과 변경 전 값을 알 수 있음
const x = ref(0)
const y = ref(0)
watch(
() => x.value + y.value,
(sum) => {
console.log(sum, 'sum')
}
)
watch(obj, (newValue, oldValue) => {
console.log(newValue, oldValue)
})
watch(obj.count, (newValue, oldValue) => {
console.log(newValue, oldValue)
})
watch(
() => obj.count,
(newValue, oldValue) => {
console.log(newValue, oldValue)
}
)
const message = ref('hello vue3')
const reverseMessage = ref('')
const changeMsg = () => {
message.value = 'hi'
}
watch(message, (newValue) => {
console.log('즉시실행함')
reverseMessage.value = newValue.split('').reverse().join('')
})
watchEffect
const title = ref('')
const contents = ref('')
const save = (title, contents) => {
console.log(`저장 title : ${title} contetns: ${contents}`)
}
watchEffect(() => {
console.log('watchEffect')
save(title.value, contents.value)
})
최초로 즉시 실행임
PROPS
부모컴포넌트
<template>
<div>
<div v-for="post in posts" :key="post.id">
<AppCard :title="post.title" :contents="post.contents" />
</div>
</div>
</template>
<script>
import { reactive } from 'vue'
import AppCard from './AppCard.vue'
export default {
components: {
AppCard
},
setup() {
const post = reactive({
title: '제목2',
contents: '내용2'
})
const posts = reactive([
{ title: '제목1', contents: '내용1' },
{ title: '제목2', contents: '내용2' },
{ title: '제목3', contents: '내용3' },
{ title: '제목4', contents: '내용4' },
{ title: '제목5', contents: '내용5' }
])
return { post, posts }
}
}
</script>
<style lang="scss" scoped></style>
자식컴포넌트
<template>
<div>
<div class="card" style="width: 18rem">
<div class="card-body">
<span class="badge bg-secondary">뉴스, 공지사항</span>
<h5 class="card-title mt-2">{{ title }}</h5>
<p class="card-text">
{{ contents }}
</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['title', 'contents'],
setup() {
return {}
}
}
</script>
<style lang="scss" scoped></style>
EMIT - 즉 자식의 함수를 부모에서 끌어와서 실행한다고 보면 됨
자식컴포넌트
<template>
<div>
<div class="card" style="width: 18rem">
<div class="card-body">
<span class="badge bg-secondary">
{{ type === 'news' ? '뉴스' : '공지사항' }} 뉴스, 공지사항</span
>
<h5 class="card-title mt-2">{{ title }}</h5>
<p class="card-text">
{{ contents }}
</p>
<a v-if="isLike" @click="toggleLike">좋아요</a> --- 1. 해당 버튼을 누르면 toggleLike 함수가 실행한다.(즉 자식에서 부모의 값을 바꾸는 거라고 보면 됨)
<a v-else>싫어요</a>
</div>
</div>
</div>
</template>
<script>
import { computed } from 'vue'
export default {
emits: ['toggleLike'], --- 3. emits:['위로 올릴거'] 을 설정해준다.
setup(props, context) {
const isLikeClass = computed(() => (props.isLike ? 'btn-danger' : 'btn-outline-danger'))
const toggleLike = () => {
context.emit('toggleLike') --- 2. toggleLike는 부모에서 실행해야하기 때문에 부모로 보낸다.
}
return { isLikeClass, toggleLike }
}
}
</script>
<style lang="scss" scoped></style>
부모컴포넌트
<template>
<div>
<div v-for="post in posts" :key="post.id">
<AppCard
:title="post.title"
:contents="post.contents"
:type="post.type"
:is-like="post.isLike"
:obj="obj"
@toggle-like="post.isLike = !post.isLike"
/>
</div>
</div>
</template>
EMIT 다른 방법
자식컴포넌트
<template>
<div>
<button @click="$emit('createPost', 1, 2, 3, '김길동')">PostCreate</button>
</div>
</template>
<script>
export default {
setup() {
return {}
}
}
</script>
<style lang="scss" scoped></style>
자식 컴포넌트 2
<template>
<div>
<button @click="createPost">Button</button>
</div>
</template>
<script>
export default {
emits: ['createPost'],
setup(props, { emit }) {
const createPost = () => {
emit('createPost', 111, 2, 3, '김길동')
}
return { createPost }
}
}
</script>
<style lang="scss" scoped></style>
부모컴포넌트
<template>
<div>
<PostCreate @create-post="createPost" /> --- 1번, createPost를 받고
</div>
</template>
<script>
const createPost = (a, b, c, d) => { --- 2번, createPost 함수를 만들자.
console.log('createPost', a, b, c, d)
}
return { createPost }
}
}
</script>