## 背景 以下のような`components/Counter.vue`があるとする。 ```html <script setup lang="ts"> import { ref } from "vue"; const count = ref(0); const increment = () => { count.value++; }; </script> <template> <div>{{ count }}</div> <button @click="increment">+</button> </template> ``` `Counter.vue`を利用している`App.vue`が以下。 ```html <script setup lang="ts"> import Counter from "./components/Counter.vue"; </script> <template> <div style="padding: 12px"> <Counter /> </div> <button>プラス</button> </template> ``` この『プラス』ボタンが押されたときに`Counter`の中のカウンターをインクリメントさせたい。しかし、Counterの値を`App.vue`では保持せず、`Counter.vue`の中で定義された`increment`関数を呼び出したい。 ## 方法 [[defineExpose]]を使って`increment`関数を公開し、[[Template refs]]を使って`Counter.vue`インスタンスのメソッドにアクセスし、実行する。 `App.vue` ```html <script setup lang="ts"> import { ref } from "vue"; const count = ref(0); const increment = () => { count.value++; }; // これを追加 defineExpose({ increment, }); </script> <template> <div>{{ count }}</div> <button @click="increment">+</button> </template> ``` `Counter.vue` ```html <script setup lang="ts"> import { ref } from "vue"; import Counter from "./components/Counter.vue"; // Counterのインスタンスをref経由で取得 const counterEl = ref<InstanceType<typeof Counter> | null>(null); </script> <template> <div style="padding: 12px"> <!-- refに先ほど指定した変数名を指定 --> <Counter ref="counterEl" /> </div> <!-- コンポーネントでexposeしたIFを利用できる --> <button @click="counterEl?.increment()">プラス</button> </template> ``` ## 参考 - https://vuejs.org/guide/essentials/template-refs