render-functions について
Vueのレンダー関数とJSXを解説するスキルです。コンポーネント出力をプログラムで制御したい開発者向けに、複雑な描画での活用法とテンプレートが適する場面を説明します。
主な機能
- 01h()による描画内容の構築
- 02レンダー関数構文としてのJSX
- 03タグ、プロパティ、子ノードの指定
- 04仮想DOM描画の制御
活用シーン
- 01複雑な条件付き描画の表現
- 02柔軟なコンポーネントライブラリの開発
- 03JSXによるコンポーネント記述
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ patternsdev/ skills --skill render-functionsインストール後、Claude Code で/render-functionsを入力して読み込まれたか確認します。
詳細
レンダー関数
目次
Vue では、Vue コンポーネントのマークアップを構築する際に、テンプレート(つまり、<template></template> 構文)を使うことが推奨されています。ただし、レンダー関数と呼ばれる機能を直接使って、コンポーネントのマークアップを構築することもできます。
Vue はビルド時に、コンポーネント用に作成したテンプレートをレンダー関数にコンパイルします。コンパイルされたこのレンダー関数によって、Vue は仮想 DOM を構成するノードの仮想表現を構築します。
使用する場面
- テンプレートディレクティブでは表現しにくい、複雑な動的レンダリングロジックが必要な場合に使用します
- 柔軟性と低レベルの制御が必要なコンポーネントライブラリの開発に役立ちます
使用しない場面
- テンプレートで対応できる場合は、テンプレートを使用します。テンプレートのほうが読みやすく、コンパイル時の最適化も利用できます
- 標準的なコンポーネントのマークアップで、
v-if、v-for、スロットによってレンダリングの要件を満たせる場合 - チームが
h()/ JSX に慣れておらず、柔軟性を得るメリットより保守コストのほうが大きい場合
使い方
h()関数に、タグ/コンポーネント、props/属性、子要素の3つの引数を渡します- 生の
h()呼び出しより読みやすい方法として、@vue/babel-plugin-jsxを使った JSX を使用します - ほとんどのアプリケーションコードでは Vue テンプレートを優先します。レンダー関数は高度なケース向けです
- Vue の JSX では
class(classNameではありません)と単一の波括弧{}を使うことを覚えておきましょう
詳細
レンダー関数を使うと、Vue がテンプレートをコンパイルするために行うコンパイル手順を省略でき、プログラムによる JavaScript を使ってコンポーネントのテンプレートを構築できます。
ただし、なぜ使うのでしょうか?
標準的なテンプレート構文では実現しにくい、より高度なカスタマイズ性と柔軟性が必要なときに、レンダー関数が役立ちます。簡単に言うと、次のような場合にレンダー関数を使うとよいでしょう。
- テンプレート内では表現が煩雑になりがちな複雑なロジックに基づいて、コンポーネントや要素を動的にレンダリングする必要がある場合。
- 高度な操作を行うため、仮想 DOM を直接操作したい場合。
- コンポーネントのテンプレートを構築するために JSX を使いたい場合。
こうした特別なケース以外では、コンポーネントのマークアップを構築する方法として、引き続き Vue のテンプレート構文を第一に選びましょう。
レンダー関数
<div> 要素が <header> 要素を内包する次のコンポーネントがあるとします。<header> 要素のテキストには、message prop の値が表示されます。
<template>
<div class="render-card">
<header class="card-header card-header-title">{{ message }}</header>
</div>
</template>
<script setup>
const { message } = defineProps(["message"]);
</script>
レンダー関数、つまり h() 関数を使って、コンポーネントのマークアップを段階的に再現してみましょう。
h は hyperscript の略です。仮想 DOM の実装でよく使われる用語で、HTML を生成する JavaScript 構文を指します。簡単に言うと、h() 関数は、Vue が追跡し、その後ページにレンダリングする DOM ノードの「仮想」表現を作成するレンダー関数です。
h() 関数には、次の3つの引数を渡します。
- HTML タグ名またはコンポーネント定義。
- 要素に渡す props/属性(イベントリスナー、クラス属性など)。
- 親ノードの子ノード。
レンダー関数を使った完全な例は次のとおりです。
<template>
<render />
</template>
<script setup>
import { h } from "vue";
const { message } = defineProps(["message"]);
const render = () => {
return h(
"div",
{
class: "render-card",
},
[
h(
"header",
{
class: "card-header card-header-title",
},
message
),
]
);
};
</script>
これで、親の App.vue インスタンスで上記のコンポーネントをレンダリングし、message prop に "Hello World!" を渡せます。
<template>
<RenderComponent message="Hello world!" />
</template>
<script setup>
import RenderComponent from "./components/RenderComponent.vue";
</script>
レンダー関数で構築したコンポーネントは、テンプレートで構築した同等のコンポーネントとまったく同じ出力を生成します。
JSX
JSX は、JavaScript 内で HTML のようなコードを記述できる構文拡張です。Vue では、レンダー関数を構築する際に、h() 関数の代わりとして JSX を使用できます。
Vue の JSX サポートは、React のように組み込まれていません。JSX コードを適切な h() 関数の呼び出しに変換するには、専用の Babel プラグイン — @vue/babel-plugin-jsx — を使用する必要があります。
以前に作成したものと同じレンダー関数コンポーネントを、今度は JSX で作成した例を示します。
<script setup>
const { message } = defineProps(["message"]);
const render = () => {
return (
<div class="render-card">
<header class="card-header card-header-title">{message}</header>
</div>
);
};
</script>
JSX は HTML よりも JavaScript に近いため、Vue の JSX コンポーネントでは className ではなく class を使用し、変数は二重波括弧 {{ }} ではなく、1 組の波括弧 {} で埋め込みます。
レンダー関数を使用する場面
- コンポーネントに、テンプレートディレクティブでは表現しにくい複雑な条件付きレンダリングロジックがある場合、レンダー関数(JSX の有無を問わず)を使うと、よりすっきりと記述できます。
- 仮想 DOM をより直接的に制御したい場合。
- 柔軟性と低レベルの制御が必要なライブラリ/コンポーネントキットの開発。
一般的なアプリケーション開発では、Vue のテンプレートが適切な表現力と可読性を備えています。テンプレートでは不十分な場合に、レンダー関数と JSX が役立ちます。