- shallowRef 란 ?
값 자체만 바뀌는지 감시하고 그 안까지 깊게 들여다보지는 않는 ref.
우선 Ref 와 shallowRef 의 차이부터 감을 잡으면 좋다.
1. Ref
ref 는 깊게 감시(deep)하여 객체 안까지 전부 반응성 추적을 한다.
const a = ref({ x: 1 })
a.value.x = 2 // 반응함
a의 값까지 변경할 수 있다.
2. shallowRef
통째로 바뀔 때만 반응한다.
내부는 신경쓰지 않고 겉만 보기 때문에 shallow 이다.
const a = shallowRef({ x: 1 })
a.value.x = 2 // 반응 안 함
a.value = { x: 2 } // 반응함
const currComponent = ref(AutoComplete)
AutoComplete 는 컴포넌트, 즉 객체이다.
만약 ref 로 선언하는 경우 컴포넌트 내부의 setup, render, props 정의 등
모든 것을 반응성 추적하려고 시도한다.
굳이 그럴 필요가 없기 때문에
보통 겉만 확인하는 shallowRef 로 선언해서 사용한다.
활용 예시)
| 최상위 부모 ─ CodeHelp ─ AutoComplete └ Select |
// 부모 CodeHelp.vue
마운트될 때 CodeHelp.vue의 부모로부터
isFilter 값을 받아서
참조할 컴포넌트 AutoComplete 또는 Select 를 정한다.
<template>
<Component :is="currComponent" :codeName="codeName" :items="detailList" :selectItem="item" :isReadOnly="props.isReadOnly" />
</template>
const props = defineProps({
isFilter: { //-- autocomplete, select 분기 해서 보여줌.
type: Boolean,
default: true
},
onMounted(() => {
currComponent.value = props.isFilter ? AutoComplete : Select
그리고
최상위부모에서 사용할 때
// Item.vue
<CodeHelp :master-seq="1"
:is-filter="false"
:label="_t('page.item.itemType')"
clearable
@onChange="onChange"
density="compact"
variant="outlined">
</CodeHelp>
이렇게 isFilter 값을 false로 보냈을 경우 (default : true)

Select 로 만들어지고
// ItemDialog.vue
<CodeHelp
:master-seq="60"
:is-filter="true"
v-model="itemData.itemSpec"
:label="_t('page.item.dialog.spec')"
@onChange="onChange"
variant="outlined"
clearable
hide-details="auto"
density="compact">
</CodeHelp>
true 로 넘기거나
isFilter 값을 넘기지 않을 경우

AutoComplete 로 만들어진다.
(입력 가능)
전체 코드
(AutoComplete, Select, CodeHelp)
AutoComplete.vue
<template>
<!-- 검색 가능 -->
<v-autocomplete
v-model="item"
:items="props.items"
:label="props.codeName"
:readonly="props.isReadOnly"
@update:modelValue="onChange"
return-object
:item-title="itemTitle"
item-value="detailSeq"
density="compact"
variant="outlined"
></v-autocomplete>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {consoleLog, getLanguage} from "@/assets/js/common/common.js";
import _ from "lodash";
const props = defineProps({
selectItem: {
type: Object,
default:{}
},
items: {
type: Object
},
codeName: {
type: String,
default: "공통코드"
},
isReadOnly: {
type: Boolean,
default: false
}
})
let itemTitle = getLanguage()==="ko"?"codeName":"codeEngName"
const emit = defineEmits(["onChange"]);
const item = ref(props.selectItem)
const onChange = (event) => {
let param = {
codeNameM: props.codeName,
codeNameD: _.isNull(event)?0:event.codeName,
codeNickName: _.isNull(event)?"":event.codeNickName,
dummy1: !event?"":event.dummy1,
dummy2: !event?"":event.dummy2,
dummy3: !event?"":event.dummy3,
dummy4: !event?"":event.dummy4,
dummy5: !event?"":event.dummy5,
masterSeq: _.isNull(event)?0:event.masterSeq,
detailSeq: _.isNull(event)?0:event.detailSeq,
}
consoleLog("CodeHelp onChange(Autocomplete)", param)
emit("onChange", param)
}
</script>
Select.vue
<template>
<v-select
v-model="item"
:items="props.items"
:label="props.codeName"
:readonly="props.isReadOnly"
@update:modelValue="onChange"
return-object
:item-title="itemTitle"
item-value="detailSeq"
density="compact"
variant="outlined"
></v-select>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {consoleLog, getLanguage} from "@/assets/js/common/common.js";
import _ from "lodash";
const props = defineProps({
selectItem: {
type: Object
},
items: {
type: Object
},
codeName: {
type: String,
default: "공통코드"
},
isReadOnly: {
type: Boolean,
default: false
}
})
let itemTitle = getLanguage()==="ko"?"codeName":"codeEngName"
const emit = defineEmits(["onChange"]);
const item = ref(props.selectItem)
const onChange = (event) => {
let param = {
codeNameM: props.codeName,
codeNameD: _.isNull(event)?0:event.codeName,
codeNickName: _.isNull(event)?"":event.codeNickName,
dummy1: !event?"":event.dummy1,
dummy2: !event?"":event.dummy2,
dummy3: !event?"":event.dummy3,
dummy4: !event?"":event.dummy4,
dummy5: !event?"":event.dummy5,
masterSeq: _.isNull(event)?0:event.masterSeq,
detailSeq: _.isNull(event)?0:event.detailSeq
}
consoleLog("CodeHelp onChange(Select)", param)
emit("onChange", param)
}
</script>
<style scoped>
</style>
CodeHelp.vue
<!--
공통코드조회 Component
@onChange로 데이터를 받으면 됨.
-->
<template>
<Component :is="currComponent" :codeName="codeName" :items="detailList" :selectItem="item" :isReadOnly="props.isReadOnly" />
</template>
<script setup>
import {onMounted, ref, shallowRef} from "vue";
import {consoleLog, doRequest, getLanguage, isDev} from "@/assets/js/common/common.js";
import {codeHelpList} from "@/assets/js/json/jsonData.js";
import AutoComplete from "@/components/common/codeHelp/AutoComplete.vue";
import Select from "@/components/common/codeHelp/Select.vue";
const currComponent = shallowRef(AutoComplete)
const props = defineProps({
isFilter: { //-- autocomplete, select 분기 해서 보여줌.
type: Boolean,
default: true
},
masterSeq: {
type: Number,
default: 0
},
detailSeq: {
type: Number,
default: 0
},
isReadOnly: {
type: Boolean,
default: false
}
})
const item = ref()
const detailList = ref()
const codeName = ref("공통코드")
onMounted(() => {
currComponent.value = props.isFilter?AutoComplete:Select
if (!isDev){
getData()
}
else{ //-- 테스트 샘플 코드
detailList.value = codeHelpList
for (let codes of codeHelpList){
if(codes.detailSeq === props.detailSeq){
item.value = codes
}
}
}
})
const getData = async () => {
await doRequest("post", "../../common/codeHelp/getCodeHelpList.do", {"masterSeq": props.masterSeq})
.then(res => {
let lang = getLanguage()
consoleLog("CodeHelp Res", res.data)
consoleLog("CodeHelpM", res.data.codeListM)
consoleLog("CodeHelpD", res.data.codeListD)
detailList.value = res.data.codeListD
codeName.value = lang==="ko"?res.data.codeListM[0].codeName:res.data.codeListM[0].codeEngName
if (props.detailSeq !== 0){
for (let codes of res.data.codeListD){
if(codes.detailSeq === props.detailSeq){
item.value = codes
}
}
}
else{
item.value = res.data.codeListD[0]
}
consoleLog("CodeHelpD", res.data.codeListD)
})
}
</script>
'웹 개발 > Vue' 카테고리의 다른 글
| [Vue3] Daum Post API 다음 주소를 Vue에서 사용하기 (주소) (0) | 2025.12.24 |
|---|---|
| [Vue3] emit, props (0) | 2025.09.29 |
| [Vue3][wikibook] 4. Vue3 시작을 위한 기초 학습 (0) | 2025.08.07 |
| [Vue3] optionsAPI / compositionAPI(script setup) 비교 예제 (0) | 2025.08.07 |
| [Vue3][wikibook] 1. Vue 소개 (3) | 2025.08.06 |