Vue CLIで作成したvueファイルの<script>ブロック内でHTMLを書いてもエラーにならない件

5月から隣の席に新入社員が座ることになり、私がOJT担当になりました。
どうしようか迷ったものの、2年間はプログラミング経験があるようなので、ひとまずVue.jsの本を渡して、Vue.jsの課題をだしてみることにしました。
もちろん、Vue.js自体は未経験だし、新人なので全然分かってないことは多いです。「分からないことがあったらいつでも質問して」と言ってみたものの、あまり積極的に質問してくる子ではないようで、進捗確認したら全然違うことを書いていたりします。自分の伝え方が悪いのか、間違ってる書き方が正しいと思って進めてるのかよく分からず、どうしたものかと困ってるところです。

それはともかく、先日、「うまく表示されなくて」と相談を受けました。その際に書いてあったのが下記のようなソースコードです。

<template>
  <div>
    <h1>Vue.js の課題</h1>
    <div v-for="(item, index) in arr" v-bind:key="index">
      <div v-html="content"></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arr: [{}, { content: <div>abcde</div> }, {}],
    };
  },
};
</script>

かなり実際の課題から簡略化していますが、ようは配列の値によって表示するHTMLを変更するということをやりたいようです。いろいろツッコミどころはあるのですが、ひとまず「v-htmlは使わないで、v-ifで表示を変更するようにして」とだけ伝えておきました(「v-html=”content”」もおかしいんですがそこはあえて触れず。正しくは「v-html=”item.content”」なので)。

それより個人的に気になったのは、このコードがエラーなく動いているということ。何でこれがエラーにならないのかと不思議でなりませんでした。なぜなら、scriptブロック内にHTMLタグをそのまま書いているから。書くなら「content: ‘

abcde

‘」というように、HTMLをクォーテーションで囲まないといけないだろと。

とりあえず、このHTMLで何が生成されてるのか調べるために、mountedメソッドを下記のように記載して、コンソールに出力するようにしてみました。

export default {
  mounted() {
    console.log(<div>aiueo</div>);
  },
};

コンソールには下記のように出力されました。

仮想DOMっぽいです。そういえば、Vue.jsのドキュメントに、Render関数にJSXで書けるというようなことが書いてありますが、多分それが影響しているものと思われます(Render 関数 | Vue.js)。Render関数やJSXって今まで使ったことがなかったので、こんな書き方ができるなんて知りませんでした(書くにしても、scriptタグに「lang=”jsx”」とつけないといけないものかと)。

試しに、HTMLタグが仮想DOMのオブジェクトにコンパイルされるということは、componentsオプションに書いたらそのままコンポーネントとして使えるのかと思って書いてみました。

<template>
  <div>
    <h1>Vue.js の課題</h1>
    <aiueo></aiueo>
  </div>
</template>

<script>
export default {
  components: {
    aiueo: <div>aiueo</div>,
  },
};
</script>

結果、動きました。

どうやら、Vue CLIで作成するとデフォルトでついているBabelが、HTMLタグを仮想DOMにコンパイルしているようです。[babel.config.js]に記載されている’@vue/cli-plugin-babel/preset’という記述を削除すると、上記のコードはエラーになりました。

今後もこのような書き方をしようとは思わないですが、ちょっと驚いたのでメモとして残します。積極的には使わない方がいいと思われます。

ちなみに、Viteで作成したプロジェクトだと、「The JSX syntax extension is not currently enabled」というエラーメッセージが表示され、動きませんでした(Vue 3 + TSX (JSX) の環境作成(Vite 使用)を参考に「@vitejs/plugin-vue-jsx」というプラグインをインポートしても、エラーは消えませんでした)。

コメント

タイトルとURLをコピーしました