반응형
부모 컴포넌트
//부모 컴포넌트
<script setup="">
import {ref} from 'vue'
import Children from '@/views/Children.vue'
const data = ref()
const list = ref(['test3', 'test2', 'test1'])
const add = () => {
list.value = [data.value, ...list.value]
}
</script>
<template>
<div class="container">
<input type="text" v-model="data"/>
<button type="button" @click="add">추가</button>
<div class="w-100" v-for="(item, index) in list" :key="index">
<Children :index="index" :item="item"/>
</div>
</div>
</template>
<style></style>
자식 컴포넌트
//자식 컴포넌트
<script setup="">
import {defineProps, ref, toRefs} from 'vue'
const props = defineProps({
item: {
type: String,
required: true
},
index: {
type: Number,
required: true
}
})
const {item, index} = toRefs(props)
const testData = ref(item.value)
</script>
<template>
<div class="w-25 border mb-2">
{{item + '::->' + testData}}
</div>
</template>
<style></style>
처음 마운트 하는 경우 예상하는 값으로 랜더링이 되고 있다. 이때 test4를 추가해보자
(상황: list 0번째에 새로운 데이터를 추가하기 위해 list.value = [data.value, ...list.value] 로 추가했다)
새로 추가된 값에 경우 testData의 값이 test3으로 들어오는 게 확인 된다.
잘 살펴 보면 마지막 test1만 원하는 값이 나오고 나머지는 그전에 값과 동일한 값이 나온다.
이유
처음 부모가 마운트 될 때 자식 컴포넌트도 마운트를 하게 된다. 이 경우에는 정상적으로 동작.
이후 부모에 list가 변경될 경우
test3, test2, test1을 랜더링 했던 컴포넌트는 마운트가 이미 됐으므로 데이터 변경사항만 리랜더링 및 패치가 되고
마운트 되지 않는다. list를 추가할 때 마지막 데이터의 경우 새로운 컴포넌트를 만들기 때문에 mount가 되면서 setup 변수를 설정하게 된다. 그래서 testData가 이미 마운트 됐던 3개의 컴포넌트에서는 앞전에 마운트 될때 들어간 값이 들어가 있고 새로운 컴포넌트에서는 새롭게 받은 item.name에 값이 들어가게 된 것이다.
해결법 : watch 사용
<script setup="">
import {defineProps, ref, toRefs, watch} from 'vue'
const props = defineProps({
item: {
type: String,
required: true
},
index: {
type: Number,
required: true
}
})
const {item, index} = toRefs(props)
const testData = ref(item.value)
watch(
() => item, (nv, ov) => {
testData.value = nv.value
},
{deep: true}
)
</script>
<template>
<div class="w-25 border mb-2">
{{item + '::->' + testData}}
</div>
</template>
<style></style>
감시자를 사용하여 setup에 위치한 변수를 바꿔준다면 해결할 수 있다.
참고: list에 첫 번 째 데이터를 삭제하는 경우에도 실제 vue에서는 마지막 컴포넌트가 삭제 된다. 단지 데이터가 변경 될 뿐이다.
반응형
'Front-end > vue.js' 카테고리의 다른 글
[vue.js] markdown to text (마크다운 문법에서 텍스트 뽑아내기) (0) | 2023.10.12 |
---|---|
[Vue3] CompositionAPI vue i18n 다국어 처리 (0) | 2023.08.08 |
[vue] Life Cycle(생명주기) (0) | 2023.07.28 |
[Vue3] Composition API를 defineProps 및 toRefs 함수와 함께 사용하여 반응 속성을 정의 (0) | 2023.07.11 |
[vue3] Vue.Draggable 정리 (0) | 2023.06.23 |