-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: PitchLineの初期化をonMountedOrActivatedで行っていなかったので修正 #2558
base: main
Are you sure you want to change the base?
Conversation
🚀 プレビュー用ページを作成しました 🚀 更新時点でのコミットハッシュ: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
トーク/ソングの切り替えでPIXI(WebGL)のオブジェクトを破棄しないように(維持するように)する
onMountedOrActivatedからonMountedに変更
これはアリだと思います!
もちろんメモリ消費は多めになりそうですが、トーク←→ソングの切り替えスピードも上がると思うのと、onMountedやonActivated周り簡単になりそうなので!
たぶんonMounted
に変えたことでいろいろ前提が変わってより簡単にできそうだったので、ちょっと気になった点をコメントしました!
renderInNextFrame = true; | ||
}; | ||
|
||
let initialized = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
状態変数が多く、起動シーケンスが結構ややこしくなっているので、可能なら削減できると嬉しいかもです!
initialized
があるのはwatch { immediate: true }
時に発動させないためだと思います。
となるとたぶん{ immediate: true }
を消せばinitialized
をなくせそうですがどうでしょう・・・?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
immediate: true
は必要なさそうですが、immediate: false
のときでもwatchのコールバックがonMounted
の前に呼ばれるというのはタイミングによっては起こり得るので(たぶん)、initialized
フラグはあった方が安全かなと思います。
ひとまずimmediate: true
は無くしました。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
たしかに!!!
起動シーケンスややこしくなっちゃうなと思ってドキュメント読み直してたら、必ずonMountedの後にwatchコールバックが呼ばれそうな設定がありました!!
https://ja.vuejs.org/guide/essentials/watchers.html#post-watchers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
すみません、不正確でした。。
flush: "post"
に関係なく、たぶんonMountedの前にwatchが呼ばれることはimmediate: true以外ではなさそうでした!
Qiita記事にまとめてみました。
KeepAliveとかv-if含めてガチャガチャいろいろ検証してみた感じでも、watchが呼ばれるのは必ずonMountedよりは後でした!!
Playgroundこちらです。
// NOTE: watchのimmediateはonMountedの前に実行されるので、最初の更新はwatchではなくここで直接実行する | ||
void updateOriginalPitchLineDataMap(); | ||
void updatePitchEditLineDataMap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
現状、念の為に呼んでる感じ・・・・・でしょうか・・・?
データが更新されるたびにupdateOriginalPitchLineDataMap
等が呼ばれるので、データが更新されていないはずのonMounted内では呼ばなくても良いはず・・・?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PitchLine.pitchDataMap
は最初は空なので、updateOriginalPitchLineDataMap
等を呼んでPitchLine.pitchDataMap
を更新(値をセット)する必要があります。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
たぶんupdateOriginalPitchLineDataMap
を呼んでるwatch
のwatch([singingGuidesInSelectedTrack, tempos, tpqn]
は、データが空っぽじゃなくなったタイミングで必ず実行されるので、onMountedで明示的に呼ばなくても値がちゃんとセットされる気がします!
質問の意図は、例えば万が一このコンポーネントのonMountedが2度以上呼ばれるようになると、ここでupdate
関数を叩かないといけないので、念の為に呼ぶ意図なのかな〜と思った次第です。
onMountedでupdate呼ぶのは良いと思うのですが、値を同期させる意図なのであればwatch内でやったほうが起動シーケンスが簡単になるんですよねー・・・。
ということで、watchImmediateAfterMounted
みたいなコンポーザブルを作るのはどうでしょうか!
こんな感じの関数を作ればよいのかなと!
onMounted後にコールバックが必ず実行される・・・はず・・・? ちょっと関数名はもう少しマシ名の思いつきたいかも。。
import { WatchSource, watch, ref, onMounted } from "vue";
const watchImmediateAfterMounted = <T>(
source: WatchSource<T>,
fn: (after: T, before: T) => void,
) => {
// onMountedのときにtrueになるだけのref
const mounted = ref(false);
onMounted(() => {
mounted.value = true;
});
// watchしたいものと`mounted`をwatchする
watch([source, mounted], ([after, mounted], [before]) => {
if (mounted) fn(after, before); // onMounted後に必ず1回実行される
});
};
export default watchImmediateAfterMounted;
ちなみにonetimeWatch
を参考にしました!
https://github.com/VOICEVOX/voicevox/blob/94995bf76da3bd06169f4de128803b00ee83b5ab/src/helpers/onetimeWatch.ts
内容
PitchLine
の初期化をonMountedOrActivated
で行っていなかったので修正します。(ピッチを表示した状態でソング→トーク→ソングと切り替えるとエラーになるのを修正します)
また、以下も行います。
onMountedOrActivated
からonMounted
に変更その他