簡単な環境説明
- Ruby on Rails(v5)
- viewファイルはslimを使用
- Vue.js(v3)
- Typescript(vueインスタンス作成・コンポーネントのimport〜slimへの受け渡し用)
上記を使用していて、ファイルの読み込みの構成としては
tsファイルコンパイル後のjsファイル→slimファイルのbodyタグの下で読み込み
という構成で、特にvue-routerなどは使用せずにslim経由で部分的にコンポーネントを使用する形を取っている。
import { createApp } from "vue";
import ExampleComponent from "../../components/ExampleComponent.vue";
document.addEventListener("DOMContentLoaded", () => {
const app = createApp({
components: {
ExampleComponent
},
});
app.mount("#vue-app");
});
doctype html
html
body
main#vue-app
//〜中略〜
= javascript_include_tag "example.js" #example.tsがコンパイルされたもの、正確には独自タグを使用してるが今回の箇所に関わらないため割愛
example-component[
name="hoge"
:example-object=@hoge
]
// タグとして読み込む
問題
コンポーネントの読み込みなどの初期設定をしていた際、slimファイルにて、コンポーネントの呼び出しを仮置きでこんなふうにしていた。
example-component[
]
すると、いくらビルドの再実行などを行っても画像のようにタグがタグのままになっていてコンポーネントが読み込まれてくれなかった..
確認した場所
一旦コンソールを見てみると、こんな警告文が。
runtime-core.esm-bundler.js:179 [Vue warn]: Failed to resolve component: example-component
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
オプションの設定が原因なのかな?と思いvueの公式ドキュメントなどを参考に、tsファイルに以下を追記
import { createApp } from "vue";
import ExampleComponent from "../../components/ExampleComponent.vue";
document.addEventListener("DOMContentLoaded", () => {
const app = createApp({
components: {
ExampleComponent
},
});
app.config.isCustomElement = tag => tag === 'example-component' //こちらを追記
app.mount("#vue-app");
});
すると、先ほどの警告文は消えるもタグが読み込まれず...
解決法
色々と既存のうまくいってる箇所と置き換えたりなどして検証している際に、
another-component[] //改行を入れていない!
こうしている状態でうまくいっている箇所を発見。
なるほど...🥲と思い改行を削除することで、無事コンポーネントが表示された。
わかったこと、反省点
propsを渡さないとき(滅多にないが、今回のように仮に設置する場合など)は、大カッコ[]
の中に改行を入れてしまうと今回のようにコンポーネントとして読み込んでもらえないとは思わず、先に他の箇所を疑ってしまった..
(試しにpropsが渡されている状態で改行を入れてみると普通に読み込まれていたので、上記パターンでしか発生しないと理解していますが、理由がわかっていないため何かご存知の方いらっしゃいましたらコメントいただけると幸いです。)
今の構造でvueを利用するときは関連ファイルが多いし、記述しないといけないものも多いので、凡ミスには気をつけたい。
また、調査の際は面倒がらずに思い切ってうまくいっている箇所と置き換えてみるのも大切だと改めて感じた。