정상적으로 동작하는 다른 컴포넌트와 마찬가지로 컴포지션 API를 사용하여 nuxt 프로젝트에서 vue 3 template ref를 사용하고 있습니다.단, 이 경우 null을 반환합니다.
템플릿은 다음과 같습니다.
<template>
<div class="horizontal-scroll-fix" ref="container">
<div class="horizontal-scroll-fix__scroll-fix">
<container class="horizontal-scroll-fix__container">
<div class="horizontal-scroll-fix__viewport" ref="viewport">
<div class="horizontal-scroll-fix__wrapper" ref="wrapper">
<slot></slot>
</div>
</div>
</container>
</div>
</div> </template>
<script>
import { ref, computed, onMounted, onBeforeUnmount, useSlots } from 'vue';
export default { // tried also to use shorthand <script setup> but no luck either
setup() {
const container = ref(null);
const wrapper = ref(null);
const viewport = ref(null);
onMounted(() => {
if (process.client) {
console.log(container?.value) // returns undefined
}
});
}
}
</script>
console.ref 오브젝트는 다음을 반환합니다.
RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: undefined, _value: undefined}
UDPDATE
그 후 셋업 스크립트의 마지막에 레퍼런스를 반환해야 한다는 통보를 받았습니다.그렇게return { container, wrapper, viewport }
다만, 혼란스러운 것은, 제 프로젝트에 있는 다른 모든 컴포넌트는, 이것을 실시하지 않고, 정상적으로 동작하고 있는 것입니다.그럼 제가 보지 못하는 이 녀석은 뭐가 다른가요?다음으로 정상적으로 동작하며 값을 반환하지 않는 템플릿 참조를 가진 다른 컴포넌트의 예를 나타냅니다.
<template>
<container>
<div :class="'sequence sequence--'+section.displayAs">
<div class="sequence__content" ref="content">
// removed inner content for the purpose of demonstrating
</div>
</div>
</container> </template>
<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue';
const props = defineProps({
section: {
required:true,
type:Object
}
});
const isDesktop = ref(false);
const currentSectionIndex = ref(0);
const fixedVisual = ref(null);
const content = ref(null);
function initMediaQuery() {
const mediaQuery = window.matchMedia('(min-width:1024px)');
checkDeviceSize(mediaQuery);
mediaQuery.addListener(checkDeviceSize);
};
function checkDeviceSize(query) {
if (query && query.matches) {
isDesktop.value = true
} else {
isDesktop.value = false
}
};
function initObserver() {
if (props.section?.displayAs === 'timeline' && isDesktop) {
console.log(isDesktop);
const target = fixedVisual;
const sections = content?.value.querySelectorAll('.sequence__section');
if (target && sections?.length) {
let callback = (entries, observer) => {
entries.forEach((entry,index) => {
if (entry.isIntersecting) {
currentSectionIndex.value = parseInt(entry.target.getAttribute('data-index'));
}
})
}
let options = {
rootMargin: '0px',
threshold:1.0
}
let observer = new IntersectionObserver(callback,options);
sections.forEach(section => {
observer.observe(section);
});
}
}
}
onMounted(() => {
if (process.client) {
initMediaQuery();
initObserver();
window.addEventListener("resize", initObserver);
}
});
onUnmounted(()=> {
if (process.client) {
window.removeEventListener("resize", initObserver);
}
});
</script>
질문에 대한 답변
3개의 변수를 반환해야 합니다.setup()
방법:
setup() {
...
return {
container,
wrapper,
viewport
} }
방법setup()
렌더러가 컴포넌트를 발견한 것처럼 컴포넌트의 라이프 사이클이 시작될 때 호출됩니다.즉, 본체에 사용되는 모든 요소가<template>
이 시점에서 알 필요가 있다setup()
종료됩니다.
설정 본문에 반환이 없습니다.ref
사용하는 값<template>
예상되는 동작을 얻으려면 , 를 변경할 필요가 있습니다.setup()
:
setup() {
const container = ref(null);
const wrapper = ref(null);
const viewport = ref(null);
// callbacks such as onMounted, onBeforeCreate, etc.
return { container, wrapper, viewport }; }