概要
v-if でコンポーネント表示を切替したとき、非表示になったコンポーネントの destroyed() が呼ばれない場合があったので調査した。
🙆♂️想定通りの振る舞い
flag が false になったら Child.destroyed() が呼ばれるのを確認した。
<template>
<div>
<Child v-if="flag"></Child>
</div>
</template>
🙅♂️想定外(destroyedが呼ばれなかった..)
flag の切替で別の Child コンポーネントを描画した場合は、Child.destroyed() は実行されなかった。
<template>
<div>
<Child v-if="flag"></Child>
<Child v-else></Child>
</div>
</template>
何が原因だったか
stack overflow で全く同じ疑問に対する回答があった。
こちらの記事によると Vue の意図した振る舞いであるらしい。内部的にはコンポーネントを使い回している様子。
もし意図的に destroyed() を呼ばせたい場合は key に別の値を設定すれば良い。
<template>
<div>
<Child key="A" v-if="flag"></Child>
<Child key="B" v-else></Child>
</div>
</template>
flag 切替のたびに Child.destroyed() が呼ばれていることを確認できた。