Quill.jsとVueのレンダリングタイミング問題をスマートに解決する方法
はじめに
Vue.jsとQuill.jsを組み合わせてリッチテキストエディタを作ると、
**「エラーになる...!」「DOMが無いって怒られる!」**という現象に遭遇した方も多いはずです。
特に以下のようなコードを書いた時に問題が起きます:
<div v-if="editable">
<div id="toolbar"></div>
</div>
<script setup>
onMounted(() => {
if (editable) {
initQuill() // ← ❗ここで「toolbarが無い」と怒られる
}
})
</script>
😱 何が起こっているのか?
Vueの v-if
は、条件がfalseのときはDOM自体を生成しません。
そのため editable
が false
だったとき、Quillが必要とする #toolbar
要素は 存在しません。
Vueが editable = true
に変わったタイミングでDOMを作り始めますが、onMounted()
の中で editable
を true
に切り替えても、まだDOMが生成されていない状態で Quill を初期化してしまうわけです。
🔥 回避法ベスト3!
✅ 1. nextTick()
を使う(公式かつVueっぽい)
onMounted(async () => {
editable.value = checkEditable() // 条件判定
if (editable.value) {
await nextTick() // DOM生成を待つ!
initQuill() // ✅ DOMがある状態で実行
}
})
メリット:
-
DOM生成完了を保証
-
Vueらしいベストプラクティス
-
v-if
のままで使えるので構造もスッキリ
✅ 2. v-show
を使って初めからDOMを描画させておく
<div v-show="editable">
<div id="toolbar"></div>
</div>
onMounted(() => {
editable.value = checkEditable()
if (editable.value) {
initQuill() // ✅ 既にDOMがあるのでOK!
}
})
メリット:
-
初期からDOMは存在しているので、Quillが怒らない
-
表示/非表示の制御だけになる
-
より直感的
注意点:
-
v-show
はdisplay: none
を使うだけなので、非表示時でもDOMはメモリに残る
✅ 3. DOMは常に出す(v-if="true"
)+クラスで隠す
<div v-if="true">
<div
id="toolbar"
:class="{ hidden: !editable }"
></div>
</div>
.hidden {
display: none;
}
メリット:
-
Quillの初期化に絶対失敗しない
-
DOMは常に出てるので問題が起きにくい
デメリット:
-
表示ロジックがCSS依存になり、ややVueっぽくなくなる
⚙️ 実際の例:Vue 3 + Quill + nextTick()
<template>
<div v-if="editable">
<div :id="'toolbar_' + messageID" class="editLeft">
<button class="ql-bold"></button>
<button class="ql-link"></button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
const editable = ref(false)
onMounted(async () => {
// editable条件を計算
editable.value = !props.threadHead.broadcastFlag || (
props.threadHead.broadcastFlag &&
props.threadHead.adminNames.includes(props.channel.myname)
)
if (editable.value) {
await nextTick()
await initQuill() // ✅ 安心して初期化!
}
})
</script>
✅ まとめ
解決方法 | 特徴 | おすすめ場面 |
---|---|---|
nextTick() |
Vue流、DOM生成後に実行 | 条件付きでDOM出す時 |
v-show |
DOMは常にあるが見た目で切り替え | Quillの初期化タイミングを安定させたい時 |
class=hidden |
DOM強制出力+CSSで制御 | 急場しのぎや複雑な構造のとき |
🚀 総評:VueとQuillをうまく付き合わせるコツ
-
Quillは DOM前提 のライブラリ
-
Vueは 再アクティブ・非同期なDOM制御
-
橋渡しが必要なのがこの「レンダリングタイミング問題」!
-
解決には
nextTick()
orv-show
が最適🧠
👋 編集ツールの導入はフロントのUX爆上がりですが、Vueとの相性を考えないとバグの温床になります。
今回のテクニックで、その地雷をスマートに回避してくださいね!✨
登録日:
更新日:
by
プログラマーこまつ