🪜

Vue の defineExpose でコンポーネント内部のスクロールを外部から制御する

2024/12/12に公開

Vue3 のコンポーネントでは、defineExpose を活用することで、親コンポーネントから子コンポーネント内の処理(例: スクロール位置の制御)を簡潔に、かつ、型安全に呼び出せます。

前提

  • TypeScript
  • Vue3 で script setup を使用

子コンポーネントで defineExpose を使用する

子コンポーネント内でスクロールの制御を行う関数を defineExpose で公開することで、親コンポーネントから直接呼び出せるようになります。

<!-- ChildComponent -->
<script setup lang="ts">
const scrollContainer = ref<HTMLDivElement | null>(null)

function scrollToTop(){
  if (scrollContainer.value) {
    scrollContainer.value.scrollTop = 0
  }
}

defineExpose({ scrollToTop })
</script>

親コンポーネント側で子コンポーネントの処理を呼び出す

子コンポーネントの defineExposeされた関数は、子コンポーネントに設定した ref を経由して呼び出せるようになっています。

<!-- ParentComponent -->
<script setup lang="ts">
import ChildComponent from '@/components/ChildComponent.vue'
# ChildComponent の型を定義
type ChildInstance = InstanceType<typeof ChildComponent>
# ChildComponent に設定する ref
const childRef = ref<ChildInstance | null>(null)

function handleScrollToTop(){
  childRef.value?.scrollToTop()
}
</script>
<template>
  <Child ref="childRef" />
  <button @click="handleScrollToTop">scrolToTop</button>
</template>

まとめ

筆者はこの方法知らず、子コンポーネントのスクロールを制御するために、 ref を子コンポーネントに渡したりゴニョゴニョやっていたのですが、defineExpose を使えばかなり簡単にできることを知りました。
今後、スクロール制御以外にも活用していきたいと思います。

Studio Tech Blog

Discussion