<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ブログサイトの立ち上げ方 &#8211; ちょいプラ素材</title>
	<atom:link href="https://vitorec.co.jp/choi-plus-sozai/category/%e3%83%96%e3%83%ad%e3%82%b0%e3%82%b5%e3%82%a4%e3%83%88%e3%81%ae%e7%ab%8b%e3%81%a1%e4%b8%8a%e3%81%92%e6%96%b9/feed/" rel="self" type="application/rss+xml" />
	<link>https://vitorec.co.jp/choi-plus-sozai</link>
	<description>趣味や日々のコトを通して，見つけたモノや出会ったヒト，出かけたトコロを紹介するブログです．</description>
	<lastBuildDate>Mon, 20 Apr 2026 22:54:21 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2024/08/choi-plus-sozai-favicon-150x150.jpg</url>
	<title>ブログサイトの立ち上げ方 &#8211; ちょいプラ素材</title>
	<link>https://vitorec.co.jp/choi-plus-sozai</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>世界トップクラスのコーディング性能の「Claude Sonnet 4.5」を試してみる</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/%e4%b8%96%e7%95%8c%e3%83%88%e3%83%83%e3%83%97%e3%82%af%e3%83%a9%e3%82%b9%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%87%e3%82%a3%e3%83%b3%e3%82%b0%e6%80%a7%e8%83%bd%e3%81%ae%e3%80%8cclaude-sonnet-4-5%e3%80%8d/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/%e4%b8%96%e7%95%8c%e3%83%88%e3%83%83%e3%83%97%e3%82%af%e3%83%a9%e3%82%b9%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%87%e3%82%a3%e3%83%b3%e3%82%b0%e6%80%a7%e8%83%bd%e3%81%ae%e3%80%8cclaude-sonnet-4-5%e3%80%8d/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sun, 07 Dec 2025 13:37:03 +0000</pubDate>
				<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<category><![CDATA[日々のコト]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=14817</guid>

					<description><![CDATA[目次 世界トップクラスのコーディング性能の「Claude Opus 4.5」「Claude Sonnet 4.5」を使ってみる標準偏差の信頼度とサンプル数の関係日本の人口ピラミッドまとめ 世界トップクラスのコーディング性 [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">世界トップクラスのコーディング性能の「Claude Opus 4.5」</a></li><li><a href="#toc2" tabindex="0">「Claude Sonnet 4.5」を使ってみる</a><ol><li><a href="#toc3" tabindex="0">標準偏差の信頼度とサンプル数の関係</a></li><li><a href="#toc4" tabindex="0">日本の人口ピラミッド</a></li></ol></li><li><a href="#toc5" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">世界トップクラスのコーディング性能の「Claude Opus 4.5」</span></h2>



<p>2025年11月24日（アメリカ時間）にリリースされたAnthropicの「Claude Opus 4.5」は、世界トップクラスのコーディング性能を誇っているようです。<br>実際のGitHubの問題を解決する「SWE-bench」で史上初の80%超え（80.9%）を達成し、GPT-5.1やGemini 3 Proを凌駕しました。<br>「SWE-bench」が80%超えの82.0%になるのは、parallel test-time compute使用時のようで、基本スコアは77.2%です。</p>



<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench.webp"><img fetchpriority="high" decoding="async" width="1680" height="945" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench.webp" alt="" class="wp-image-14821" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench.webp 1680w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-500x281.webp 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-800x450.webp 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-300x169.webp 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-768x432.webp 768w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-1536x864.webp 1536w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-120x68.webp 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-160x90.webp 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/SWE-bench-320x180.webp 320w" sizes="(max-width: 1680px) 100vw, 1680px" /></a></figure>



<p>以下の記事では、Googleの「Gemini 3」で画像を生成してみました。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together">

<a href="https://vitorec.co.jp/choi-plus-sozai/%e6%9c%80%e6%96%b0%e3%81%ae%e9%ab%98%e6%80%a7%e8%83%bdai%e3%83%a2%e3%83%87%e3%83%ab%e3%80%8cgemini-3%e3%80%8d%e3%82%92%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/" title="最新の高性能AIモデル「Gemini 3」を試してみる" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-160x90.jpg" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-160x90.jpg 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-120x68.jpg 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-320x180.jpg 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">最新の高性能AIモデル「Gemini 3」を試してみる</div><div class="blogcard-snippet internal-blogcard-snippet">最新の高性能AIモデルがリリースされたというニュースを目にしたので試しに「Gemini 3」を使ってみました。この記事のアイキャッチ画像も「Gemini 3」が生成した画像です。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2026.04.21</div></div></div></div></a>
</div>



<p>これに続いて「Claude Sonnet 4.5」の能力を試してみます。</p>



<h2 class="wp-block-heading"><span id="toc2">「Claude Sonnet 4.5」を使ってみる</span></h2>



<p>「Claude Opus 4.5」は無料で使えないので、ブラウザから無料で使える「Claude Sonnet 4.5」を使ってみました。<br><br><a rel="noopener noreferrer" href="https://claude.ai/" target="_blank">claude.ai<span class="fa fa-external-link external-icon anchor-icon"></span></a>のトップページにアクセスしてアカウントを作れば、すぐに使えるようになります。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-official">

<a rel="noopener noreferrer" href="https://claude.ai/" title="Just a moment..." class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fclaude.ai%2F?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Just a moment...</div><div class="blogcard-snippet external-blogcard-snippet"></div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://claude.ai/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">claude.ai</div></div></div></div></a>
</div>



<h3 class="wp-block-heading"><span id="toc3">標準偏差の信頼度とサンプル数の関係</span></h3>



<p>長年仕事をしてきた中で、ずっと知りたかったことがあります。</p>



<p>いろいろな測定をするとき、N個のサンプルデータから、標準偏差σを計算して、母集団のバラつき具合を評価することがあります。</p>



<p>「それなりに信頼できる標準偏差σを計算するには、サンプル数は、いくつ以上必要なんだろう？」</p>



<p>私は今まで、先輩に言われた、</p>



<p>「最低でも20個、できれば30個以上は必要。」</p>



<p>という教えを信じて、20個～30個の測定データを使ってきました。</p>



<p>この機会に「標準偏差の信頼度とサンプル数の関係」を「Claude Sonnet 4.5」に聞いてみました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>データサンプル数N個のデータでσを計算します。<br>N数が増えるほどσの信頼度が上がると考えていますが、間違いないですか？</p>
</div></div>



<p>「Claude Sonnet 4.5」の回答は当然</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-21 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#fff7cc;--cocoon-custom-border-color:#fcb900"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Claude-Sonnet-4.5.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-yellow-background-color has-luminous-vivid-amber-border-color">
<p>はい、その理解は正しいです。サンプル数Nが増えるほど、標準偏差σ（母標準偏差の推定値）の信頼度は上がります。</p>
</div></div>



<p>でした。<br>さらに、長年知りたかった標準偏差σの誤差の式も教えてくれました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-21 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#fff7cc;--cocoon-custom-border-color:#fcb900"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Claude-Sonnet-4.5.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-yellow-background-color has-luminous-vivid-amber-border-color">
<p>標準偏差の推定値自体にもばらつき（標準誤差）があります。<br>母標準偏差をσ、サンプルサイズをNとすると、標準偏差の推定値の標準誤差は近似的に:<br><strong>σ / √(2N)</strong><br>となります。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>上記の標準偏差の誤差を縦軸、N数を横軸にしたグラフを作ってください。</p>
</div></div>



<p>と追加でお願いすると、あっという間にグラフ描画のプログラムコードを生成し、グラフを表示してくれました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>このグラフを描くのに使ったプログラムコードを見せてください。</p>
</div></div>



<p>とお願いしてプログラムコードを見ると、reactベースのプログラムコードでした。<br>私は、reactのスキルがないので、</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>単純なHTML/JavaScriptでグラフを描きたいので、Chart.jsを使ったバージョンを作成してください。<br>Vue3も使ったコードにして欲しい。</p>
</div></div>



<p>とお願いしました。<br>すると、数十秒後に、</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-21 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#fff7cc;--cocoon-custom-border-color:#fcb900"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Claude-Sonnet-4.5.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-yellow-background-color has-luminous-vivid-amber-border-color">
<p>Chart.jsとVue3を使ったバージョンを作成しました！</p>
</div></div>



<p>と伝えてきて、以下のプログラムコードを提示してくれました。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;標準偏差の標準誤差とサンプル数の関係 (Vue3版)&lt;/title&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.prod.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        body {
            font-family: &#39;Arial&#39;, sans-serif;
            background-color: #f3f4f6;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            padding: 20px;
        }
        .container {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            padding: 30px;
            max-width: 900px;
            width: 100%;
        }
        h1 {
            text-align: center;
            color: #1f2937;
            margin-bottom: 10px;
            font-size: 24px;
        }
        .subtitle {
            text-align: center;
            color: #6b7280;
            margin-bottom: 30px;
            font-size: 14px;
        }
        .info-box {
            margin-top: 20px;
            padding: 15px;
            background-color: #f9fafb;
            border-radius: 6px;
            font-size: 14px;
            color: #4b5563;
        }
        .info-box p {
            margin: 0 0 10px 0;
            font-weight: bold;
        }
        .info-box ul {
            margin: 0;
            padding-left: 20px;
        }
        .info-box li {
            margin: 5px 0;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=&quot;app&quot;&gt;
        &lt;div class=&quot;container&quot;&gt;
            &lt;h1&gt;{{ title }}&lt;/h1&gt;
            &lt;p class=&quot;subtitle&quot;&gt;{{ subtitle }}&lt;/p&gt;
            
            &lt;canvas ref=&quot;chartCanvas&quot;&gt;&lt;/canvas&gt;
            
            &lt;div class=&quot;info-box&quot;&gt;
                &lt;p&gt;グラフから読み取れること:&lt;/p&gt;
                &lt;ul&gt;
                    &lt;li v-for=&quot;(info, index) in infoList&quot; :key=&quot;index&quot;&gt;{{ info }}&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        const { createApp, ref, onMounted } = Vue;

        createApp({
            setup() {
                const title = ref(&#39;標準偏差の標準誤差とサンプル数の関係&#39;);
                const subtitle = ref(&#39;標準誤差 = σ / √(2N)　（σ = 1 の場合）&#39;);
                const chartCanvas = ref(null);
                const infoList = ref([
                    &#39;N数が少ない時は標準誤差が大きく、推定精度が低い&#39;,
                    &#39;N数が増えるにつれて標準誤差は急速に減少する&#39;,
                    &#39;N数が大きくなると、誤差の減少は緩やかになる（√の効果）&#39;
                ]);

                const generateData = () =&gt; {
                    const labels = [];
                    const data = [];
                    
                    for (let n = 1; n &lt;= 1000; n += 5) {
                        // σ = 1 と仮定した場合の標準誤差
                        const standardError = 1 / Math.sqrt(2 * n);
                        labels.push(n);
                        data.push(standardError);
                    }
                    
                    return { labels, data };
                };

                const createChart = () =&gt; {
                    const { labels, data } = generateData();
                    const ctx = chartCanvas.value.getContext(&#39;2d&#39;);
                    
                    new Chart(ctx, {
                        type: &#39;line&#39;,
                        data: {
                            labels: labels,
                            datasets: [{
                                label: &#39;標準誤差&#39;,
                                data: data,
                                borderColor: &#39;#3b82f6&#39;,
                                backgroundColor: &#39;rgba(59, 130, 246, 0.1)&#39;,
                                borderWidth: 2,
                                pointRadius: 0,
                                tension: 0.1
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: true,
                            aspectRatio: 2,
                            plugins: {
                                legend: {
                                    display: true,
                                    position: &#39;top&#39;
                                },
                                tooltip: {
                                    callbacks: {
                                        title: function(context) {
                                            return &#39;N = &#39; + context[0].label;
                                        },
                                        label: function(context) {
                                            return &#39;標準誤差: &#39; + context.parsed.y.toFixed(4);
                                        }
                                    }
                                }
                            },
                            scales: {
                                x: {
                                    title: {
                                        display: true,
                                        text: &#39;サンプル数 (N)&#39;,
                                        font: {
                                            size: 14
                                        }
                                    },
                                    ticks: {
                                        maxTicksLimit: 10
                                    }
                                },
                                y: {
                                    title: {
                                        display: true,
                                        text: &#39;標準誤差&#39;,
                                        font: {
                                            size: 14
                                        }
                                    },
                                    beginAtZero: true
                                }
                            }
                        }
                    });
                };

                onMounted(() =&gt; {
                    createChart();
                });

                return {
                    title,
                    subtitle,
                    chartCanvas,
                    infoList
                };
            }
        }).mount(&#39;#app&#39;);
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></div>



<p>このコードの利点として、以下の説明がありました。</p>



<ul class="wp-block-list">
<li>純粋なHTML/JavaScriptで動作（Reactは不要）</li>



<li>ブラウザで直接開くだけで動作</li>



<li>Chart.jsはCDNから読み込むので、インストール不要</li>
</ul>



<p>ということで、この投稿にWordPressのブロックエディタで「カスタムHTML」ブロックを配置し、上記のHTMLのコードを貼り付けてみます。</p>



<p>どうでしょう？<br>以下にグラフが表示されていますよね。</p>



<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>標準偏差の標準誤差とサンプル数の関係 (Vue3版)</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.prod.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            background-color: #f3f4f6;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            /*padding: 20px;*/
        }
        .container {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            /*padding: 30px;*/
            /*max-width: 900px;*/
            width: 100%;
        }
        h1 {
            text-align: center;
            color: #1f2937;
            margin-bottom: 10px;
            font-size: 24px;
        }
        .subtitle {
            text-align: center;
            color: #6b7280;
            margin-bottom: 30px;
            font-size: 14px;
        }
        .info-box {
            margin-top: 20px;
            padding: 15px;
            background-color: #f9fafb;
            border-radius: 6px;
            font-size: 14px;
            color: #4b5563;
        }
        .info-box p {
            margin: 0 0 10px 0;
            font-weight: bold;
        }
        .info-box ul {
            margin: 0;
            padding-left: 20px;
        }
        .info-box li {
            margin: 5px 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="container">
            <h1>{{ title }}</h1>
            <p class="subtitle">{{ subtitle }}</p>
            
            <canvas ref="chartCanvas"></canvas>
            
            <div class="info-box">
                <p>グラフから読み取れること:</p>
                <ul>
                    <li v-for="(info, index) in infoList" :key="index">{{ info }}</li>
                </ul>
            </div>
        </div>
    </div>

    <script>
        const { createApp, ref, onMounted } = Vue;

        createApp({
            setup() {
                const title = ref('標準偏差の標準誤差とサンプル数の関係');
                const subtitle = ref('標準誤差 = σ / √(2N)　（σ = 1 の場合）');
                const chartCanvas = ref(null);
                const infoList = ref([
                    'N数が少ない時は標準誤差が大きく、推定精度が低い',
                    'N数が増えるにつれて標準誤差は急速に減少する',
                    'N数が大きくなると、誤差の減少は緩やかになる（√の効果）'
                ]);

                const generateData = () => {
                    const labels = [];
                    const data = [];
                    
                    for (let n = 1; n <= 1000; n += 5) {
                        // σ = 1 と仮定した場合の標準誤差
                        const standardError = 1 / Math.sqrt(2 * n);
                        labels.push(n);
                        data.push(standardError);
                    }
                    
                    return { labels, data };
                };

                const createChart = () => {
                    const { labels, data } = generateData();
                    const ctx = chartCanvas.value.getContext('2d');
                    
                    new Chart(ctx, {
                        type: 'line',
                        data: {
                            labels: labels,
                            datasets: [{
                                label: '標準誤差',
                                data: data,
                                borderColor: '#3b82f6',
                                backgroundColor: 'rgba(59, 130, 246, 0.1)',
                                borderWidth: 2,
                                pointRadius: 0,
                                tension: 0.1
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: true,
                            aspectRatio: 2,
                            plugins: {
                                legend: {
                                    display: true,
                                    position: 'top'
                                },
                                tooltip: {
                                    callbacks: {
                                        title: function(context) {
                                            return 'N = ' + context[0].label;
                                        },
                                        label: function(context) {
                                            return '標準誤差: ' + context.parsed.y.toFixed(4);
                                        }
                                    }
                                }
                            },
                            scales: {
                                x: {
                                    title: {
                                        display: true,
                                        text: 'サンプル数 (N)',
                                        font: {
                                            size: 14
                                        }
                                    },
                                    ticks: {
                                        maxTicksLimit: 10
                                    }
                                },
                                y: {
                                    title: {
                                        display: true,
                                        text: '標準誤差',
                                        font: {
                                            size: 14
                                        }
                                    },
                                    beginAtZero: true
                                }
                            }
                        }
                    });
                };

                onMounted(() => {
                    createChart();
                });

                return {
                    title,
                    subtitle,
                    chartCanvas,
                    infoList
                };
            }
        }).mount('#app');
    </script>
</body>
</html>



<p><strong>グラフから読み取れること</strong>の内容も「Claude Sonnet 4.5」が自動で付けてくれています。<br>さすがのコーディング性能ですね。</p>



<p>ただし、元々のWordPressのスタイルが崩れるので、bodyと.containerのCSSの一部は、以下のようにコメントアウトしています（グレー部分）。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-css" data-lang="CSS"><code>        body {
            font-family: &#39;Arial&#39;, sans-serif;
            background-color: #f3f4f6;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            /*padding: 20px;*/
        }
        .container {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            /*padding: 30px;*/
            /*max-width: 900px;*/
            width: 100%;
        }</code></pre></div>



<h3 class="wp-block-heading"><span id="toc4">日本の人口ピラミッド</span></h3>



<p>次に、以下のプロンプトで日本の人口ピラミッドのグラフを作ってみます。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>日本の人口ピラミッドのグラフをJavaScriptで作って欲しい。</p>



<ul class="wp-block-list">
<li>グラフライブラリーはChart.jsを使う。</li>



<li>5歳刻みで年齢階級を表示する。</li>



<li>0-4歳が一番下に配置され、上に向かって高齢にする。</li>



<li>左側に男性（青色）、右側に女性（ピンク色）を表示する。</li>



<li>男性と女性のバーを同じ高さで揃える。</li>
</ul>
</div></div>



<p>WordPressの同じ投稿ページにVue3のインスタンスが2つあると厄介なので、こちらのグラフではVue3を使っていません。</p>



<p>「Claude Sonnet 4.5」は、日本の人口情報を検索/取得した後、以下のプログラムコードを生成してくれました。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;日本の人口ピラミッド 2024&lt;/title&gt;
    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        body {
            font-family: &#39;Helvetica Neue&#39;, Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background: #f5f5f5;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        .container {
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            padding: 30px;
            max-width: 1200px;
            width: 100%;
        }
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 10px;
            font-size: 28px;
        }
        .subtitle {
            text-align: center;
            color: #666;
            margin-bottom: 30px;
            font-size: 14px;
        }
        #chartContainer {
            position: relative;
            height: 700px;
            margin: 0 auto;
        }
        .source {
            text-align: center;
            color: #999;
            font-size: 12px;
            margin-top: 20px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;h1&gt;日本の人口ピラミッド&lt;/h1&gt;
        &lt;div class=&quot;subtitle&quot;&gt;2024年10月1日現在（総人口：約1億2,380万人）&lt;/div&gt;
        &lt;div id=&quot;chartContainer&quot;&gt;
            &lt;canvas id=&quot;pyramidChart&quot;&gt;&lt;/canvas&gt;
        &lt;/div&gt;
        &lt;div class=&quot;source&quot;&gt;出典：総務省統計局「人口推計」2024年10月1日現在データに基づく&lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // 2024年の日本の人口データ（5歳刻み、単位：万人）
        // 総人口推計に基づく近似値
        // 0歳を下にするため、配列は逆順（高齢→若年）で定義
        const ageGroups = [
            &#39;90歳以上&#39;,
            &#39;85-89歳&#39;,
            &#39;80-84歳&#39;,
            &#39;75-79歳&#39;,
            &#39;70-74歳&#39;,
            &#39;65-69歳&#39;,
            &#39;60-64歳&#39;,
            &#39;55-59歳&#39;,
            &#39;50-54歳&#39;,
            &#39;45-49歳&#39;,
            &#39;40-44歳&#39;,
            &#39;35-39歳&#39;,
            &#39;30-34歳&#39;,
            &#39;25-29歳&#39;,
            &#39;20-24歳&#39;,
            &#39;15-19歳&#39;,
            &#39;10-14歳&#39;,
            &#39;5-9歳&#39;,
            &#39;0-4歳&#39;
        ];

        // 男性人口（左側、負の値で表示）
        const malePopulation = [
            -85,   // 90+
            -161,  // 85-89
            -279,  // 80-84
            -376,  // 75-79
            -442,  // 70-74
            -489,  // 65-69
            -470,  // 60-64
            -388,  // 55-59
            -413,  // 50-54
            -464,  // 45-49
            -426,  // 40-44
            -375,  // 35-39
            -332,  // 30-34
            -315,  // 25-29
            -299,  // 20-24
            -280,  // 15-19
            -257,  // 10-14
            -239,  // 5-9
            -222   // 0-4
        ];

        // 女性人口（右側、正の値で表示）
        const femalePopulation = [
            187,   // 90+
            249,   // 85-89
            345,   // 80-84
            418,   // 75-79
            463,   // 70-74
            495,   // 65-69
            469,   // 60-64
            384,   // 55-59
            408,   // 50-54
            459,   // 45-49
            422,   // 40-44
            369,   // 35-39
            322,   // 30-34
            303,   // 25-29
            285,   // 20-24
            266,   // 15-19
            244,   // 10-14
            227,   // 5-9
            211    // 0-4
        ];

        const ctx = document.getElementById(&#39;pyramidChart&#39;).getContext(&#39;2d&#39;);
        
        const pyramidChart = new Chart(ctx, {
            type: &#39;bar&#39;,
            data: {
                labels: ageGroups,
                datasets: [
                    {
                        label: &#39;男性&#39;,
                        data: malePopulation,
                        backgroundColor: &#39;rgba(54, 162, 235, 0.7)&#39;,
                        borderColor: &#39;rgba(54, 162, 235, 1)&#39;,
                        borderWidth: 1
                    },
                    {
                        label: &#39;女性&#39;,
                        data: femalePopulation,
                        backgroundColor: &#39;rgba(255, 99, 132, 0.7)&#39;,
                        borderColor: &#39;rgba(255, 99, 132, 1)&#39;,
                        borderWidth: 1
                    }
                ]
            },
            options: {
                indexAxis: &#39;y&#39;,
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    title: {
                        display: false
                    },
                    legend: {
                        display: true,
                        position: &#39;top&#39;,
                        labels: {
                            font: {
                                size: 14
                            }
                        }
                    },
                    tooltip: {
                        callbacks: {
                            label: function(context) {
                                let label = context.dataset.label || &#39;&#39;;
                                if (label) {
                                    label += &#39;: &#39;;
                                }
                                const value = Math.abs(context.parsed.x);
                                label += value.toFixed(0) + &#39;万人&#39;;
                                return label;
                            }
                        }
                    }
                },
                scales: {
                    x: {
                        stacked: false,
                        ticks: {
                            callback: function(value) {
                                return Math.abs(value) + &#39;万人&#39;;
                            },
                            font: {
                                size: 12
                            }
                        },
                        grid: {
                            color: &#39;rgba(0, 0, 0, 0.05)&#39;
                        }
                    },
                    y: {
                        stacked: true,
                        position: &#39;left&#39;,
                        ticks: {
                            font: {
                                size: 12
                            }
                        },
                        grid: {
                            display: false
                        }
                    }
                }
            }
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></div>



<p>このプログラムコードをWordPressの「カスタムHTML」ブロックに貼り付けてグラフを表示します。</p>



<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>日本の人口ピラミッド 2024</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
    <style>
        body {
            font-family: 'Helvetica Neue', Arial, sans-serif;
            margin: 0;
            /*padding: 20px;*/
            background: #f5f5f5;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        .container {
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            /*padding: 30px;*/
            /*max-width: 1200px;*/
            width: 100%;
        }
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 10px;
            font-size: 28px;
        }
        .subtitle {
            text-align: center;
            color: #666;
            margin-bottom: 30px;
            font-size: 14px;
        }
        #chartContainer {
            position: relative;
            height: 700px;
            margin: 0 auto;
        }
        .source {
            text-align: center;
            color: #999;
            font-size: 12px;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>日本の人口ピラミッド</h1>
        <div class="subtitle">2024年10月1日現在（総人口：約1億2,380万人）</div>
        <div id="chartContainer">
            <canvas id="pyramidChart"></canvas>
        </div>
        <div class="source">出典：総務省統計局「人口推計」2024年10月1日現在データに基づく</div>
    </div>

    <script>
        // 2024年の日本の人口データ（5歳刻み、単位：万人）
        // 総人口推計に基づく近似値
        // 0歳を下にするため、配列は逆順（高齢→若年）で定義
        const ageGroups = [
            '90歳以上',
            '85-89歳',
            '80-84歳',
            '75-79歳',
            '70-74歳',
            '65-69歳',
            '60-64歳',
            '55-59歳',
            '50-54歳',
            '45-49歳',
            '40-44歳',
            '35-39歳',
            '30-34歳',
            '25-29歳',
            '20-24歳',
            '15-19歳',
            '10-14歳',
            '5-9歳',
            '0-4歳'
        ];

        // 男性人口（左側、負の値で表示）
        const malePopulation = [
            -85,   // 90+
            -161,  // 85-89
            -279,  // 80-84
            -376,  // 75-79
            -442,  // 70-74
            -489,  // 65-69
            -470,  // 60-64
            -388,  // 55-59
            -413,  // 50-54
            -464,  // 45-49
            -426,  // 40-44
            -375,  // 35-39
            -332,  // 30-34
            -315,  // 25-29
            -299,  // 20-24
            -280,  // 15-19
            -257,  // 10-14
            -239,  // 5-9
            -222   // 0-4
        ];

        // 女性人口（右側、正の値で表示）
        const femalePopulation = [
            187,   // 90+
            249,   // 85-89
            345,   // 80-84
            418,   // 75-79
            463,   // 70-74
            495,   // 65-69
            469,   // 60-64
            384,   // 55-59
            408,   // 50-54
            459,   // 45-49
            422,   // 40-44
            369,   // 35-39
            322,   // 30-34
            303,   // 25-29
            285,   // 20-24
            266,   // 15-19
            244,   // 10-14
            227,   // 5-9
            211    // 0-4
        ];

        const ctx = document.getElementById('pyramidChart').getContext('2d');
        
        const pyramidChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: ageGroups,
                datasets: [
                    {
                        label: '男性',
                        data: malePopulation,
                        backgroundColor: 'rgba(54, 162, 235, 0.7)',
                        borderColor: 'rgba(54, 162, 235, 1)',
                        borderWidth: 1
                    },
                    {
                        label: '女性',
                        data: femalePopulation,
                        backgroundColor: 'rgba(255, 99, 132, 0.7)',
                        borderColor: 'rgba(255, 99, 132, 1)',
                        borderWidth: 1
                    }
                ]
            },
            options: {
                indexAxis: 'y',
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    title: {
                        display: false
                    },
                    legend: {
                        display: true,
                        position: 'top',
                        labels: {
                            font: {
                                size: 14
                            }
                        }
                    },
                    tooltip: {
                        callbacks: {
                            label: function(context) {
                                let label = context.dataset.label || '';
                                if (label) {
                                    label += ': ';
                                }
                                const value = Math.abs(context.parsed.x);
                                label += value.toFixed(0) + '万人';
                                return label;
                            }
                        }
                    }
                },
                scales: {
                    x: {
                        stacked: false,
                        ticks: {
                            callback: function(value) {
                                return Math.abs(value) + '万人';
                            },
                            font: {
                                size: 12
                            }
                        },
                        grid: {
                            color: 'rgba(0, 0, 0, 0.05)'
                        }
                    },
                    y: {
                        stacked: true,
                        position: 'left',
                        ticks: {
                            font: {
                                size: 12
                            }
                        },
                        grid: {
                            display: false
                        }
                    }
                }
            }
        });
    </script>
</body>
</html>



<p>プログラムコードを書くスキルや手間が不要になるだけでなく、必要なデータも探してきてくれるので、自分より賢い「アシスタント」か「お手伝いさん」に仕事を頼む感じです。</p>



<h2 class="wp-block-heading"><span id="toc5">まとめ</span></h2>



<p>世界トップクラスのコーディング性能を誇っている「Claude Sonnet 4.5」を試してみました。<br>当たり前ですが、私のスキルを圧倒的に超えるコーディング性能でした。</p>



<p>以下の記事で紹介した「ガントチャート」のプログラムコードをデバッグしてもらったところ、いくつかの不具合を指摘して、修正後のプログラムコードを提示してくれました。<br>早速、以下の記事のプログラムコードも修正後のコードに差し替えました。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-reference">

<a href="https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%ac%e3%83%b3%e3%83%88%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%99%e3%82%8b/" title="WordPressの投稿にガントチャートを実装する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">WordPressの投稿にガントチャートを実装する</div><div class="blogcard-snippet internal-blogcard-snippet">「frappe-gantt」を独自に機能拡張したJavaScriptライブラリを作成し、WordPressの投稿にガントチャートを実装しました。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2023.11.12</div></div></div></div></a>
</div>



<p>前回の「Gemini 3」も、今回紹介した「Claude Sonnet 4.5」も、実際に試して感じたことは、</p>



<p><strong><span class="fz-22px"><span class="fz-20px">　AIを毛嫌いしている状況ではなくなっている。</span></span></strong></p>



<p>　<strong><span class="fz-22px"><span class="fz-20px">AIを賢く使いこなす人や組織が、ますます賢くて強くなる。</span></span></strong></p>



<p>です。</p>



<p>皆さんも実際に試してみてください。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/%e4%b8%96%e7%95%8c%e3%83%88%e3%83%83%e3%83%97%e3%82%af%e3%83%a9%e3%82%b9%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%87%e3%82%a3%e3%83%b3%e3%82%b0%e6%80%a7%e8%83%bd%e3%81%ae%e3%80%8cclaude-sonnet-4-5%e3%80%8d/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>最新の高性能AIモデル「Gemini 3」を試してみる</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/%e6%9c%80%e6%96%b0%e3%81%ae%e9%ab%98%e6%80%a7%e8%83%bdai%e3%83%a2%e3%83%87%e3%83%ab%e3%80%8cgemini-3%e3%80%8d%e3%82%92%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/%e6%9c%80%e6%96%b0%e3%81%ae%e9%ab%98%e6%80%a7%e8%83%bdai%e3%83%a2%e3%83%87%e3%83%ab%e3%80%8cgemini-3%e3%80%8d%e3%82%92%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sun, 07 Dec 2025 11:43:13 +0000</pubDate>
				<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<category><![CDATA[日々のコト]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=14807</guid>

					<description><![CDATA[目次 最新の高性能AIモデルが続々とリリース「Gemini 3」を使ってみるアイキャッチ画像の生成リアルな画像も生成できる世界地図Google Antigravity3Dオセロゲーム3Dモデルデータバイブコーディング（V [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-4" checked><label class="toc-title" for="toc-checkbox-4">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">最新の高性能AIモデルが続々とリリース</a></li><li><a href="#toc2" tabindex="0">「Gemini 3」を使ってみる</a><ol><li><a href="#toc3" tabindex="0">アイキャッチ画像の生成</a></li><li><a href="#toc4" tabindex="0">リアルな画像も生成できる</a></li><li><a href="#toc5" tabindex="0">世界地図</a></li></ol></li><li><a href="#toc6" tabindex="0">Google Antigravity</a><ol><li><a href="#toc7" tabindex="0">3Dオセロゲーム</a></li><li><a href="#toc8" tabindex="0">3Dモデルデータ</a></li><li><a href="#toc9" tabindex="0">バイブコーディング（Vibe Coding）</a></li></ol></li><li><a href="#toc10" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">最新の高性能AIモデルが続々とリリース</span></h2>



<p>2025年11月は、最新の高性能AIモデルが続々とリリースされました。</p>



<p>まずは、Googleの「Gemini 3」が、2025年11月18日（アメリカ時間）にリリースされました。<br>これを受けて、OpenAIのサム・アルトマンCEOが社内向けに「コード・レッド（緊急事態）」を宣言したとのニュースも流れています。</p>



<p>間髪を入れず、2025年11月24日（アメリカ時間）に、Anthropicが「Claude Opus 4.5」をリリースしました。</p>



<p>どちらも、</p>



<ul class="wp-block-list">
<li>複雑な推論能力</li>



<li>高度なコーディング能力</li>



<li>エージェント機能（自律的にタスクを実行する）</li>



<li>低ハルシネーション（正確性の向上）</li>



<li>マルチモーダル（テキスト/画像/音声/動画などの色々な情報をシームレスに扱える）</li>
</ul>



<p>を売りにしています。</p>



<p>私は、今まで、AIを積極的に使ってきませんでしたが、最新の高性能AIモデルを試してみることにします。</p>



<h2 class="wp-block-heading"><span id="toc2">「Gemini 3」を使ってみる</span></h2>



<p>「Gemini 3 Pro」を試したいところですが、ブラウザから無料で使える「Gemini 3」を使ってみました。</p>



<h3 class="wp-block-heading"><span id="toc3">アイキャッチ画像の生成</span></h3>



<p>「Gemini 3」は、マルチモーダルの機能が向上したということで、アイキャッチ画像を生成してみることにします。</p>



<p>以下のプロンプトで画像を生成してもらいました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>「Gemini 3」と「Claude Opus 4.5」と「GPT-5」が競合しているアイキャッチ画像を作って。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>アイソメトリックのイラストにして。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>背景の色は、白を基調にして。<br>カラフルな、ポスターカラーの色使いにして。</p>
</div></div>



<p>10秒ちょっとで以下の画像を生成してくれました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE.jpg"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE.jpg" alt="" class="wp-image-14809" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE.jpg 1024w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-500x500.jpg 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-800x800.jpg 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-300x300.jpg 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-768x768.jpg 768w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/THE-AI-RACE-150x150.jpg 150w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>
</div></div>



<p>この画像をこの記事のアイキャッチ画像として使っています。</p>



<p>「THE AI RACE」というタイトルもキャッチーだし、「Gemini 3」が先頭を走っているところも手前味噌でしたたかですね。</p>



<h3 class="wp-block-heading"><span id="toc4">リアルな画像も生成できる</span></h3>



<p>もっとリアルな画像も生成できます。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>夕日に染まる富士山を背景に、キャンピングカー「TOY'S BOX 470H」で、海辺でキャンプをしている画像を作って。</p>
</div></div>



<p>とお願いしましたが、私の「TOY'S BOX 470H」と違うバンコンのキャンピングカーだったので、次のように画像をアップして、</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<figure class="wp-block-image size-medium"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881.jpg"><img loading="lazy" decoding="async" width="500" height="281" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-500x281.jpg" alt="" class="wp-image-14267" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-500x281.jpg 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-800x450.jpg 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-300x169.jpg 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-768x432.jpg 768w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-1536x864.jpg 1536w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-2048x1152.jpg 2048w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-120x68.jpg 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-160x90.jpg 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/07/58917f32c6241e15577cb05a2f77d881-320x180.jpg 320w" sizes="(max-width: 500px) 100vw, 500px" /></a></figure>



<p>「TOY'S BOX 470H」の画像はこれです。<br>キャンピングカーの画像を差し替えて。</p>
</div></div>



<p>と修正をお願いしました。</p>



<p>すると、以下のような完璧な画像を作ってくれました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b.jpg"><img loading="lazy" decoding="async" width="1344" height="768" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b.jpg" alt="" class="wp-image-14810" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b.jpg 1344w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b-500x286.jpg 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b-800x457.jpg 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b-300x171.jpg 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b-768x439.jpg 768w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b-120x68.jpg 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/23285bd253fd634c5cb7aaccf151414b-160x90.jpg 160w" sizes="(max-width: 1344px) 100vw, 1344px" /></a></figure>
</div></div>



<p>夕暮れ時なので、焚き火だけでなく、「TOY'S BOX 470H」のルームライトが灯っているところなんか、最高じゃないですか？<br>ちょっと驚きです。</p>



<h3 class="wp-block-heading"><span id="toc5">世界地図</span></h3>



<p>次に、世界地図を描くプログラムコードを作ってもらいます。<br>数回のプロンプトで自分の要望を伝えていきます。</p>



<p>こちらの要望に対し、プログラムコードをどのように変更するかも提示してくれるので安心です。<br>不具合に対する修正能力も高いです。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>ミラー図法の世界地図（白地図）をJavaScriptで描くプログラムを作って。<br>地図データはNatural Earthから取得して。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>Miller Cylindrical Projection（ミラー図法）を用いて、Natural Earthのデータから世界地図を描画するJavaScriptプログラムを作成します。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>このプログラムでは、軽量で扱いやすい <strong>D3.js</strong> ライブラリを使用します。D3.jsは地図投影法の計算に非常に優れており、Natural Earthのデータを変換して描画するのに最適です。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>地図の中央を日本の経度に合わせて。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>海岸線の解像度を上げるには、Natural Earthのデータセットを 110m（低解像度）から 50m（中解像度）または 10m（高解像度）に変更します。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>ウェブブラウザでの動作速度と見た目のバランスが良い 50m 解像度を使用したコードを提示します。また、解像度が上がるとデータ量が増えるため、読み込み完了までキャンバスをクリアにする処理を含めています。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>国境線を入れて欲しい。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>国境線を追加するには、Natural Earthの「Admin 0 Countries（国の境界線）」データセットを使用します。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>以前使用した land（陸地） データは地形のみですが、admin_0_countries データを使用することで、各国の境界線を個別に描画できるようになります。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>Vue3を使ったコードに変更して。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>Vue 3 (Composition API) を使って、これまでの Miller図法の世界地図をコンポーネント化します。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Vue 3 で地図を描画する場合、<strong><code>onMounted</code> フック</strong>を使用して、DOM（Canvas）が確実に生成された後に D3.js の描画ロジックを走らせるのが一般的です。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>特定の国がホバーされたときにツールチップを出すような機能を追加して。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>Canvasでのホバー検知（Tooltip）は、SVGとは異なり、マウスの座標からどのポリゴン（国）の上にいるかをD3の投影法を使って逆算する必要があります。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>以下のコードでは、<code>mousemove</code> イベントを監視し、<code>d3.geoContains</code> を使って現在マウスの下にある国を特定し、その名前を表示する機能を追加しました。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>ツールチップの国名は日本語にして。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>国名を日本語にするには、Natural EarthのGeoJSONデータに含まれる日本語プロパティ <strong><code>NAME_JA</code></strong> を参照するようにコードを修正します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>CSSやレスポンシブ対応で地図のサイズを変更したときに、マウスのホバー位置を補正するようにして欲しい。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>地図のサイズを変更（CSSでリサイズしたり、レスポンシブ対応したり）すると、ブラウザ上の表示サイズとCanvasの内部解像度にズレが生じます。マウスの座標をそのまま <code>invert</code> に渡すと位置がズレるため、**「Canvasの内部サイズと実際の表示サイズの比率」**を使って座標を補正する必要があります。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>以下のコードでは、マウス座標を計算する際に scaleX と scaleY を導入し、表示サイズに関わらず正しく国を特定できるように修正しました。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>国名の文字数の表示に必要なツールチップの幅が確保されてないので、文字が重なってしまいます。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>原因が完全に特定できました。ツールチップの幅が固定されているか、改行の制御がなされていないために、HTML要素内で文字が溢れて（Wrapして）重なってしまっている状態です。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>CSSに <strong><code>white-space: nowrap;</code></strong>（自動改行の禁止）を追加し、さらに <strong><code>width: auto;</code></strong>（コンテンツに合わせる）を明示することで、国名がどれだけ長くても（例：「グレートブリテン及び北アイルランド連合王国」など）一行でクッキリと表示されるように修正します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>地図の陸地部分は、カラーコード#f5f5dcで塗りつぶして。<br>地図の海は、カラーコード#e0f7fa で塗りつぶして。<br>マウスでホバーした国は、カラーコード#ffa500で塗りつぶして。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>以下の要件に従い、コードを修正します。</p>



<ol start="1" class="wp-block-list">
<li><strong>陸地色</strong>: <code>#f5f5dc</code> (ベージュ / Beigewood)</li>



<li><strong>海色</strong>: <code>#e0f7fa</code> (非常に薄い青 / Pale cyan)</li>



<li><strong>ホバー色</strong>: <code>#ffa500</code> (オレンジ / Orange)</li>
</ol>



<p>ホバーした国を塗りつぶすには、<code>handleMouseMove</code> 関数内でホバーされた国を特定した後、その国をCanvasに再描画するロジックを <code>drawMap</code> 関数に追加する必要があります。合王国」など）一行でクッキリと表示されるように修正します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>地図の緯度線/経度線は消して。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>地図の描画ロジックから緯度線/経度線（Graticule）の描画処理を削除します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>このVue3のコンポーネントをブラウザで直接実行できるにhtmlファイルにして欲しい。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-20 sbs-flat sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-border-color:#abb8c3"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/12/Gemini-3.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-border-color has-cyan-bluish-gray-border-color">
<p>Vue 3のコンポーネント構造を維持しつつ、ビルド環境（npm等）なしでブラウザで直接実行できるように、CDNを利用した単一のHTMLファイルに書き換えます。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Vue 3はグローバル変数版を使用し、<code>setup</code>関数内で地図の描画ロジックを実装します。</p>
</div></div>



<p>「Gemini 3」が最終的に提示したプログラムコードです。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ja&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Miller Projection - No Graticules&lt;/title&gt;
    &lt;script src=&quot;https://unpkg.com/vue@3/dist/vue.global.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://d3js.org/d3.v7.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://d3js.org/d3-geo-projection.v4.min.js&quot;&gt;&lt;/script&gt;
    &lt;style&gt;
        body { margin: 0; background-color: #f1f5f9; font-family: &#39;Hiragino Sans&#39;, Meiryo, sans-serif; }
        #app { display: flex; flex-direction: column; align-items: center; padding: 20px; }
        .map-container { position: relative; background: #ffffff; box-shadow: 0 10px 25px rgba(0,0,0,0.1); border-radius: 8px; cursor: crosshair; }
        canvas { display: block; width: 100%; height: auto; max-width: 1000px; }
        
        /* ツールチップのスタイル */
        .tooltip {
            position: absolute; pointer-events: none; background: #1e293b; color: white; padding: 8px 16px; 
            border-radius: 6px; font-size: 15px; font-weight: bold; box-shadow: 0 4px 12px rgba(0,0,0,0.3); 
            z-index: 1000; white-space: nowrap; width: auto; min-width: fit-content;
            transform: translate(15px, 15px);
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;div id=&quot;app&quot;&gt;
    &lt;strong&gt;世界白地図 (ミラー図法 / 国名表示対応)&lt;/strong&gt;
    &lt;div class=&quot;map-container&quot; @mousemove=&quot;handleMouseMove&quot; @mouseleave=&quot;handleMouseLeave&quot;&gt;
        &lt;canvas ref=&quot;mapCanvas&quot; :width=&quot;internalWidth&quot; :height=&quot;internalHeight&quot;&gt;&lt;/canvas&gt;
        &lt;div v-if=&quot;hoveredCountry&quot; class=&quot;tooltip&quot; :style=&quot;tooltipStyle&quot;&gt;
            {{ hoveredCountry }}
        &lt;/div&gt;
        &lt;div v-if=&quot;loading&quot; style=&quot;position:absolute; inset:0; display:flex; justify-content:center; align-items:center; background:rgba(255,255,255,0.7);&quot;&gt;読み込み中...&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
    const { createApp, ref, onMounted, computed } = Vue;

    createApp({
        setup() {
            const mapCanvas = ref(null);
            const internalWidth = 1600;
            const internalHeight = 1000;
            const loading = ref(true);
            const hoveredCountry = ref(null);
            const mousePos = ref({ x: 0, y: 0 });
            
            let geoData = null;
            let projection = null;
            let path = null;
            let context = null;

            // カラーコード定義
            const SEA_COLOR = &quot;#e0f7fa&quot;;
            const LAND_COLOR = &quot;#f5f5dc&quot;;
            const HOVER_COLOR = &quot;#ffa500&quot;;
            const BORDER_COLOR = &quot;#8b4513&quot;;

            onMounted(async () =&gt; {
                context = mapCanvas.value.getContext(&#39;2d&#39;);
                
                projection = d3.geoMiller().scale(260).translate([internalWidth / 2, internalHeight / 2]).rotate([-135, 0]);
                path = d3.geoPath(projection, context);

                // データURL（110m解像度）
                const geoDataUrl = &quot;https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_admin_0_countries.geojson&quot;;

                try {
                    geoData = await d3.json(geoDataUrl);
                    loading.value = false;
                    drawMap(null);
                } catch (error) { console.error(error); }
            });

            const drawMap = (hoverFeature) =&gt; {
                // 1. 海の塗りつぶし
                context.fillStyle = SEA_COLOR;
                context.fillRect(0, 0, internalWidth, internalHeight);

                // 2. 経緯度線の描画ロジックを削除しました (以前のコード: const graticule = d3.geoGraticule(); ...)

                // 3. 全ての国を通常色で塗りつぶし＆境界線を描画
                context.beginPath(); 
                path(geoData);
                context.fillStyle = LAND_COLOR;
                context.fill();
                context.strokeStyle = BORDER_COLOR;
                context.lineWidth = 1.0;
                context.stroke();
                
                // 4. ホバー中の国を強調描画 (上書き)
                if (hoverFeature) {
                    context.beginPath();
                    path(hoverFeature);
                    context.fillStyle = HOVER_COLOR;
                    context.fill();
                    
                    // 境界線を再度描画
                    context.strokeStyle = BORDER_COLOR;
                    context.lineWidth = 1.2; 
                    context.stroke();
                }
            };

            const handleMouseMove = (event) =&gt; {
                if (!geoData || !projection) return;
                const rect = mapCanvas.value.getBoundingClientRect();
                const scaleX = internalWidth / rect.width;
                const scaleY = internalHeight / rect.height;
                const canvasX = (event.clientX - rect.left) * scaleX;
                const canvasY = (event.clientY - rect.top) * scaleY;

                mousePos.value = { x: event.clientX - rect.left, y: event.clientY - rect.top };
                
                const coords = projection.invert([canvasX, canvasY]);
                while (coords[0] &gt; 180) coords[0] -= 360;
                while (coords[0] &lt; -180) coords[0] += 360;

                const feature = geoData.features.find(f =&gt; d3.geoContains(f, coords));
                const currentCountryName = feature ? (feature.properties.NAME_JA || feature.properties.NAME) : null;
                
                if (hoveredCountry.value !== currentCountryName) {
                    hoveredCountry.value = currentCountryName;
                    drawMap(feature); 
                }
            };

            const handleMouseLeave = () =&gt; { 
                if (hoveredCountry.value !== null) {
                    hoveredCountry.value = null;
                    drawMap(null);
                }
            };

            const tooltipStyle = computed(() =&gt; ({
                left: `${mousePos.value.x}px`,
                top: `${mousePos.value.y}px`
            }));

            return { mapCanvas, internalWidth, internalHeight, loading, hoveredCountry, handleMouseMove, handleMouseLeave, tooltipStyle };
        }
    }).mount(&#39;#app&#39;);
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</code></pre></div>



<p>この投稿にWordPressのブロックエディタで「カスタムHTML」ブロックを配置し、上記のHTMLのコードを貼り付けてみます。</p>



<p>世界地図が表示され、地図の上をマウスでホバーすると国名が表示されるはずです。</p>



<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Miller Projection - No Graticules</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://d3js.org/d3-geo-projection.v4.min.js"></script>
    <style>
        body { margin: 0; background-color: #f1f5f9; font-family: 'Hiragino Sans', Meiryo, sans-serif; }
        #app { display: flex; flex-direction: column; align-items: center; padding: 20px; }
        .map-container { position: relative; background: #ffffff; box-shadow: 0 10px 25px rgba(0,0,0,0.1); border-radius: 8px; cursor: crosshair; }
        canvas { display: block; width: 100%; height: auto; max-width: 1000px; }
        
        /* ツールチップのスタイル */
        .tooltip {
            position: absolute; pointer-events: none; background: #1e293b; color: white; padding: 8px 16px; 
            border-radius: 6px; font-size: 15px; font-weight: bold; box-shadow: 0 4px 12px rgba(0,0,0,0.3); 
            z-index: 1000; white-space: nowrap; width: auto; min-width: fit-content;
            transform: translate(15px, 15px);
        }
    </style>
</head>
<body>

<div id="app">
    <strong>世界白地図 (ミラー図法 / 国名表示対応)</strong>
    <div class="map-container" @mousemove="handleMouseMove" @mouseleave="handleMouseLeave">
        <canvas ref="mapCanvas" :width="internalWidth" :height="internalHeight"></canvas>
        <div v-if="hoveredCountry" class="tooltip" :style="tooltipStyle">
            {{ hoveredCountry }}
        </div>
        <div v-if="loading" style="position:absolute; inset:0; display:flex; justify-content:center; align-items:center; background:rgba(255,255,255,0.7);">読み込み中...</div>
    </div>
</div>

<script>
    const { createApp, ref, onMounted, computed } = Vue;

    createApp({
        setup() {
            const mapCanvas = ref(null);
            const internalWidth = 1600;
            const internalHeight = 1000;
            const loading = ref(true);
            const hoveredCountry = ref(null);
            const mousePos = ref({ x: 0, y: 0 });
            
            let geoData = null;
            let projection = null;
            let path = null;
            let context = null;

            // カラーコード定義
            const SEA_COLOR = "#e0f7fa";
            const LAND_COLOR = "#f5f5dc";
            const HOVER_COLOR = "#ffa500";
            const BORDER_COLOR = "#8b4513";

            onMounted(async () => {
                context = mapCanvas.value.getContext('2d');
                
                projection = d3.geoMiller().scale(260).translate([internalWidth / 2, internalHeight / 2]).rotate([-135, 0]);
                path = d3.geoPath(projection, context);

                // データURL（110m解像度）
                const geoDataUrl = "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_admin_0_countries.geojson";

                try {
                    geoData = await d3.json(geoDataUrl);
                    loading.value = false;
                    drawMap(null);
                } catch (error) { console.error(error); }
            });

            const drawMap = (hoverFeature) => {
                // 1. 海の塗りつぶし
                context.fillStyle = SEA_COLOR;
                context.fillRect(0, 0, internalWidth, internalHeight);

                // 2. 経緯度線の描画ロジックを削除しました (以前のコード: const graticule = d3.geoGraticule(); ...)

                // 3. 全ての国を通常色で塗りつぶし＆境界線を描画
                context.beginPath(); 
                path(geoData);
                context.fillStyle = LAND_COLOR;
                context.fill();
                context.strokeStyle = BORDER_COLOR;
                context.lineWidth = 1.0;
                context.stroke();
                
                // 4. ホバー中の国を強調描画 (上書き)
                if (hoverFeature) {
                    context.beginPath();
                    path(hoverFeature);
                    context.fillStyle = HOVER_COLOR;
                    context.fill();
                    
                    // 境界線を再度描画
                    context.strokeStyle = BORDER_COLOR;
                    context.lineWidth = 1.2; 
                    context.stroke();
                }
            };

            const handleMouseMove = (event) => {
                if (!geoData || !projection) return;
                const rect = mapCanvas.value.getBoundingClientRect();
                const scaleX = internalWidth / rect.width;
                const scaleY = internalHeight / rect.height;
                const canvasX = (event.clientX - rect.left) * scaleX;
                const canvasY = (event.clientY - rect.top) * scaleY;

                mousePos.value = { x: event.clientX - rect.left, y: event.clientY - rect.top };
                
                const coords = projection.invert([canvasX, canvasY]);
                while (coords[0] > 180) coords[0] -= 360;
                while (coords[0] < -180) coords[0] += 360;

                const feature = geoData.features.find(f => d3.geoContains(f, coords));
                const currentCountryName = feature ? (feature.properties.NAME_JA || feature.properties.NAME) : null;
                
                if (hoveredCountry.value !== currentCountryName) {
                    hoveredCountry.value = currentCountryName;
                    drawMap(feature); 
                }
            };

            const handleMouseLeave = () => { 
                if (hoveredCountry.value !== null) {
                    hoveredCountry.value = null;
                    drawMap(null);
                }
            };

            const tooltipStyle = computed(() => ({
                left: `${mousePos.value.x}px`,
                top: `${mousePos.value.y}px`
            }));

            return { mapCanvas, internalWidth, internalHeight, loading, hoveredCountry, handleMouseMove, handleMouseLeave, tooltipStyle };
        }
    }).mount('#app');
</script>

</body>
</html>



<h2 class="wp-block-heading"><span id="toc6">Google Antigravity</span></h2>



<p>上記の「世界地図」ように、WEBブラウザから「Gemini 3」にアクセスして、プログラムコードを生成してもらうこともできますが、生成したプログラムコードを実行環境に毎回コピーしてデバッグするのは面倒です。</p>



<p>ネットで調べていたら、「Google Antigravity」のことを知りました。<br>「Google Antigravity」は、単なるエディタではなく、AIが自立して考え、手も動かしてくれる、AIエージェントです。</p>



<p>私にとっては、以下のメリットを感じたので、直ぐに自分のPCにインストールして使ってみました。</p>



<ul class="wp-block-list">
<li>慣れ親しんだVSCodeからforkしているので、アプリケーションの見た目に抵抗感がない。<br>自分では一切コードを書かないバイブコーディング（Vibe Coding）なので、本当に見た目だけ。</li>



<li>事前にプロジェクトの進め方やコーディングの方針を提示してくれる。<br>途中で方針の追加・変更もできるし、変更内容をちゃんとドキュメントに残してくれる。</li>



<li>Chromeブラウザと連携して動作確認できる。<br>生成したプログラムコードをいちいちコピペする必要がない。<br>AIエージェントは、自ら考プログラムコードを生成するだけでなく、ブラウザからDOMを取得して最低限のデバッグしているみたい。ここが「手を動かす」という意味。</li>
</ul>



<h3 class="wp-block-heading"><span id="toc7">3Dオセロゲーム</span></h3>



<p>「Google Antigravity」を使って「3Dオセロゲーム」を作ってみました。<br>以下のプロンプトからスタートしました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>Vue3とJavaScriptでオセロゲームのプログラムを作りたい。<br>オセロゲームのゲームボードと駒は3Dモデルを使う。<br>3DライブラリーはThree.jsを使う。<br>3Dモデルデータはこちらから指定する。</p>



<p>最初のメニュー画面で、対戦相手を</p>



<ul class="wp-block-list">
<li>2人のユーザー（対人戦）</li>



<li>ユーザーとコンピュータ（対コンピューター戦）</li>



<li>コンピューターとコンピューター（観戦）</li>
</ul>



<p>を選べるようにする。</p>



<p>対コンピューター戦では、コンピュータの強さを3段階で選べるようにする。<br>ゲーム開始時に、どちらが白か黒か決める（それに合わせて先攻/後攻も決める）。<br>ゲームが終了したら、ゲームボードの駒がフライングした後、白/黒の駒ごとに積み上げるアニメーションで、どちらが勝ったかビジュアルに表示する。<br>積み上げのアニメーションは、後でHTMLで指定する。</p>
</div></div>



<h3 class="wp-block-heading"><span id="toc8">3Dモデルデータ</span></h3>



<p>ゲームボードと駒の3Dモデルデータも以下の画像を「Gemini 3」に渡して生成してもらいました。</p>



<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/0650233d766c6b3b04b78395e6a724f0.jpg"><img loading="lazy" decoding="async" width="800" height="495" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/0650233d766c6b3b04b78395e6a724f0.jpg" alt="" class="wp-image-15056" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/0650233d766c6b3b04b78395e6a724f0.jpg 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/0650233d766c6b3b04b78395e6a724f0-500x309.jpg 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/0650233d766c6b3b04b78395e6a724f0-300x186.jpg 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/0650233d766c6b3b04b78395e6a724f0-768x475.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a></figure>



<p>以下の画像は、「Gimine 3」が自分で生成した画像です。<br>「Gimine 3」に渡したオリジナルの画像とは、見る角度、駒や駒が入った透明ケースの位置や配置が異なっています。<br>つまり、「Gimine 3」は、オリジナルの画像から3次元の世界を完全に認識していると思われます。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="800" height="500" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/66c88c3edd9933d06b3f88314599b338.jpg" alt="" class="wp-image-15057" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/66c88c3edd9933d06b3f88314599b338.jpg 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/66c88c3edd9933d06b3f88314599b338-500x313.jpg 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/66c88c3edd9933d06b3f88314599b338-300x188.jpg 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/66c88c3edd9933d06b3f88314599b338-768x480.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></figure>



<p>以下の画像も「Gimine 3」が生成した駒の画像です。<br>駒の形状も正しく認識していますね。</p>



<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/72d988d7a9e1b1e5465314468cbc8c99.jpg"><img loading="lazy" decoding="async" width="800" height="500" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/72d988d7a9e1b1e5465314468cbc8c99.jpg" alt="" class="wp-image-15058" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/72d988d7a9e1b1e5465314468cbc8c99.jpg 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/72d988d7a9e1b1e5465314468cbc8c99-500x313.jpg 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/72d988d7a9e1b1e5465314468cbc8c99-300x188.jpg 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/72d988d7a9e1b1e5465314468cbc8c99-768x480.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></a></figure>



<h3 class="wp-block-heading"><span id="toc9">バイブコーディング（Vibe Coding）</span></h3>



<p>もちろん、最初のプロンプトだけで一発完成にはなりません。</p>



<p>私は、「ああして、こうして。」と日本語で指示するだけで、一切プログラムコードは書かないバイブコーディング（Vibe Coding）です。<br>ただし、何度もプロンプトでこちらの要望や不具合点を「Google Antigravity」（裏で動いている「Gimine 3」）に伝える必要があります。</p>



<p>実は、「コンピューターとコンピューター（観戦）」のモードは、途中で追加しました。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-flat sbp-r sbis-cb cf block-box not-nested-style cocoon-block-balloon" style="--cocoon-custom-background-color:#f3fafe;--cocoon-custom-border-color:#8ed1fc"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon has-background has-border-color has-watery-blue-background-color has-pale-cyan-blue-border-color">
<p>メニュー画面に「コンピューター対コンピューター」のボタンを追加して。 <br>このボタンが押されると、最強モードで「コンピューター対コンピューター」のゲームを開始して。</p>
</div></div>



<p>デバッグのために、毎回「ユーザーとコンピュータ（対コンピューター戦）」のモードで、コンピューターと対戦するのが面倒くさくなったからです。</p>



<p>実際に作成した「<a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/html/othello_game/index.html" target="_blank">3Dオセロゲーム</a>」は、以下のリンクから遊べます。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-check">

<a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/html/othello_game/index.html" title="3D Othello" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/f7886c350f9ee078dbd5be15b2f33604.jpg" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">3D Othello</div><div class="blogcard-snippet external-blogcard-snippet">3Dオセロゲーム</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/html/othello_game/index.html" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">vitorec.co.jp</div></div></div></div></a>
</div>



<p>「3DOthello」のタイトル画像も、オリジナルのオセロゲームのタイトル画像をベースに「Gemini 3」で生成しました。</p>



<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/3D-Othello.png"><img loading="lazy" decoding="async" width="514" height="568" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/3D-Othello.png" alt="" class="wp-image-15046" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/3D-Othello.png 514w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/3D-Othello-452x500.png 452w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2026/02/3D-Othello-271x300.png 271w" sizes="(max-width: 514px) 100vw, 514px" /></a></figure>



<h2 class="wp-block-heading"><span id="toc10">まとめ</span></h2>



<p>最新の高性能AIモデルがリリースされたというニュースを目にして、「Gemini 3」試してみました。</p>



<p>また、「Google Antigravity」で「3Dオセロゲーム」も作ってみました。</p>



<p>生成された画像の出来栄えやプログラムコードの完成度にびっくりです。<br>とんでもない時代になってきました。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/%e6%9c%80%e6%96%b0%e3%81%ae%e9%ab%98%e6%80%a7%e8%83%bdai%e3%83%a2%e3%83%87%e3%83%ab%e3%80%8cgemini-3%e3%80%8d%e3%82%92%e8%a9%a6%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>「Vue 3 Datepicker」やりたいことは何でもできるんじゃない？！</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/%e3%80%8cvue-3-datepicker%e3%80%8d%e3%82%84%e3%82%8a%e3%81%9f%e3%81%84%e3%81%93%e3%81%a8%e3%81%af%e4%bd%95%e3%81%a7%e3%82%82%e3%81%a7%e3%81%8d%e3%82%8b%e3%82%93%e3%81%98%e3%82%83%e3%81%aa%e3%81%84/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/%e3%80%8cvue-3-datepicker%e3%80%8d%e3%82%84%e3%82%8a%e3%81%9f%e3%81%84%e3%81%93%e3%81%a8%e3%81%af%e4%bd%95%e3%81%a7%e3%82%82%e3%81%a7%e3%81%8d%e3%82%8b%e3%82%93%e3%81%98%e3%82%83%e3%81%aa%e3%81%84/#comments</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Mon, 25 Jul 2022 03:15:19 +0000</pubDate>
				<category><![CDATA[Vue3]]></category>
		<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=11120</guid>

					<description><![CDATA[目次 環境Vue 3 Datepickerとは？Vue 3 Datepickerの機能紹介デフォルト状態フォーマットの変更日本語表記にする「秒」を入力できるようにする2つのカレンダーを表示して期間を入力するまとめ 環境  [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-6" checked><label class="toc-title" for="toc-checkbox-6">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">環境</a></li><li><a href="#toc2" tabindex="0">Vue 3 Datepickerとは？</a></li><li><a href="#toc3" tabindex="0">Vue 3 Datepickerの機能紹介</a><ol><li><a href="#toc4" tabindex="0">デフォルト状態</a></li><li><a href="#toc5" tabindex="0">フォーマットの変更</a></li><li><a href="#toc6" tabindex="0">日本語表記にする</a></li><li><a href="#toc7" tabindex="0">「秒」を入力できるようにする</a></li><li><a href="#toc8" tabindex="0">2つのカレンダーを表示して期間を入力する</a></li></ol></li><li><a href="#toc9" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">環境</span></h2>



<p>このページで使用しているフレームワークやライブラリのバージョンは、以下のとおりです。</p>



<figure class="wp-block-table"><table><tbody><tr><td>vue.js</td><td>3.2.37</td></tr><tr><td>Vue 3 Datepicker</td><td>7.2.2</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><span id="toc2">Vue 3 Datepickerとは？</span></h2>



<p>「<a rel="noopener noreferrer" href="https://vue3datepicker.com/" target="_blank">Vue 3 Datepicker<span class="fa fa-external-link external-icon anchor-icon"></span></a>」は、Vue3で使用できるDate-Time-Pickerライブラリです。</p>



<p>今回、以下の機能を持ったDate-Time-Pickerを探していて見つけたライブラリです。</p>



<ul class="wp-block-list">
<li>日付と時刻が入力できること。</li>



<li>時刻は、「秒」まで入力できること。</li>



<li>日本語表記に対応できること。</li>



<li>モダンなデザインで、使いやすいUIであること。</li>
</ul>



<p>デザインや使い勝手は、好みのわかれるところですが、この「Vue 3 Datepicker」は、何より機能が豊富です。</p>



<p>「やりたいこと、何でもできるじゃん！」と感激したので、是非とも紹介したくなりました。</p>



<h2 class="wp-block-heading"><span id="toc3">Vue 3 Datepickerの機能紹介</span></h2>



<p>「Vue 3 Datepicker」は、とにかく機能が豊富です。<br>全ての機能は、<a rel="noopener noreferrer" href="https://vue3datepicker.com/" target="_blank">公式のドキュメント<span class="fa fa-external-link external-icon anchor-icon"></span></a>を見てもらうとして、ここでは、一部の機能と実際のソースコードを紹介します。</p>



<h3 class="wp-block-heading"><span id="toc4">デフォルト状態</span></h3>



<p>まずは、デフォルトの状態です。<br>厳密には、デフォルト状態に<strong>placeholder</strong>を追加しています。<br><br>下のテキストボックスをクリックして、実際の日時を入力してみてください。</p>



<div id="app-default">
    <datepicker placeholder="ここをクリックして日時を入力" v-model="date"></datepicker>
</div>

<script>
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        data() {
            return { date: Vue.ref() };
        },
    }).mount("#app-default");
</script>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-edit"></span>コード</span></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;div id=&quot;app-default&quot;&gt;
    &lt;datepicker
        placeholder=&quot;ここをクリックして日時を入力&quot;
        v-model=&quot;date&quot;
    &gt;&lt;/datepicker&gt;
&lt;/div&gt;

&lt;script&gt;
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        data() {
            return { date: Vue.ref() };
        },
    }).mount(&quot;#app-default&quot;);
&lt;/script&gt;</code></pre></div>



<h3 class="wp-block-heading"><span id="toc5">フォーマットの変更</span></h3>



<p>デフォルトの状態では、入力した日時が「MM/DD/YYYY, HH:mm」のフォーマットで表示されます。<br>このフォーマットを「YYYY-MM-DD HH:mm:ss」に変更します。</p>



<div id="app-format">
    <datepicker placeholder="ここをクリックして日時を入力" v-model="date" v-bind:format="format"></datepicker>
</div>

<script>
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        data() {
            return {
                date: Vue.ref(),
                format: (date) => {
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, "0");
                    const day = String(date.getDate()).padStart(2, "0");
                    const hours = String(date.getHours()).padStart(2, "0");
                    const minutes = String(date.getMinutes()).padStart(2, "0");
                    const seconds = String(date.getSeconds()).padStart(2, "0");

                    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                },
            };
        },
    }).mount("#app-format");
</script>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-edit"></span>コード</span></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;div id=&quot;app-format&quot;&gt;
    &lt;datepicker
        placeholder=&quot;ここをクリックして日時を入力&quot;
        v-model=&quot;date&quot;
        v-bind:format=&quot;format&quot;
    &gt;&lt;/datepicker&gt;
&lt;/div&gt;

&lt;script&gt;
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        data() {
            return {
                date: Vue.ref(),
                format: (date) =&gt; {
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, &quot;0&quot;);
                    const day = String(date.getDate()).padStart(2, &quot;0&quot;);
                    const hours = String(date.getHours()).padStart(2, &quot;0&quot;);
                    const minutes = String(date.getMinutes()).padStart(2, &quot;0&quot;);
                    const seconds = String(date.getSeconds()).padStart(2, &quot;0&quot;);

                    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                },
            };
        },
    }).mount(&quot;#app-format&quot;);
&lt;/script&gt;
</code></pre></div>



<h3 class="wp-block-heading"><span id="toc6">日本語表記にする</span></h3>



<p>&lt;datepicker&gt;タグに<strong>locale="jp"</strong>を追加するだけで、曜日が日本語表記になります。</p>



<p><strong>cancel-text="キャンセル"</strong>、<strong>select-text="OK"</strong>も追加して、”Cancel”を”キャンセル”、”Select”を”OK”に変更します。</p>



<p>「月」の数字の後ろに”月”、「年」の数字の後ろに”年”の文字を表示するには、<br><strong>&lt;template year="{ value }"&gt; {{ value }}年&gt;&lt;/template&gt;</strong><br>を追加します。</p>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box alert-box">
<p>Vue 3 Datepickerのバージョン5.x.xまでは、&lt;template>タグの<span class="bold-red">赤字</span>部分を下記のとおり<span class="bold-red">year</span>にする必要がありました。<br><br><strong>&lt;template year="{ <span class="bold-red">year</span> }"> {{ <span class="bold-red">year</span> }}年>&lt;/template></strong><br><br>このように、Vue 3 Datepickerは、バージョンによって仕様が大きく変わりますので、注意が必要です。</p>
</div>



<p>これ以降、実際のコードは、&lt;datepicker&gt;…&lt;/datepicker&gt;タグの部分のみが変更になりますので、&lt;datepicker&gt;…&lt;/datepicker&gt;タグ部分のみを掲載します。</p>



<div id="app-jp">
    <datepicker placeholder="ここをクリックして日時を入力" v-model="date" v-bind:format="format" locale="jp" cancel-text="キャンセル" select-text="OK">
        <template #year="{ value }"> {{ value }}年 </template>
    </datepicker>
</div>

<script>
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        data() {
            return {
                date: Vue.ref(),
                format: (date) => {
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, "0");
                    const day = String(date.getDate()).padStart(2, "0");
                    const hours = String(date.getHours()).padStart(2, "0");
                    const minutes = String(date.getMinutes()).padStart(2, "0");
                    const seconds = String(date.getSeconds()).padStart(2, "0");

                    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                },
            };
        },
    }).mount("#app-jp");
</script>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-edit"></span>コード</span></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>    &lt;datepicker
        placeholder=&quot;ここをクリックして日時を入力&quot;
        v-model=&quot;date&quot;
        v-bind:format=&quot;format&quot;
        locale=&quot;jp&quot;
        cancel-text=&quot;キャンセル&quot;
        select-text=&quot;OK&quot;
    &gt;
        &lt;template #year=&quot;{ value }&quot;&gt; {{ value }}年 &lt;/template&gt;
    &lt;/datepicker&gt;</code></pre></div>



<h3 class="wp-block-heading"><span id="toc7">「秒」を入力できるようにする</span></h3>



<p>&lt;datepicker&gt;タグに<strong>enable-seconds</strong>を追加するだけで、時刻入力で「秒」も入力できるようになります。</p>



<div id="app-seconds">
    <datepicker placeholder="ここをクリックして日時を入力" v-model="date" v-bind:format="format" locale="jp" cancel-text="キャンセル" select-text="OK" enable-seconds="">
        <template #year="{ value }"> {{ value }}年 </template>
    </datepicker>
</div>

<script>
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        data() {
            return {
                date: Vue.ref(),
                format: (date) => {
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, "0");
                    const day = String(date.getDate()).padStart(2, "0");
                    const hours = String(date.getHours()).padStart(2, "0");
                    const minutes = String(date.getMinutes()).padStart(2, "0");
                    const seconds = String(date.getSeconds()).padStart(2, "0");

                    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                },
            };
        },
    }).mount("#app-seconds");
</script>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-edit"></span>コード</span></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>    &lt;datepicker
        placeholder=&quot;ここをクリックして日時を入力&quot;
        v-model=&quot;date&quot;
        v-bind:format=&quot;format&quot;
        locale=&quot;jp&quot;
        cancel-text=&quot;キャンセル&quot;
        select-text=&quot;OK&quot;
        enable-seconds
    &gt;
        &lt;template #year=&quot;{ value }&quot;&gt; {{ value }}年 &lt;/template&gt;
    &lt;/datepicker&gt;</code></pre></div>



<h3 class="wp-block-heading"><span id="toc8">2つのカレンダーを表示して期間を入力する</span></h3>



<p>最後に2つのカレンダーを表示して、期間を入力する例です。<br>&lt;datepicker&gt;タグに<strong>range</strong>と<strong>multi-calendars</strong>を追加します。</p>



<p>日時が格納される変数<strong>date</strong>が配列になるので、<strong>format</strong>関数が少し複雑になります。<br></p>



<div id="app-multi">
    <datepicker placeholder="ここをクリックして日時を入力" v-model="date" v-bind:format="format" locale="jp" cancel-text="キャンセル" select-text="OK" enable-seconds="" range="" multi-calendars="">
        <template #year="{ value }"> {{ value }}年 </template>
    </datepicker>
</div>

<script>
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        mounted() {
            this.date = [];
        },
        data() {
            return {
                date: Vue.ref(),
                format: (date_array) => {
                    let result = "";
                    date_array.forEach((date, index) => {
                        if (Object.prototype.toString.call(date) == "[object Date]") {
                            const year = date.getFullYear();
                            const month = String(date.getMonth() + 1).padStart(2, "0");
                            const day = String(date.getDate()).padStart(2, "0");
                            const hours = String(date.getHours()).padStart(2, "0");
                            const minutes = String(date.getMinutes()).padStart(2, "0");
                            const seconds = String(date.getSeconds()).padStart(2, "0");

                            result += `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                            if (index == 0) {
                                result += ` - `;
                            }
                        }
                    });

                    return result;
                },
            };
        },
    }).mount("#app-multi");
</script>



<div class="wp-block-cocoon-blocks-micro-text micro-text micro-copy micro-top"><span class="micro-text-content micro-content"><span class="micro-text-icon micro-icon fab-edit"></span>コード</span></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;div id=&quot;app-multi&quot;&gt;
    &lt;datepicker
        placeholder=&quot;ここをクリックして日時を入力&quot;
        v-model=&quot;date&quot;
        v-bind:format=&quot;format&quot;
        locale=&quot;jp&quot;
        cancel-text=&quot;キャンセル&quot;
        select-text=&quot;OK&quot;
        enable-seconds
        range
        multi-calendars
    &gt;
        &lt;template #year=&quot;{ value }&quot;&gt; {{ value }}年 &lt;/template&gt;
    &lt;/datepicker&gt;
&lt;/div&gt;

&lt;script&gt;
    Vue.createApp({
        components: { Datepicker: VueDatePicker },
        mounted() {
            this.date = [];
        },
        data() {
            return {
                date: Vue.ref(),
                format: (date_array) =&gt; {
                    let result = &quot;&quot;;
                    date_array.forEach((date, index) =&gt; {
                        if (Object.prototype.toString.call(date) == &quot;[object Date]&quot;) {
                            const year = date.getFullYear();
                            const month = String(date.getMonth() + 1).padStart(2, &quot;0&quot;);
                            const day = String(date.getDate()).padStart(2, &quot;0&quot;);
                            const hours = String(date.getHours()).padStart(2, &quot;0&quot;);
                            const minutes = String(date.getMinutes()).padStart(2, &quot;0&quot;);
                            const seconds = String(date.getSeconds()).padStart(2, &quot;0&quot;);

                            result += `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                            if (index == 0) {
                                result += ` - `;
                            }
                        }
                    });

                    return result;
                },
            };
        },
    }).mount(&quot;#app-multi&quot;);
&lt;/script&gt;</code></pre></div>



<h2 class="wp-block-heading"><span id="toc9">まとめ</span></h2>



<p>日時入力に関して、やりたいことが何でもできそうな「Vue 3 Datepicker」を紹介しました。</p>



<p>ここで紹介した機能を使って、GPXファイルのタイムスタンプを変更するアプリケーションを作ってみました。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/gpx%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e3%82%bf%e3%82%a4%e3%83%a0%e3%82%b9%e3%82%bf%e3%83%b3%e3%83%97%e3%82%92%e5%a4%89%e6%9b%b4%e3%81%99%e3%82%8b/" title="GPXファイルのタイムスタンプを変更する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/07/ca409b1593a4491d18292e29ca6b6786-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/07/ca409b1593a4491d18292e29ca6b6786-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/07/ca409b1593a4491d18292e29ca6b6786-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/07/ca409b1593a4491d18292e29ca6b6786-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">GPXファイルのタイムスタンプを変更する</div><div class="blogcard-snippet internal-blogcard-snippet">GPXファイルのタイムスタンプを変更するツールを作成しました。「Vue 3 Datepicker」で開始日時/終了日時を指定して、GPXファイルのタイムスタンプを簡単に変更できます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2022.08.14</div></div></div></div></a>
</div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/%e3%80%8cvue-3-datepicker%e3%80%8d%e3%82%84%e3%82%8a%e3%81%9f%e3%81%84%e3%81%93%e3%81%a8%e3%81%af%e4%bd%95%e3%81%a7%e3%82%82%e3%81%a7%e3%81%8d%e3%82%8b%e3%82%93%e3%81%98%e3%82%83%e3%81%aa%e3%81%84/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>WordPressの投稿にガントチャートを実装する</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%ac%e3%83%b3%e3%83%88%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%99%e3%82%8b/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%ac%e3%83%b3%e3%83%88%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%99%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Fri, 10 Jun 2022 15:00:00 +0000</pubDate>
				<category><![CDATA[Vue3]]></category>
		<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=10848</guid>

					<description><![CDATA[目次 環境frappe-ganttとは？実装したガントチャートガントチャートの編集方法工数グラフまとめ 環境 このページで使用しているフレームワークやライブラリのバージョンは、以下のとおりです。 vue.js 3.2.3 [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-8" checked><label class="toc-title" for="toc-checkbox-8">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">環境</a></li><li><a href="#toc2" tabindex="0">frappe-ganttとは？</a></li><li><a href="#toc3" tabindex="0">実装したガントチャート</a><ol><li><a href="#toc4" tabindex="0">ガントチャートの編集方法</a></li><li><a href="#toc5" tabindex="0">工数グラフ</a></li></ol></li><li><a href="#toc6" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">環境</span></h2>



<p>このページで使用しているフレームワークやライブラリのバージョンは、以下のとおりです。</p>



<figure class="wp-block-table"><table><tbody><tr><td>vue.js</td><td>3.2.31</td></tr><tr><td>vue3-sfc-loader</td><td>0.8.4</td></tr><tr><td>frappe-gantt</td><td>0.6.1をベースに機能拡張</td></tr><tr><td>moment</td><td>2.29.3</td></tr><tr><td>sweetalert2</td><td>11.4.17</td></tr><tr><td>vue-select</td><td>4.0.0-beta.3</td></tr><tr><td>@lk77/vue3-color</td><td>3.0.6</td></tr><tr><td>encoding-japanese</td><td>2.0.0</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><span id="toc2">frappe-ganttとは？</span></h2>



<p>「<a href="https://github.com/frappe/gantt">frappe-gantt<span class="fa fa-external-link external-icon anchor-icon"></span></a>」は、マウスでドラッグしてグラフィカルに編集できるガントチャートのJavaScriptライブラリです。<br>センスの良いデザイン、わかりやすいユーザーインターフェースが魅力的です。</p>



<p>ただ、アップデートが停滞気味で、機能的にも足りない部分があるので、「frappe-gantt」を独自に機能拡張したライブラリを作成することにしました。</p>



<p>追加した機能は、以下のとおりです。</p>



<ul class="wp-block-list">
<li>タスクの担当者入力</li>



<li>タスクの工数配分入力</li>



<li>タスクや進捗度の色の編集</li>



<li>タスクに入力した担当者 / 工数配分を基に、積み上げ工数グラフを表示</li>
</ul>



<p>作成したJavaScriptライブラリを「Vue3.x」から利用して、WordPressの投稿にガントチャートを実装します。</p>



<h2 class="wp-block-heading"><span id="toc3">実装したガントチャート</span></h2>



<p>実装したガントチャートです。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div id="spinner" uk-spinner="ratio: 2"></div>



<script src="https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js"></script>

<!-- Vue3 datepicker -->
<!-- <script src="https://unpkg.com/@vuepic/vue-datepicker@latest"></script> -->
<!-- <link rel="stylesheet" href="https://unpkg.com/@vuepic/vue-datepicker@latest/dist/main.css"> -->
<script src="https://cdn.jsdelivr.net/npm/@vuepic/vue-datepicker@7.2.2/dist/vue-datepicker.iife.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vuepic/vue-datepicker@7.2.2/dist/main.css">

<div id="app"></div>

<script type="module">
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from "https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js";

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?\.js|.mjs$/.test(url)
                ? ".mjs"
                : /.*?\.vue$/.test(url)
                ? ".vue"
                : /.*?\.css$/.test(url)
                ? ".css"
                : ".vue";
            const getContentData = (asBinary) =>
                fetch(url).then((res) =>
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement("style");
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName("style")[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case ".css":
                    return options.addStyle(getContentData(false));
                case ".less":
                    console.error(".......");
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            "vue-gantt": Vue.defineAsyncComponent(() =>
                loadModule(
                    "../wp-content/themes/cocoon-child-master/vue-components/VueGantt.vue?version=1-1-5",
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `<vue-gantt />`,
    });
    app.mount("#app");
</script>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>初回は、本日の位置に［初期タスク］が1つ配置されます。<br>スクロールバーを本日の位置に動かしてください。<br>この状態から、ガントチャートを編集していきます。</p>



<p>次回以降は、前回の編集途中のガントチャートが自動的に読み込まれます。</p>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box alert-box">
<p>・別のPCやブラウザを使った場合<br />・ブラウザのデータをクリアした場合<br />は、前回の編集途中のガントチャートや一時保存したガントチャートを読み込むことができなくなります。<br />重要なガントチャートは、ローカルファイルにダウンロードしてください。</p>
<p>キーボード操作が必要なため、スマートフォンやタブレットでは、正しく編集できません。</p>
</div>



<h3 class="wp-block-heading"><span id="toc4">ガントチャートの編集方法</span></h3>



<ul>
    <li>
        <strong>タスク情報を変更する</strong
        ><br />タスクをダブルクリックすると、タスク情報を編集するダイアログが表示されます。<br />
        ダイアログにタスク情報を入力し、<span class="swal2-confirm-text"
            >OK</span
        >
        ボタンを押します。<br /><br />
        タスク名だけは、入力が<b><span style="color: red">必須</span></b
        >の項目です。<br /><br />
        <!-- タスクの開始日時 / 終了日時のボックスをクリックするとカレンダー /
        時計のユーザーインターフェースが表示され、開始日時 /
        終了日時を変更できます。<br /><br /> -->
        タスクの詳細は、複数行テキスト、HTMLタグも入力できます。<br /><br />
        担当者は、そのタスクを担当する人の情報（名前やID、メールアドレスなど）を入力します。<br /><br />
        工数配分は、そのタスクに配分する工数の割合を入力します。<br /><br />
        プログレスの色 /
        タスクバーの色を指定したい場合は、色指定ボタン（小さい長方形
        <span class="color-button-text">&nbsp;</span>
        ）を押し、カラーピッカーを起動して色を選びます。<br />色指定ボタンを押すたびに、カラーピッカーの表示
        / 非表示が切り替わります。<br />　
    </li>
    <li>
        <strong>タスクの開始日 / 終了日を変更する</strong
        ><br />タスクにマウスカーソルを合わせると、タスクの左端 /
        右端にハンドルが表示されます。<br />左端 /
        右端のハンドルをドラッグし、タスクの開始日 / 終了日を変更します。<br /><br />タスクを左右にドラッグすると、開始日
        / 終了日の間隔を維持したまま、タスクの日程を変更できます。<br />
        ［Shift］キーを押しながら左右にドラッグすると、移動方向は左右のみに固定され、上下の位置は変わりません。<br /><!-- <br />
        タスク情報を編集するダイアログでも、カレンダー /
        時計のユーザーインターフェースを使って、タスクの開始日時 /
        終了日時を変更できます。<br /> -->　
    </li>
    <li>
        <strong>タスクの進捗度を変更する</strong
        ><br />タスクにマウスカーソルを合わせると、三角形のハンドルが表示されます。<br />三角形のハンドルをドラッグし、タスクの進捗度を変更します。<br />　
    </li>
    <li>
        <strong style="text-align: -webkit-match-parent"
            >タスクを追加する</strong
        ><br /><span class="gantt-button-text"
            ><i class="fa-solid fa-square-plus"></i> タスクを追加</span
        >
        ボタンを押すと、新規のタスク情報を入力するダイアログが表示されます。<br />
        ダイアログにタスク情報を入力し、<span class="swal2-confirm-text"
            >OK</span
        >
        ボタンを押すと、新しいタスクが一番下に追加されます。<br /><br />
        タスク名だけは、入力が<b><span style="color: red">必須</span></b
        >の項目です。<br />　
    </li>
    <li>
        <strong>タスクを削除する</strong
        ><br />タスクを右クリックすると、タスクの削除を確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、選択したタスクが削除されます。<br />　
    </li>
    <li>
        <strong>タスクの依存関係（親子関係）を変更する</strong
        ><br />［Alt］キーを押したまま、「親タスク」をクリックします。<br />赤い矢印が表示されます。<br />その後、依存関係を設定したい「子タスク」をクリックします。<br />「親タスク」から「子タスク」に矢印がつながり、依存関係が設定されます。<br /><br />既に、依存関係が設定されている場合は、依存関係が解除されます。<br />　
    </li>
    <li>
        <strong style="text-align: -webkit-match-parent"
            >タスクの上下位置を変更する</strong
        ><br />タスクを上下にドラッグすると、タスクの上下位置を変更できます。<br />
        ［Shift］キーを押しながら上下にドラッグすると、移動方向は上下のみに固定され、左右の位置は変わりません。<br /><br />
        「子タスク」を「親タスク」の上に移動することはできません。<br />ドラッグ後のタスクの位置は、「親タスク」「子タスク」の上下関係を優先して調整されます。<br /><br />
        <div
            class="gantt-free-index"
            style="margin-left: 1.5em; margin-bottom: 0.5em; font-size: 0.95em"
        >
            <input
                type="checkbox"
                id="free-index"
                class="gantt-checkbox"
                checked
            />
            <label for="free-index" class="gantt-label"
                >タスクの上下位置を自由に配置</label
            >
        </div>
        を有効にした状態でタスクを上下にドラッグすると、上下位置を自由に変更できます。<br />
        この状態では、「親タスク」「子タスク」の関係も無視され、タスクを移動した後の上下位置の整列も行いません。<br />　
    </li>
    <li>
        <strong>ビューモードを変更する</strong><br /><span
            class="gantt-button-text"
            >日</span
        >
        <span class="gantt-button-text">週</span>
        <span class="gantt-button-text">月</span>
        ボタンを押して、ビューモードを変更します。<br />　
    </li>
    <li>
        <strong>ガントチャートをリセットする</strong><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-trash"></i> リセット</span
        >
        ボタンを押すと、ガントチャートのリセットを確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、ガントチャートを初期状態にリセットします。<br />　
    </li>
    <li>
        <strong>ガントチャートを保存 / 読込む</strong><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-right-to-bracket"></i> 保存</span
        >
        ボタンを押すと、ガントチャートの保存を確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、作成中のガントチャートを自分の使っているブラウザに一時的に保存します。<br /><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-right-from-bracket"></i> 読込み</span
        >
        ボタンを押すと、ガントチャートの読込みを確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、保存したガントチャートを読込みます。<br /><br />ブラウザを閉じても、保存したガントチャートはブラウザに残ります。<br />　
    </li>
    <li>
        <strong>ガントチャートをダウンロード / アップロードする</strong
        ><br /><span class="gantt-button-text"
            ><i class="fa-solid fa-file-arrow-down"></i> ダウンロード</span
        >
        ボタンを押すと、作成中のガントチャートをローカルファイルにダウンロードできます。<br /><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-file-arrow-up"></i> アップロード</span
        >
        ボタンを押し、ダウンロードしたガントチャートファイルを指定すると、このファイルがアップロードされ、ガントチャートが更新されます。
    </li>
</ul>



<h3 class="wp-block-heading"><span id="toc5">工数グラフ</span></h3>



<ul>
    <li>
        <strong>タスク情報を変更する</strong
        ><br />タスクをダブルクリックすると、タスク情報を編集するダイアログが表示されます。<br />
        ダイアログにタスク情報を入力し、<span class="swal2-confirm-text"
            >OK</span
        >
        ボタンを押します。<br /><br />
        タスク名だけは、入力が<b><span style="color: red">必須</span></b
        >の項目です。<br /><br />
        タスクの開始日時 / 終了日時のボックスをクリックするとカレンダー /
        時計のユーザーインターフェースが表示され、開始日時 /
        終了日時を変更できます。<br /><br />
        タスクの詳細は、複数行テキスト、HTMLタグも入力できます。<br /><br />
        担当者は、そのタスクを担当する人の情報（名前やID、メールアドレスなど）を入力します。<br /><br />
        工数配分は、そのタスクに配分する工数の割合を入力します。<br /><br />
        プログレスの色 /
        タスクバーの色を指定したい場合は、色指定ボタン（小さい長方形
        <span class="color-button-text">&nbsp;</span>
        ）を押し、カラーピッカーを起動して色を選びます。<br />色指定ボタンを押すたびに、カラーピッカーの表示
        / 非表示が切り替わります。<br />　
    </li>
    <li>
        <strong>タスクの開始日 / 終了日を変更する</strong
        ><br />タスクにマウスカーソルを合わせると、タスクの左端 /
        右端にハンドルが表示されます。<br />左端 /
        右端のハンドルをドラッグし、タスクの開始日 / 終了日を変更します。<br /><br />タスクを左右にドラッグすると、開始日
        / 終了日の間隔を維持したまま、タスクの日程を変更できます。<br />
        ［Shift］キーを押しながら左右にドラッグすると、移動方向は左右のみに固定され、上下の位置は変わりません。<br /><br />
        タスク情報を編集するダイアログでも、カレンダー /
        時計のユーザーインターフェースを使って、タスクの開始日時 /
        終了日時を変更できます。<br />　
    </li>
    <li>
        <strong>タスクの進捗度を変更する</strong
        ><br />タスクにマウスカーソルを合わせると、三角形のハンドルが表示されます。<br />三角形のハンドルをドラッグし、タスクの進捗度を変更します。<br />　
    </li>
    <li>
        <strong style="text-align: -webkit-match-parent"
            >タスクを追加する</strong
        ><br /><span class="gantt-button-text"
            ><i class="fa-solid fa-square-plus"></i> タスクを追加</span
        >
        ボタンを押すと、新規のタスク情報を入力するダイアログが表示されます。<br />
        ダイアログにタスク情報を入力し、<span class="swal2-confirm-text"
            >OK</span
        >
        ボタンを押すと、新しいタスクが一番下に追加されます。<br /><br />
        タスク名だけは、入力が<b><span style="color: red">必須</span></b
        >の項目です。<br />　
    </li>
    <li>
        <strong>タスクを削除する</strong
        ><br />タスクを右クリックすると、タスクの削除を確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、選択したタスクが削除されます。<br />　
    </li>
    <li>
        <strong>タスクの依存関係（親子関係）を変更する</strong
        ><br />［Alt］キーを押したまま、「親タスク」をクリックします。<br />赤い矢印が表示されます。<br />その後、依存関係を設定したい「子タスク」をクリックします。<br />「親タスク」から「子タスク」に矢印がつながり、依存関係が設定されます。<br /><br />既に、依存関係が設定されている場合は、依存関係が解除されます。<br />　
    </li>
    <li>
        <strong style="text-align: -webkit-match-parent"
            >タスクの上下位置を変更する</strong
        ><br />タスクを上下にドラッグすると、タスクの上下位置を変更できます。<br />
        ［Shift］キーを押しながら上下にドラッグすると、移動方向は上下のみに固定され、左右の位置は変わりません。<br /><br />
        「子タスク」を「親タスク」の上に移動することはできません。<br />ドラッグ後のタスクの位置は、「親タスク」「子タスク」の上下関係を優先して調整されます。<br /><br />
        <div
            class="gantt-free-index"
            style="margin-left: 1.5em; margin-bottom: 0.5em; font-size: 0.95em"
        >
            <input
                type="checkbox"
                id="free-index"
                class="gantt-checkbox"
                checked
            />
            <label for="free-index" class="gantt-label"
                >タスクの上下位置を自由に配置</label
            >
        </div>
        を有効にした状態でタスクを上下にドラッグすると、上下位置を自由に変更できます。<br />
        この状態では、「親タスク」「子タスク」の関係も無視され、タスクを移動した後の上下位置の整列も行いません。<br />　
    </li>
    <li>
        <strong>ビューモードを変更する</strong><br /><span
            class="gantt-button-text"
            >日</span
        >
        <span class="gantt-button-text">週</span>
        <span class="gantt-button-text">月</span>
        ボタンを押して、ビューモードを変更します。<br />　
    </li>
    <li>
        <strong>ガントチャートをリセットする</strong><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-trash"></i> リセット</span
        >
        ボタンを押すと、ガントチャートのリセットを確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、ガントチャートを初期状態にリセットします。<br />　
    </li>
    <li>
        <strong>ガントチャートを保存 / 読込む</strong><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-right-to-bracket"></i> 保存</span
        >
        ボタンを押すと、ガントチャートの保存を確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、作成中のガントチャートを自分の使っているブラウザに一時的に保存します。<br /><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-right-from-bracket"></i> 読込み</span
        >
        ボタンを押すと、ガントチャートの読込みを確認するダイアログが表示されます。<br />
        ダイアログの
        <span class="swal2-confirm-text">OK</span>
        ボタンを押すと、保存したガントチャートを読込みます。<br /><br />ブラウザを閉じても、保存したガントチャートはブラウザに残ります。<br />　
    </li>
    <li>
        <strong>ガントチャートをダウンロード / アップロードする</strong
        ><br /><span class="gantt-button-text"
            ><i class="fa-solid fa-file-arrow-down"></i> ダウンロード</span
        >
        ボタンを押すと、作成中のガントチャートをローカルファイルにダウンロードできます。<br /><br /><span
            class="gantt-button-text"
            ><i class="fa-solid fa-file-arrow-up"></i> アップロード</span
        >
        ボタンを押し、ダウンロードしたガントチャートファイルを指定すると、このファイルがアップロードされ、ガントチャートが更新されます。
    </li>
</ul>



<h2 class="wp-block-heading"><span id="toc6">まとめ</span></h2>



<p>「frappe-gantt」を独自に機能拡張したJavaScriptライブラリを作成し、WordPressの投稿にガントチャートを実装しました。</p>



<p>ガントチャートを使うと、視覚的に業務計画を立てることができます。<br>また、進捗度も変更できるので、業務の進み具合いもビジュアルに把握しやすくなります。</p>



<p>タスクに担当者と工数配分を入力すれば、積み上げ工数グラフで、担当者ごとの毎日の業務負荷を確認できます。</p>



<p>以下のページは、少し広い画面でガントチャートを編集できます。<br>ちょっとした業務計画の作成に利用ください。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-check">

<a href="https://vitorec.co.jp/choi-plus-sozai/%e3%82%ac%e3%83%b3%e3%83%88%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88/" title="ガントチャート" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-Logo-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-Logo-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-Logo-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/06/Frappe-Gantt-Logo-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">ガントチャート</div><div class="blogcard-snippet internal-blogcard-snippet">ガントチャート編集ページ</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.01.01</div></div></div></div></a>
</div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%ac%e3%83%b3%e3%83%88%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPressの投稿にソートやページネーションの機能を持ったテーブルを実装する</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%bd%e3%83%bc%e3%83%88%e3%82%84%e3%83%9a%e3%83%bc%e3%82%b8%e3%83%8d%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e6%a9%9f%e8%83%bd%e3%82%92%e6%8c%81/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%bd%e3%83%bc%e3%83%88%e3%82%84%e3%83%9a%e3%83%bc%e3%82%b8%e3%83%8d%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e6%a9%9f%e8%83%bd%e3%82%92%e6%8c%81/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sun, 24 Apr 2022 03:05:42 +0000</pubDate>
				<category><![CDATA[Vue3]]></category>
		<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=10802</guid>

					<description><![CDATA[目次 環境vue-good-table-nextとは？テーブル用ライブラリの比較WordPressの投稿でvue-good-table-nextを使う“table_library_comparison_table.vue [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-10" checked><label class="toc-title" for="toc-checkbox-10">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">環境</a></li><li><a href="#toc2" tabindex="0">vue-good-table-nextとは？</a></li><li><a href="#toc3" tabindex="0">テーブル用ライブラリの比較</a></li><li><a href="#toc4" tabindex="0">WordPressの投稿でvue-good-table-nextを使う</a><ol><li><a href="#toc5" tabindex="0">“table_library_comparison_table.vue”の中身</a></li></ol></li><li><a href="#toc6" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">環境</span></h2>



<p>このページで使用しているフレームワークやライブラリのバージョンは、以下のとおりです。</p>



<figure class="wp-block-table"><table><tbody><tr><td>vue.js</td><td>3.2.31</td></tr><tr><td>vue3-sfc-loader</td><td>0.8.4</td></tr><tr><td>vue-good-table-next</td><td>0.1.0</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><span id="toc2">vue-good-table-nextとは？</span></h2>



<p>「<a rel="noopener noreferrer" href="https://borisflesch.github.io/vue-good-table-next/" target="_blank">vue-good-table-next<span class="fa fa-external-link external-icon anchor-icon"></span></a>」は、ソート、ページネーション、フィルターなどの機能をもったテーブルを実装できるVueライブラリです。<br>「vue-good-table-next」は、「Vue2.x」で動作する「vue-good-table」を「Vue3.x」に対応させたバージョンです。<br><a rel="noopener noreferrer" href="https://github.com/borisflesch/vue-good-table-next/" target="_blank">GitHub<span class="fa fa-external-link external-icon anchor-icon"></span></a>（updatedショートコードは投稿・固定ページ以外では利用できません。時点）の「vue-good-table-next」バージョンは「0.1.0」で、"README"にも以下の注意書きがあります。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>This project is a port of Vue-good-table for Vue 3.x. The current version is stable enough to start developing new projects but work is still in progress and changes could be made in the short-term. Thus the project is not yet intended to be used in a production environment.</p></blockquote>



<p>ただ、基本的な動作は安定しているようです。</p>



<h2 class="wp-block-heading"><span id="toc3">テーブル用ライブラリの比較</span></h2>



<p>多機能なテーブルを実装するためのライブラリやプラグインは、以下のようにいろいろ提供されています。</p>



<ul class="wp-block-list"><li><a href="https://borisflesch.github.io/vue-good-table-next/">vue-good-table-next<span class="fa fa-external-link external-icon anchor-icon"></span></a></li><li><a href="https://matanya.gitbook.io/vue-tables-2/">vue-tables2（v-tables3）<span class="fa fa-external-link external-icon anchor-icon"></span></a></li><li><a href="https://www.vuetable.com/">Vuetable-2<span class="fa fa-external-link external-icon anchor-icon"></span></a></li><li><a href="https://gridjs.io/">Grid.js<span class="fa fa-external-link external-icon anchor-icon"></span></a></li></ul>



<p></p>



<p>この記事では「vue-good-table-next」を紹介しますが、各種のライブラリの特徴を比較表にまとめました。（updatedショートコードは投稿・固定ページ以外では利用できません。時点）<br>なお、この比較表は、「vue-good-table-next」をインポートしたSFCで表示しています。</p>



<script src="https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js"></script>

<div id="app"></div>

<script type="module">
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from "https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js";

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?\.js|.mjs$/.test(url)
                ? ".mjs"
                : /.*?\.vue$/.test(url)
                ? ".vue"
                : /.*?\.css$/.test(url)
                ? ".css"
                : ".vue";
            const getContentData = (asBinary) =>
                fetch(url).then((res) =>
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement("style");
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName("style")[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case ".css":
                    return options.addStyle(getContentData(false));
                case ".less":
                    console.error(".......");
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            "table-library-comparison-table": Vue.defineAsyncComponent(() =>
                loadModule(
                    "../wp-content/themes/cocoon-child-master/vue-components/table_library_comparison_table.vue",
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `<table-library-comparison-table />`,
    });
    app.mount("#app");
</script>



<p>カスタマイズの自由度では「vue-tables2（v-tables3）」が優れているのですが、Vue3の対応が不完全なので、総合的に「vue-good-table-next」を選びました。</p>



<h2 class="wp-block-heading"><span id="toc4">WordPressの投稿でvue-good-table-nextを使う</span></h2>



<p>上記の各種ライブラリの比較表の部分には、WordPressのブロックエディタで以下の「カスタム HTML」ブロックを配置しています。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js&quot;&gt;&lt;/script&gt;

&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;

&lt;script type=&quot;module&quot;&gt;
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from &quot;https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js&quot;;

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?\.js|.mjs$/.test(url)
                ? &quot;.mjs&quot;
                : /.*?\.vue$/.test(url)
                ? &quot;.vue&quot;
                : /.*?\.css$/.test(url)
                ? &quot;.css&quot;
                : &quot;.vue&quot;;
            const getContentData = (asBinary) =&gt;
                fetch(url).then((res) =&gt;
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement(&quot;style&quot;);
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName(&quot;style&quot;)[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case &quot;.css&quot;:
                    return options.addStyle(getContentData(false));
                case &quot;.less&quot;:
                    console.error(&quot;.......&quot;);
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            &quot;table-library-comparison-table&quot;: Vue.defineAsyncComponent(() =&gt;
                loadModule(
                    &quot;../wp-content/themes/cocoon-child-master/vue-components/table_library_comparison_table.vue&quot;,
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `&lt;table-library-comparison-table /&gt;`,
    });
    app.mount(&quot;#app&quot;);
&lt;/script&gt;</code></pre></div>



<p>いつものように、「vue3-sfc-loader」で"table_library_comparison_table.vue"を読み込んでいます。</p>



<h3 class="wp-block-heading"><span id="toc5">“table_library_comparison_table.vue”の中身</span></h3>



<p>"table_library_comparison_table.vue"の全体です。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script setup&gt;
////////////////////////////////////////////////////////////////////////////////
// vue-good-table-next モジュール
////////////////////////////////////////////////////////////////////////////////
import { VueGoodTable } from &quot;https://cdn.jsdelivr.net/npm/vue-good-table-next@0.1.0/dist/vue-good-table.cjs.min.js&quot;;

////////////////////////////////////////////////////////////////////////////////
// data
////////////////////////////////////////////////////////////////////////////////
const table_columns = [
    {
        label: &quot;比較項目&quot;,
        field: &quot;comparison_items&quot;,
        thClass: &quot;vgt-center-align vgt-comparison-items&quot;,
        tdClass: &quot;vgt-center-align vgt-comparison-items&quot;,
        sortable: true,
        html: true,
    },
    {
        label: &quot;vue-good-table-next&quot;,
        field: &quot;vue_good_table_next&quot;,
        thClass: &quot;vgt-center-align vgt-vue-good-table-next&quot;,
        tdClass: &quot;vgt-center-align vgt-vue-good-table-next&quot;,
        html: true,
    },
    {
        label: &quot;vue-tables2&quot;,
        field: &quot;vue_tables2&quot;,
        thClass: &quot;vgt-center-align vgt-vue-tables2&quot;,
        tdClass: &quot;vgt-center-align vgt-vue-tables2&quot;,
        html: true,
    },
    {
        label: &quot;Vuetable-2&quot;,
        field: &quot;vuetable_2&quot;,
        thClass: &quot;vgt-center-align vgt-vuetable-2&quot;,
        tdClass: &quot;vgt-center-align vgt-vuetable-2&quot;,
        html: true,
    },
    {
        label: &quot;Grid.js&quot;,
        field: &quot;grid_js&quot;,
        thClass: &quot;vgt-center-align vgt-grid-js&quot;,
        tdClass: &quot;vgt-center-align vgt-grid-js&quot;,
        html: true,
    },
];
const table_rows = Vue.ref([]);
const search_options = {
    enabled: true,
    trigger: &quot;enter&quot;,
    placeholder: &quot;テーブルを検索します&quot;,
};
const sort_options = {
    enabled: false,
};
const pagination_options = {
    enabled: true,
    mode: &quot;pages&quot;,
    perPage: -1, // -1のときは全項目
    position: &quot;top&quot;,
    perPageDropdown: [3, 5],
    dropdownAllowAll: true,
    setCurrentPage: 1,
    nextLabel: &quot;次へ&quot;,
    prevLabel: &quot;前へ&quot;,
    rowsPerPageLabel: &quot;1ページに表示する比較項目数&quot;,
    ofLabel: &quot; / &quot;,
    pageLabel: &quot;ページ&quot;, // for &#39;pages&#39; mode
    allLabel: &quot;全項目&quot;,
};

////////////////////////////////////////////////////////////////////////////////
// onMountedライフサイクルフック
////////////////////////////////////////////////////////////////////////////////
Vue.onMounted(() =&gt; {
    table_rows.value = [
        {
            comparison_items: &quot;Vue3対応&quot;,
            vue_good_table_next: &quot;〇&lt;br&gt;基本的な動作は安定&quot;,
            vue_tables2: &quot;&lt;span style=&#39;font-size: 1.2em;&#39;&gt;△&lt;/span&gt;&lt;br&gt;v-tables3で対応しているが不完全&quot;,
            vuetable_2: &quot;&lt;span style=&#39;font-size: 1.8em;&#39;&gt;×&lt;/span&gt;&quot;,
            grid_js: &quot;〇&lt;br&gt;オリジナルがJavaScriptライブラリなので、Vue3のコンポーネントでラップ可能&quot;
        },
        {
            comparison_items: &quot;ソート&quot;,
            vue_good_table_next: &quot;〇&quot;,
            vue_tables2: &quot;〇&quot;,
            vuetable_2: &quot;〇&quot;,
            grid_js: &quot;〇&quot;
        },
        {
            comparison_items: &quot;ページネーション&quot;,
            vue_good_table_next: &quot;〇&quot;,
            vue_tables2: &quot;〇&quot;,
            vuetable_2: &quot;〇&quot;,
            grid_js: &quot;〇&quot;
        },
        {
            comparison_items: &quot;グループ表示&quot;,
            vue_good_table_next: &quot;〇&quot;,
            vue_tables2: &quot;&lt;span style=&#39;font-size: 1.2em;&#39;&gt;◎&lt;/span&gt;&lt;br&gt;指定の要素で自動的にグループ化&quot;,
            vuetable_2: &quot;？&quot;,
            grid_js: &quot;&lt;span style=&#39;font-size: 1.8em;&#39;&gt;×&lt;/span&gt;&quot;
        },
        {
            comparison_items: &quot;ヘッダー/セルの&lt;br&gt;HTML対応&quot;,
            vue_good_table_next: &quot;〇&quot;,
            vue_tables2: &quot;〇&quot;,
            vuetable_2: &quot;〇&quot;,
            grid_js: &quot;〇&quot;
        },
        {
            comparison_items: &quot;テーブル構成の&lt;br&gt;カスタマイズ&quot;,
            vue_good_table_next: &quot;〇&lt;br&gt;ある程度可能&quot;,
            vue_tables2: &quot;&lt;span style=&#39;font-size: 1.2em;&#39;&gt;◎&lt;/span&gt;&lt;br&gt;カスタムテンプレートで自由度大&quot;,
            vuetable_2: &quot;？&quot;,
            grid_js: &quot;&lt;span style=&#39;font-size: 1.8em;&#39;&gt;×&lt;/span&gt;&quot;
        },
    ];
});
&lt;/script&gt;

&lt;template&gt;
    &lt;VueGoodTable v-bind:columns=&quot;table_columns&quot; v-bind:rows=&quot;table_rows&quot; v-bind:search-options=&quot;search_options&quot;
        v-bind:sort-options=&quot;sort_options&quot; v-bind:pagination-options=&quot;pagination_options&quot;&gt;
        &lt;template #table-column=&quot;props&quot;&gt;
            &lt;span v-if=&quot;props.column.label == &#39;vue-tables2&#39;&quot;&gt;
                {{ props.column.label }}&lt;br&gt;（v-tables3）
            &lt;/span&gt;
            &lt;span v-else&gt;
                {{ props.column.label }}
            &lt;/span&gt;
        &lt;/template&gt;
    &lt;/VueGoodTable&gt;
&lt;/template&gt;

&lt;style&gt;
@import &quot;https://cdn.jsdelivr.net/npm/vue-good-table-next@0.1.0/dist/vue-good-table-next.css&quot;;

table.vgt-table th,
table.vgt-table td {
    vertical-align: middle !important;
}

th.vgt-comparison-items {
    min-width: 10em !important;
}

th.vgt-vue-good-table-next,
th.vgt-vue-tables2,
th.vgt-vuetable-2,
th.vgt-grid-js {
    min-width: 15em !important;
}

td.vgt-vue-good-table-next,
td.vgt-vue-tables2,
td.vgt-vuetable-2,
td.vgt-grid-js {
    font-size: 0.8em;
}
&lt;/style&gt;</code></pre></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// vue-good-table-next モジュール
////////////////////////////////////////////////////////////////////////////////
import { VueGoodTable } from &quot;https://cdn.jsdelivr.net/npm/vue-good-table-next@0.1.0/dist/vue-good-table.cjs.min.js&quot;;
</code></pre></div>



<p>"vue-good-table-next"モジュールをCDNサイト「<a href="https://cdn.jsdelivr.net/npm/vue@next/dist/">https://cdn.jsdelivr.net<span class="fa fa-external-link external-icon anchor-icon"></span></a>」からインポートします。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;template&gt;
    &lt;VueGoodTable v-bind:columns=&quot;table_columns&quot; v-bind:rows=&quot;table_rows&quot; v-bind:search-options=&quot;search_options&quot;
        v-bind:sort-options=&quot;sort_options&quot; v-bind:pagination-options=&quot;pagination_options&quot;&gt;
        &lt;template #table-column=&quot;props&quot;&gt;
            &lt;span v-if=&quot;props.column.label == &#39;vue-tables2&#39;&quot;&gt;
                {{ props.column.label }}&lt;br&gt;（v-tables3）
            &lt;/span&gt;
            &lt;span v-else&gt;
                {{ props.column.label }}
            &lt;/span&gt;
        &lt;/template&gt;
    &lt;/VueGoodTable&gt;
&lt;/template&gt;</code></pre></div>



<p>インポートした"VueGoodTable"を&lt;template&gt;タグで配置します。</p>



<p>基本は、作成したSFCのローカル変数を"VueGoodTable"のプロパティーにバインドしているだけですが、</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>        &lt;template #table-column=&quot;props&quot;&gt;
            …
        &lt;/template&gt;
</code></pre></div>



<p>の部分については、「vue-good-table-next」の公式ドキュメントの「<a rel="noopener noreferrer" href="https://borisflesch.github.io/vue-good-table-next/guide/advanced/#custom-column-headers" target="_blank">Custom column headers<span class="fa fa-external-link external-icon anchor-icon"></span></a>」を参照してください。</p>



<p>また、テーブルのコンテンツ（"table_rows"）は、あえて"Vue.onMounted();"の中で設定しました。<br>実際の用途では、"table_rows"を動的に変更すると、テーブルのコンテンツがリアクティブに再表示されます。</p>



<h2 class="wp-block-heading"><span id="toc6">まとめ</span></h2>



<p>「vue-good-table-next」を使うと、WordPressの投稿に多機能なテーブルを手軽に実装できます。<br>しかも、Vueを使っているので、テーブルのコンテンツも簡単に更新/再表示ができます。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>


]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%bd%e3%83%bc%e3%83%88%e3%82%84%e3%83%9a%e3%83%bc%e3%82%b8%e3%83%8d%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e6%a9%9f%e8%83%bd%e3%82%92%e6%8c%81/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPressの投稿にVue3のSFCを読み込んでChart.jsのチャートを表示する</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%abvue3%e3%81%aesfc%e3%82%92%e8%aa%ad%e3%81%bf%e8%be%bc%e3%82%93%e3%81%a7chart-js%e3%81%ae%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e8%a1%a8%e7%a4%ba/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%abvue3%e3%81%aesfc%e3%82%92%e8%aa%ad%e3%81%bf%e8%be%bc%e3%82%93%e3%81%a7chart-js%e3%81%ae%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e8%a1%a8%e7%a4%ba/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Thu, 21 Apr 2022 12:38:47 +0000</pubDate>
				<category><![CDATA[Vue3]]></category>
		<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=10675</guid>

					<description><![CDATA[目次 環境Chart.jsとは？棒グラフを表示するコードの解説"bar_chart.vue"の中身ユーザーインターフェースで棒グラフを操作する"bar_chart_with_ui.vue"の中身まとめ 環境 このページで [&#8230;]]]></description>
										<content:encoded><![CDATA[



  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-12" checked><label class="toc-title" for="toc-checkbox-12">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">環境</a></li><li><a href="#toc2" tabindex="0">Chart.jsとは？</a></li><li><a href="#toc3" tabindex="0">棒グラフを表示する</a><ol><li><a href="#toc4" tabindex="0">コードの解説</a></li><li><a href="#toc5" tabindex="0">"bar_chart.vue"の中身</a></li></ol></li><li><a href="#toc6" tabindex="0">ユーザーインターフェースで棒グラフを操作する</a><ol><li><a href="#toc7" tabindex="0">"bar_chart_with_ui.vue"の中身</a></li></ol></li><li><a href="#toc8" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">環境</span></h2>



<p>このページで使用しているフレームワークやライブラリのバージョンは、以下のとおりです。</p>



<figure class="wp-block-table"><table><tbody><tr><td>vue.js</td><td>3.2.31</td></tr><tr><td>vue3-sfc-loader</td><td>0.8.4</td></tr><tr><td>chart.js</td><td>3.6.0</td></tr></tbody></table></figure>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box alert-box">
<p>この記事を書いた後、「<a rel="noopener noreferrer" href="https://vue-chartjs.org/" target="_blank">vue-chartjs<span class="fa fa-external-link external-icon anchor-icon"></span></a>」のバージョン5がリリースされました。<br>「vue-chartjs」バージョン5では、最新の「<a rel="noopener noreferrer" href="https://www.chartjs.org/" target="_blank">Chart.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>」バージョン4をサポートしています。<br>「Chart.js」バージョン4では、チャートのDataやOptionsが変更された場合、再描画するようになりました。なので、この記事で紹介した「Chart.js」を直接ラップする方法より、「vue-chartjs」バージョン5を利用した方が簡単で便利です。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-official">

<a rel="noopener noreferrer" href="https://vue-chartjs.org/" title="&#128200; vue-chartjs" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fvue-chartjs.org%2F?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">&#128200; vue-chartjs</div><div class="blogcard-snippet external-blogcard-snippet">⚡ Easy and beautiful charts with Chart.js and Vue.js</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vue-chartjs.org/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">vue-chartjs.org</div></div></div></div></a>
</div>
</div>



<h2 class="wp-block-heading"><span id="toc2">Chart.jsとは？</span></h2>



<p>「<a rel="noopener noreferrer" href="https://www.chartjs.org/" target="_blank">Chart.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>」は、チャート（グラフ）を表示するJavaScriptライブラリです。<br />機能の豊富さと表示の美しさで、この「Chart.js」を越えるJavaScriptライブラリはないと思います。<br />MITライセンスで、無償で利用できます。</p>
<p>2021年の4月に、メジャーバージョンが「2.x」から「3.x」に変わり、<a rel="noopener noreferrer" href="https://www.chartjs.org/docs/latest/getting-started/v3-migration.html" target="_blank">仕様も大きく変わっています<span class="fa fa-external-link external-icon anchor-icon"></span></a>。<br />なので、今から「Chart.js」を利用する方は、バージョン「3.x」を使うことをお勧めします。</p>
<p>Vue3で「Chart.js」を使えるようにしたコンポーネント「<a rel="noopener noreferrer" href="https://vue-chartjs.org/" target="_blank">vue-chartjs<span class="fa fa-external-link external-icon anchor-icon"></span></a>」もあります。<br />「vue-chartjs」のバージョン「4.x」から、「Chart.js」のバージョン「3.x」に対応しているので、Vueの環境で簡単に「Chart.js」を使いたい場合は、「vue-chartjs」を利用すると良いでしょう。</p>
<p>ただし、「vue-chartjs」のバージョン「4.0.5」では、ドキュメントに以下の記載があり、チャートのOptionsを変更しても、チャートが再描画されません。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong><span class="fz-22px">Options</span></strong><br>The options object is not currently implemented reactively. Therefore, if you dynamically change the chart options, they will not be recognized by the update data handler.</p>
</blockquote>



<p>なので、この記事では「vue-chartjs」を使わず、「Chart.js」を直接ラップしたSFCを作成し、このコンポーネントでチャートを表示します。</p>



<p>WordPressの投稿にVueのSFCを読み込む方法については、以下の記事で紹介しています。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e7%92%b0%e5%a2%83%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88/" title="WordPressのサイトでVue3の単一ファイルコンポーネントを使う" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/11d1f1030333d800c479e7742dd73450.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">WordPressのサイトでVue3の単一ファイルコンポーネントを使う</div><div class="blogcard-snippet external-blogcard-snippet">「vue3-sfc-loader」を使うと、「Node.js」が無いブラウザ環境でもVue3の単一ファイルコンポーネントを使うことができます。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88%e3%82%92/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">vitorec.co.jp</div></div></div></div></a>
</div>



<h2 class="wp-block-heading"><span id="toc3">棒グラフを表示する</span></h2>



<p>まずは、簡単な棒グラフを表示してみましょう。<br>このチャートは、「Chart.js」の<a rel="noopener noreferrer" href="https://www.chartjs.org/docs/latest/" target="_blank">ドキュメント<span class="fa fa-external-link external-icon anchor-icon"></span></a>の最初の例に出てくる棒グラフです。</p>



<script src="https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js"></script>

<div id="app"></div>

<script type="module">
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from "https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js";

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?\.js|.mjs$/.test(url)
                ? ".mjs"
                : /.*?\.vue$/.test(url)
                ? ".vue"
                : /.*?\.css$/.test(url)
                ? ".css"
                : ".vue";
            const getContentData = (asBinary) =>
                fetch(url).then((res) =>
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement("style");
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName("style")[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case ".css":
                    return options.addStyle(getContentData(false));
                case ".less":
                    console.error(".......");
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            "bar-chart": Vue.defineAsyncComponent(() =>
                loadModule(
                    "../wp-content/themes/cocoon-child-master/vue-components/bar_chart.vue",
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `<bar-chart />`,
    });
    app.mount("#app");
</script>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>チャートが表示されている部分には、WordPressのブロックエディタで以下の「カスタム HTML」ブロックを配置しています。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js&quot;&gt;&lt;/script&gt;

&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;

&lt;script type=&quot;module&quot;&gt;
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from &quot;https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js&quot;;

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?\.js|.mjs$/.test(url)
                ? &quot;.mjs&quot;
                : /.*?\.vue$/.test(url)
                ? &quot;.vue&quot;
                : /.*?\.css$/.test(url)
                ? &quot;.css&quot;
                : &quot;.vue&quot;;
            const getContentData = (asBinary) =&gt;
                fetch(url).then((res) =&gt;
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement(&quot;style&quot;);
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName(&quot;style&quot;)[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case &quot;.css&quot;:
                    return options.addStyle(getContentData(false));
                case &quot;.less&quot;:
                    console.error(&quot;.......&quot;);
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            &quot;bar-chart&quot;: Vue.defineAsyncComponent(() =&gt;
                loadModule(
                    &quot;../wp-content/themes/cocoon-child-master/vue-components/bar_chart.vue&quot;,
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `&lt;bar-chart /&gt;`,
    });
    app.mount(&quot;#app&quot;);
&lt;/script&gt;</code></pre></div>



<h3 class="wp-block-heading"><span id="toc4">コードの解説</span></h3>



<p>前回の紹介記事「<a href="https://vitorec.co.jp/choi-plus-sozai/%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e7%92%b0%e5%a2%83%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88/" target="_blank">ブラウザ環境でVue3の単一ファイルコンポーネントを使う</a>」からの差分を中心に解説します。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            &quot;bar-chart&quot;: Vue.defineAsyncComponent(() =&gt;
                loadModule(
                    &quot;../wp-content/themes/cocoon-child-master/vue-components/bar_chart.vue&quot;,
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `&lt;bar-chart /&gt;`,
    });
    app.mount(&quot;#app&quot;);
</code></pre></div>



<p>アプリケーションインスタンスの作成とマウントの方法は、前回の「<a href="https://vitorec.co.jp/choi-plus-sozai/%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e7%92%b0%e5%a2%83%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88/" target="_blank">ブラウザ環境でVue3の単一ファイルコンポーネントを使う</a>」と同じ流れです。<br>違うのは、"bar_chart.vue"というSFCを"bar-chart"という名前のコンポーネントとして読み込んで、`&lt;bar-chart /&gt;`で表示している点です。</p>



<h3 class="wp-block-heading"><span id="toc5">"bar_chart.vue"の中身</span></h3>



<p>"bar_chart.vue"の全体です。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script setup&gt;
////////////////////////////////////////////////////////////////////////////////
// Chart.js モジュール
////////////////////////////////////////////////////////////////////////////////
// Chart.jsモジュールのimportとregisterを行う
import { Chart, registerables } from &quot;../chart.js-3.6.0/dist/chart.esm.js&quot;;
Chart.register(...registerables);

////////////////////////////////////////////////////////////////////////////////
// data
////////////////////////////////////////////////////////////////////////////////
let chart = {}; // チャートオブジェクト
const chart_height = 400; // チャートの高さ
let chart_options = { // チャートのオプション
    scales: {
        y: {
            beginAtZero: true
        }
    },
};
let chart_data = { // チャートのデータ
    labels: [&quot;Red&quot;, &quot;Blue&quot;, &quot;Yellow&quot;, &quot;Green&quot;, &quot;Purple&quot;, &quot;Orange&quot;],
    datasets: [{
        label: &quot;# of Votes&quot;,
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: [
            &quot;rgba(255, 99, 132, 0.2)&quot;,
            &quot;rgba(54, 162, 235, 0.2)&quot;,
            &quot;rgba(255, 206, 86, 0.2)&quot;,
            &quot;rgba(75, 192, 192, 0.2)&quot;,
            &quot;rgba(153, 102, 255, 0.2)&quot;,
            &quot;rgba(255, 159, 64, 0.2)&quot;
        ],
        borderColor: [
            &quot;rgba(255, 99, 132, 1)&quot;,
            &quot;rgba(54, 162, 235, 1)&quot;,
            &quot;rgba(255, 206, 86, 1)&quot;,
            &quot;rgba(75, 192, 192, 1)&quot;,
            &quot;rgba(153, 102, 255, 1)&quot;,
            &quot;rgba(255, 159, 64, 1)&quot;
        ],
        borderWidth: 1
    }]
};

////////////////////////////////////////////////////////////////////////////////
// onMountedライフサイクルフック
////////////////////////////////////////////////////////////////////////////////
Vue.onMounted(() =&gt; {
    renderChart();
});

////////////////////////////////////////////////////////////////////////////////
// チャートを描画する
////////////////////////////////////////////////////////////////////////////////
const renderChart = () =&gt; {
    const ctx = document.getElementById(&quot;chart&quot;).getContext(&quot;2d&quot;);
    chart = new Chart(ctx, {
        type: &quot;bar&quot;,
        data: chart_data,
        options: chart_options,
    });
};
&lt;/script&gt;

&lt;template&gt;
    &lt;div&gt;
        &lt;canvas id=&quot;chart&quot; width=&quot;100%&quot; v-bind:height=&quot;chart_height&quot;&gt;&lt;/canvas&gt;
    &lt;/div&gt;
&lt;/template&gt;

&lt;style&gt;
&lt;/style&gt;</code></pre></div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p>"bar_chart.vue"のセットアップは、</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script&gt;
export default defineComponent({
    setup() {
        …
    },
});
&lt;/script&gt;</code></pre></div>



<p>を使わずに、</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script setup&gt;
    …
&lt;/script&gt;</code></pre></div>



<p>の中でやっています。</p>



<p>&lt;script setup&gt;については、Vue3の公式ドキュメント「<a rel="noopener noreferrer" href="https://v3.ja.vuejs.org/api/sfc-script-setup.html" target="_blank">SFC&lt;script setup&gt;<span class="fa fa-external-link external-icon anchor-icon"></span></a>」を参照してください。<br>&lt;script setup&gt;の利便性については、以下の記事が参考になります。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-reference">

<a rel="noopener noreferrer" href="https://zenn.dev/azukiazusa/articles/676d88675e4e74" title="【Vue.js 3.2】`` 構文がすごくすごい" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/d508310b83eec34aeaa616c715f5bd29.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">【Vue.js 3.2】`` 構文がすごくすごい</div><div class="blogcard-snippet external-blogcard-snippet"></div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://zenn.dev/azukiazusa/articles/676d88675e4e74" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">zenn.dev</div></div></div></div></a>
</div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// Chart.js モジュール
////////////////////////////////////////////////////////////////////////////////
// Chart.jsモジュールのimportとregisterを行う
import { Chart, registerables } from &quot;../chart.js-3.6.0/dist/chart.esm.js&quot;;
Chart.register(...registerables);</code></pre></div>



<p>「Chart.js」ライブラリ一式をCDNサイト「<a rel="noopener noreferrer" href="https://www.jsdelivr.com/package/npm/chart.js" target="_blank">https://www.jsdelivr.com/package/npm/chart.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>」からダウンロードして、適当なフォルダに保存します。<br>「ちょいプラ素材」のブログは、WordPressのテーマに「<a rel="noopener noreferrer" href="https://wp-cocoon.com/" target="_blank">Cocoon<span class="fa fa-external-link external-icon anchor-icon"></span></a>」を使っています。<br>今回は、「<a rel="noopener noreferrer" href="https://wp-cocoon.com/" target="_blank">Cocoon<span class="fa fa-external-link external-icon anchor-icon"></span></a>」の子テーマ「<a rel="noopener noreferrer" href="https://wp-cocoon.com/downloads/#toc3" target="_blank">cocoon-child-master<span class="fa fa-external-link external-icon anchor-icon"></span></a>」の下に"chart.js-3.6.0"というフォルダを作って保存しました。</p>



<p>SFC"bar_chart.vue"が保存されているフォルダからの相対パス"../chart.js-3.6.0/dist/chart.esm.js"で「Chart.js」のESモジュール"chart.esm.js"をインポートします。</p>



<p>「Chart.js」モジュールをインポートした後は、実際に利用するモジュールの登録（register）が必要です。1つ1つのモジュールを登録するのは面倒なので、"Chart.register(...registerables);"でまとめて登録しています。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// data
////////////////////////////////////////////////////////////////////////////////
let chart = {}; // チャートオブジェクト
const chart_height = 400; // チャートの高さ
let chart_options = { // チャートのオプション
    …
};
let chart_data = { // チャートのデータ
    …
};</code></pre></div>



<p>このSFCだけで使うデータを宣言しています。<br>それぞれのデータの意味は、コメントを見てください。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// onMountedライフサイクルフック
////////////////////////////////////////////////////////////////////////////////
Vue.onMounted(() =&gt; {
    renderChart();
});</code></pre></div>



<p>このSFCがマウントされたときに呼ばれる、ライフサイクルフックです。<br>SFCがマウントされたら、この後に説明する"renderChart();"を実行します。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// チャートを描画する
////////////////////////////////////////////////////////////////////////////////
const renderChart = () =&gt; {
    const ctx = document.getElementById(&quot;chart&quot;).getContext(&quot;2d&quot;);
    chart = new Chart(ctx, {
        type: &quot;bar&quot;,
        data: chart_data,
        options: chart_options,
    });
};</code></pre></div>



<p>チャートを描画する処理です。<br>この後の&lt;template&gt;タグで配置される&lt;canvas id="chart"&gt;要素に「Chart.js」の"bar"モジュール（棒グラフモジュール）を紐づけます。<br><br>また、"chart = new Chart();"で作成した「Chart.js」のモジュール（JavaScriptのオブジェクト）を変数"chart"に保存しておきます。<br>こうすることで、「Chart.js」のメソッド（関数）を使って、作成した"bar"モジュールを操作することができます。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;template&gt;
    &lt;div&gt;
        &lt;canvas id=&quot;chart&quot; width=&quot;100%&quot; v-bind:height=&quot;chart_height&quot;&gt;&lt;/canvas&gt;
    &lt;/div&gt;
&lt;/template&gt;</code></pre></div>



<p>&lt;template&gt;タグで&lt;canvas id="chart"&gt;要素を配置します。</p>



<h2 class="wp-block-heading"><span id="toc6">ユーザーインターフェースで棒グラフを操作する</span></h2>



<p>次に、先ほどの棒グラフを表示するSFCにユーザーインターフェースを追加して、チャートを操作してみましょう。<br>ユーザーインターフェースとデータの連携は、Vueが得意とするところです。</p>



<div id="app2"></div>

<script type="module">
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from "https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js";

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?\.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?\.js|.mjs$/.test(url)
                ? ".mjs"
                : /.*?\.vue$/.test(url)
                ? ".vue"
                : /.*?\.css$/.test(url)
                ? ".css"
                : ".vue";
            const getContentData = (asBinary) =>
                fetch(url).then((res) =>
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement("style");
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName("style")[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case ".css":
                    return options.addStyle(getContentData(false));
                case ".less":
                    console.error(".......");
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            "bar-chart": Vue.defineAsyncComponent(() =>
                loadModule(
                    "../wp-content/themes/cocoon-child-master/vue-components/bar_chart_with_ui.vue",
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `<bar-chart />`,
    });
    app.mount("#app2");
</script>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>［データを変更］ボタンを押すと、データが0～50の範囲の整数にランダムに変化します。<br>［縦軸の最大値］スライダーを動かすと、チャートの縦軸の最大値を変更できます。</p>



<h3 class="wp-block-heading"><span id="toc7">"bar_chart_with_ui.vue"の中身</span></h3>



<p>新しく作成したSFC"bar_chart_with_ui.vue"の全体です。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script setup&gt;
////////////////////////////////////////////////////////////////////////////////
// Chart.js モジュール
////////////////////////////////////////////////////////////////////////////////
// Chart.jsモジュールのimportとregisterを行う
import { Chart, registerables } from &quot;../chart.js-3.6.0/dist/chart.esm.js&quot;;
Chart.register(...registerables);

////////////////////////////////////////////////////////////////////////////////
// data
////////////////////////////////////////////////////////////////////////////////
let chart = {}; // チャートオブジェクト
const chart_height = 400; // チャートの高さ
let y_max = Vue.ref(50); // 縦軸の最大値
let chart_options = { // チャートのオプション
    scales: {
        y: {
            beginAtZero: true,
            min: 0,
            max: y_max.value,
        }
    },
};
let chart_data = { // チャートのデータ
    labels: [&quot;Red&quot;, &quot;Blue&quot;, &quot;Yellow&quot;, &quot;Green&quot;, &quot;Purple&quot;, &quot;Orange&quot;],
    datasets: [{
        label: &quot;# of Votes&quot;,
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: [
            &quot;rgba(255, 99, 132, 0.2)&quot;,
            &quot;rgba(54, 162, 235, 0.2)&quot;,
            &quot;rgba(255, 206, 86, 0.2)&quot;,
            &quot;rgba(75, 192, 192, 0.2)&quot;,
            &quot;rgba(153, 102, 255, 0.2)&quot;,
            &quot;rgba(255, 159, 64, 0.2)&quot;
        ],
        borderColor: [
            &quot;rgba(255, 99, 132, 1)&quot;,
            &quot;rgba(54, 162, 235, 1)&quot;,
            &quot;rgba(255, 206, 86, 1)&quot;,
            &quot;rgba(75, 192, 192, 1)&quot;,
            &quot;rgba(153, 102, 255, 1)&quot;,
            &quot;rgba(255, 159, 64, 1)&quot;
        ],
        borderWidth: 1
    }]
};

////////////////////////////////////////////////////////////////////////////////
// onMountedライフサイクルフック
////////////////////////////////////////////////////////////////////////////////
Vue.onMounted(() =&gt; {
    renderChart();
});

////////////////////////////////////////////////////////////////////////////////
// チャートを描画する
////////////////////////////////////////////////////////////////////////////////
const renderChart = () =&gt; {
    const ctx = document.getElementById(&quot;chart2&quot;).getContext(&quot;2d&quot;);
    chart = new Chart(ctx, {
        type: &quot;bar&quot;,
        data: chart_data,
        options: chart_options,
    });
};

////////////////////////////////////////////////////////////////////////////////
// チャートのデータを変更する
////////////////////////////////////////////////////////////////////////////////
const onChangeData = () =&gt; {
    chart_data.datasets[0].data = [
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
    ];
    chart.update(); // チャートを再描画する
};

////////////////////////////////////////////////////////////////////////////////
// 縦軸の最大値を変更する
////////////////////////////////////////////////////////////////////////////////
const onChangeYMax = () =&gt; {
    chart_options.scales.y.max = y_max.value;
    chart.update(); // チャートを再描画する
};
&lt;/script&gt;

&lt;template&gt;
    &lt;div&gt;
        &lt;canvas id=&quot;chart2&quot; width=&quot;100%&quot; v-bind:height=&quot;chart_height&quot;&gt;&lt;/canvas&gt;
        &lt;form class=&quot;chart-ui-form&quot;&gt;
            &lt;input type=&quot;button&quot; class=&quot;data-change-button&quot; v-on:click=&quot;onChangeData&quot; value=&quot;データを変更&quot; /&gt;
            &lt;div class=&quot;chart-range-container&quot;&gt;
                &lt;span style=&quot;margin-right: 0.2em&quot;&gt;縦軸の最大値　10&lt;/span&gt;
                &lt;input type=&quot;range&quot; id=&quot;view-time-start-range&quot; class=&quot;y-max-range&quot; v-model.number=&quot;y_max&quot; min=&quot;10&quot;
                    max=&quot;100&quot; step=&quot;10&quot; v-on:mouseup=&quot;onChangeYMax&quot; v-on:touchend=&quot;onChangeYMax&quot; /&gt;
                &lt;span style=&quot;margin-left: 0.2em&quot;&gt;100&lt;/span&gt;
            &lt;/div&gt;
        &lt;/form&gt;
    &lt;/div&gt;
&lt;/template&gt;

&lt;style&gt;
.chart-ui-form {
    margin: 20px;
}

.chart-range-container {
    margin-left: 10px;
    margin-top: 10px;
}

.data-change-button {
    color: #fff;
    background-color: #3b83d8;
    font-weight: bold;
    border-radius: 4px;
    display: inline-block;
    cursor: pointer;
    line-height: normal;
    padding: 7px 13px;
    text-decoration: none;
    text-align: center;
    font-size: 14px;
    border: 2px solid transparent;
    position: relative;
}

.y-max-range {
    max-width: 40%;
    width: 40%;
}
&lt;/style&gt;</code></pre></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>SFCの変更点を解説します。</p>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>let y_max = Vue.ref(50); // 縦軸の最大値
let chart_options = { // チャートのオプション
    scales: {
        y: {
            beginAtZero: true,
            min: 0,
            max: y_max.value,
        }
    },
};</code></pre></div>



<p>チャートのオプションを指定する"chart_options"の"scale.y"オブジェクトに、"min"と"max"を追加しました。<br>"min"、"max"を指定しない場合は、データの値に応じて、「Chart.js」が軸の表示を最適に調整してくれます。</p>



<p>"max"には、新しく追加した変数"y_max"の値を設定します。<br>また、変数"y_max"は、Vueの「<a rel="noopener noreferrer" href="https://v3.ja.vuejs.org/guide/reactivity-fundamentals.html#%E3%83%AA%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%95%E3%82%99%E3%81%AA%E7%8A%B6%E6%85%8B%E3%81%AE%E5%AE%A3%E8%A8%80" target="_blank">refメソッド<span class="fa fa-external-link external-icon anchor-icon"></span></a>」でリアクティブな変数にしています。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// チャートのデータを変更する
////////////////////////////////////////////////////////////////////////////////
const onChangeData = () =&gt; {
    chart_data.datasets[0].data = [
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
        Math.floor(Math.random() * 51),
    ];
    chart.update(); // チャートを再描画する
};</code></pre></div>



<p>［データを変更］ボタンが押されたときに呼ばれるイベントハンドラーです。<br>チャートのデータが0～50の範囲の整数にランダムに変化します。<br>実際の用途では、チャートに表示したいデータの設定処理を実装します。</p>



<p>その後、"chart.update();"でチャートを再描画します。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>////////////////////////////////////////////////////////////////////////////////
// 縦軸の最大値を変更する
////////////////////////////////////////////////////////////////////////////////
const onChangeYMax = () =&gt; {
    chart_options.scales.y.max = y_max.value;
    chart.update(); // チャートを再描画する
};</code></pre></div>



<p>［縦軸の最大値］スライダーを動かした後、マウスのボタンを離すと呼ばれるイベントハンドラーです。<br>チャートのオプション"chart_options.scales.y.max"の値を変更した後、"chart.update();"でチャートを再描画します。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;template&gt;
    …
&lt;/template&gt;

&lt;style&gt;
    …
&lt;/style&gt;</code></pre></div>



<p>&lt;template&gt;タグと&lt;style&gt;タグで、SFCの外観（ビュー）を定義します。</p>



<p>以上のように、VueのSFCを使うと、</p>



<ul class="wp-block-list">
<li>ユーザーインターフェースの操作をトリガーにして、</li>



<li>必要なデータやオプションを変更し、</li>



<li>「Chart.js」のupdate()メソッドを呼び出すだけで、</li>
</ul>



<p>チャートの表示を動的に、しかも簡単に操作できます。</p>



<h2 class="wp-block-heading"><span id="toc8">まとめ</span></h2>



<p>「Chart.js」を直接ラップしたSFCを作成し、コンポーネントでチャートを表示する方法を紹介しました。</p>



<p>チャートのデータやオプションを動的に変えることができるので、WordPressのデータベースのデータをビジュアルに表示したり、データが保存されているCSVファイルをアップロードして、CSVファイルのデータをチャートで確認したり、いろいろなシチュエーションで活用できるはずです。</p>



<p>次は、WordPressの投稿に「<a rel="noopener noreferrer" href="https://borisflesch.github.io/vue-good-table-next/" target="_blank">vue-good-table-next<span class="fa fa-external-link external-icon anchor-icon"></span></a>」のテーブルを表示してみましょう。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%bd%e3%83%bc%e3%83%88%e3%82%84%e3%83%9a%e3%83%bc%e3%82%b8%e3%83%8d%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e6%a9%9f%e8%83%bd%e3%82%92%e6%8c%81/" title="WordPressの投稿にソートやページネーションの機能を持ったテーブルを実装する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">WordPressの投稿にソートやページネーションの機能を持ったテーブルを実装する</div><div class="blogcard-snippet internal-blogcard-snippet">VueのSFCを介して「vue-good-table-next」を使うと、WordPressの投稿に多機能なテーブルを手軽に実装できます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.07.25</div></div></div></div></a>
</div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%abvue3%e3%81%aesfc%e3%82%92%e8%aa%ad%e3%81%bf%e8%be%bc%e3%82%93%e3%81%a7chart-js%e3%81%ae%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e8%a1%a8%e7%a4%ba/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WordPressのサイトでVue3の単一ファイルコンポーネントを使う</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88%e3%82%92/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88%e3%82%92/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Wed, 20 Apr 2022 09:52:07 +0000</pubDate>
				<category><![CDATA[Vue3]]></category>
		<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=10600</guid>

					<description><![CDATA[目次 環境Vueのコンポーネントとは？単一ファイルコンポーネントとは？ブラウザ環境で単一ファイルコンポーネントを使うには？「vue3-sfc-loader」の使い方コードの解説"hello_world.vue"の中身まと [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-14" checked><label class="toc-title" for="toc-checkbox-14">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">環境</a></li><li><a href="#toc2" tabindex="0">Vueのコンポーネントとは？</a></li><li><a href="#toc3" tabindex="0">単一ファイルコンポーネントとは？</a></li><li><a href="#toc4" tabindex="0">ブラウザ環境で単一ファイルコンポーネントを使うには？</a></li><li><a href="#toc5" tabindex="0">「vue3-sfc-loader」の使い方</a><ol><li><a href="#toc6" tabindex="0">コードの解説</a></li><li><a href="#toc7" tabindex="0">"hello_world.vue"の中身</a></li></ol></li><li><a href="#toc8" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">環境</span></h2>



<p>このページで使用しているフレームワークやライブラリのバージョンは、以下のとおりです。</p>



<figure class="wp-block-table"><table><tbody><tr><td>vue.js</td><td>3.2.31</td></tr><tr><td>vue3-sfc-loader</td><td>0.8.4</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><span id="toc2">Vueのコンポーネントとは？</span></h2>



<p>Vueでは、大きなアプリケーション（下図の左側）を小さな部品の組み合わせで構成（下図の右側）することができます。<br>この小さな部品（下図の緑色の箱）に相当するのがコンポーネントです。</p>



<figure class="wp-block-image size-full"><a href="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400.png"><img loading="lazy" decoding="async" width="1406" height="544" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400.png" alt="" class="wp-image-14533" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400.png 1406w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400-500x193.png 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400-800x310.png 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400-300x116.png 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2025/10/e775493df2d4f350fa43ae9e3ce78400-768x297.png 768w" sizes="(max-width: 1406px) 100vw, 1406px" /></a></figure>



<p>詳しくは、Vueの公式ドキュメント「<a rel="noopener noreferrer" href="https://v3.ja.vuejs.org/guide/introduction.html#%E3%82%B3%E3%83%B3%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AB%E3%82%88%E3%82%8B%E6%A7%8B%E6%88%90" target="_blank">コンポーネントによる構成<span class="fa fa-external-link external-icon anchor-icon"></span></a>」を参照してください。</p>



<h2 class="wp-block-heading"><span id="toc3">単一ファイルコンポーネントとは？</span></h2>



<p><a rel="noopener noreferrer" href="https://v3.ja.vuejs.org/guide/single-file-component.html" target="_blank">単一ファイルコンポーネント<span class="fa fa-external-link external-icon anchor-icon"></span></a>（Single-File Component：以後SFCと呼ぶ）は、Vueを使う上で、とても便利な仕組みです。</p>
<p>SFCは、下図のように、「JavaScript：&lt;script&gt;タグ」「HTML：&lt;template&gt;タグ」「CSS：&lt;style&gt;タグ」を1つにまとめて記述したファイルのことです。<br>このファイルの拡張子は「*.vue」で、SFCのことを、別名「*.vue」ファイルということがあります。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="601" height="541" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC.png" alt="" class="wp-image-10606" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC.png 601w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC-500x450.png 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC-300x270.png 300w" sizes="(max-width: 601px) 100vw, 601px" /></figure>



<p>SFCの「JavaScript：&lt;script&gt;タグ」でコンポーネントの動作や処理を記述することができ、「HTML：&lt;template&gt;タグ」「CSS：&lt;style&gt;タグ」でコンポーネントの外観を指定することができます。<br>つまり、「*.vue」ファイル1つで、コンポーネントの動作と外観が規定できるということです。</p>



<p>大きなアプリケーションを小さなコンポーネントに分解すれば、ソースコードの可読性も上がりますし、メンテナンスも容易になります。</p>



<p>また、このSFCに汎用性を持たせて、再利用できるように作っておけば、いろいろなアプリケーションで流用できます。</p>



<h2 class="wp-block-heading"><span id="toc4">ブラウザ環境で単一ファイルコンポーネントを使うには？</span></h2>



<p>とっても便利なSFCなのですが、ブラウザ環境で動作するJavaScriptでは、「*.vue」ファイルをそのまま読み込むことができません。</p>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box information-box">
<p>サーバーの「Node.js」にインストールした「weback」や「Vue CLI」、「Vite」などの開発環境では、「*.vue」ファイルを直接読み込むことができます。</p>
</div>



<p>Vueの便利な機能の1つであるSFCが使えないのは、とても残念です。</p>



<p>ところが、「<a rel="noopener noreferrer" href="https://github.com/FranckFreiburger/vue3-sfc-loader" target="_blank">vue3-sfc-loader<span class="fa fa-external-link external-icon anchor-icon"></span></a>」というライブラリを使えば、ブラウザ環境でも「*.vue」ファイルを直接読み込んで、SFCの仕組みを活用することができます。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Vue3/Vue2 Single File Component loader.</p>



<p>Load .vue files dynamically at runtime from your html/js. No node.js environment, no (webpack) build step needed.</p>
</blockquote>



<p>上記「vue3-sfc-loader」の概要にも書いてあるように、"<span class="marker-under-red">No node.js environment, no (webpack) build step needed.</span>"、つまり、「Node.js」も「webpack」も無いブラウザ環境で、VueのSFCを使えるようになります。<br>ブラウザ環境で、SFCがサクッと使えるようになると、WordPressサイトのような「Node.js」の無い環境で、Vueの便利さと簡便さが最大限発揮できると思います。</p>



<p>「vue3-sfc-loader」のオプションを工夫すると、読み込んだ「*.vue」ファイルから、別の「*.vue」ファイルを読み込んだり、外部サイトのJavaScriptライブラリをインポートすることもできます。</p>



<h2 class="wp-block-heading"><span id="toc5">「vue3-sfc-loader」の使い方</span></h2>



<p>実際に、「vue3-sfc-loader」を使って、SFCを読み込んでみましょう。</p>



<script src="https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js"></script>

<div id="app"></div>

<script type="module">
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from "https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js";

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?.js|.mjs$/.test(url)
                ? ".mjs"
                : /.*?.vue$/.test(url)
                ? ".vue"
                : /.*?.css$/.test(url)
                ? ".css"
                : ".vue";
            const getContentData = (asBinary) =>
                fetch(url).then((res) =>
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement("style");
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName("style")[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case ".css":
                    return options.addStyle(getContentData(false));
                case ".less":
                    console.error(".......");
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            "hello-world": Vue.defineAsyncComponent(() =>
                loadModule(
                    "../wp-content/themes/cocoon-child-master/vue-components/hello_world.vue",
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `<hello-world />`,
    });
    app.mount("#app");
</script>



<p>どうでしょうか？<br>赤い文字で「<strong style="color:red">Hello World!</strong>」と表示されましたか？</p>



<p>「<strong style="color:red">Hello World!</strong>」と表示されている部分には、WordPressのブロックエディタで「カスタム HTML」ブロックを配置しています。</p>



<p>「カスタム HTML」ブロックには、以下のHTMLコードを入力します。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js&quot;&gt;&lt;/script&gt;

&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;

&lt;script type=&quot;module&quot;&gt;
    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from &quot;https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js&quot;;

    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?.js|.mjs$/.test(url)
                ? &quot;.mjs&quot;
                : /.*?.vue$/.test(url)
                ? &quot;.vue&quot;
                : /.*?.css$/.test(url)
                ? &quot;.css&quot;
                : &quot;.vue&quot;;
            const getContentData = (asBinary) =&gt;
                fetch(url).then((res) =&gt;
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement(&quot;style&quot;);
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName(&quot;style&quot;)[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case &quot;.css&quot;:
                    return options.addStyle(getContentData(false));
                case &quot;.less&quot;:
                    console.error(&quot;.......&quot;);
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };

    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            &quot;hello-world&quot;: Vue.defineAsyncComponent(() =&gt;
                loadModule(
                    &quot;../wp-content/themes/cocoon-child-master/vue-components/hello_world.vue&quot;,
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `&lt;hello-world /&gt;`,
    });
    app.mount(&quot;#app&quot;);
&lt;/script&gt;</code></pre></div>



<h3 class="wp-block-heading"><span id="toc6">コードの解説</span></h3>



<p>では、コードの中身を解説します。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.global.js&quot;&gt;&lt;/script&gt;</code></pre></div>



<p>VueをCDNサイト「<a href="https://cdn.jsdelivr.net/npm/vue@next/dist/">https://cdn.jsdelivr.net<span class="fa fa-external-link external-icon anchor-icon"></span></a>」からインポートします。<br>"vue@3.2.31"なので、メジャーバージョンが「3」です。<br>なので、Vue3を読み込んでいます。</p>



<p>投稿やページの最初に1回インポートすれば、それ以降、Vueのメソッド（関数）は、"Vue.createApp();"のように「Vue.func()」で利用できます。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;</code></pre></div>



<p>Vueのアプリケーションインスタンスをマウントする&lt;div&gt;タグを"app"というidで配置します。<br>この&lt;div&gt;要素が、この後に読み込むSFC、"hello_world.vue"で置き換えられます。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script type=&quot;module&quot;&gt;
　…
&lt;script&gt;</code></pre></div>



<p>&lt;script type="module"&gt;～&lt;/script&gt;が、SFCを読み込むJavaScriptになります。<br>JavaScriptでimport文を使うので、「type="module"」にします。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader モジュール
    ////////////////////////////////////////////////////////////////////////////////
    import { loadModule } from &quot;https://cdn.jsdelivr.net/npm/vue3-sfc-loader@0.8.4/dist/vue3-sfc-loader.esm.js&quot;;
</code></pre></div>



<p>「vue3-sfc-loader」をCDNサイト「<a href="https://cdn.jsdelivr.net/npm/vue@next/dist/">https://cdn.jsdelivr.net<span class="fa fa-external-link external-icon anchor-icon"></span></a>」からインポートします。<br>ファイル名が"vue3-sfc-loader.esm.js"になっていて、"esm"という文字列が入っています。<br>これは、import文でインポートできる「ESモジュール」であることを示しています。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>    ////////////////////////////////////////////////////////////////////////////////
    // vue3-sfc-loader オプション
    // SFCファイルから外部のモジュールをimportできるオプション
    // 参考：https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863
    ////////////////////////////////////////////////////////////////////////////////
    const vue3_sfc_loader_options = {
        moduleCache: { vue: Vue },
        getFile(url) {
            url = /.*?.js|.mjs|.css|.less|.vue$/.test(url)
                ? url
                : `${url}.vue`;
            const type = /.*?.js|.mjs$/.test(url)
                ? &quot;.mjs&quot;
                : /.*?.vue$/.test(url)
                ? &quot;.vue&quot;
                : /.*?.css$/.test(url)
                ? &quot;.css&quot;
                : &quot;.vue&quot;;
            const getContentData = (asBinary) =&gt;
                fetch(url).then((res) =&gt;
                    !res.ok
                        ? Promise.reject(url)
                        : asBinary
                        ? res.arrayBuffer()
                        : res.text()
                );
            return { getContentData: getContentData, type: type };
        },
        addStyle(textContent) {
            let styleElement = document.createElement(&quot;style&quot;);
            document.head.insertBefore(
                Object.assign(styleElement, { textContent }),
                document.head.getElementsByTagName(&quot;style&quot;)[0] || null
            );
        },
        handleModule(type, getContentData, path, options) {
            switch (type) {
                case &quot;.css&quot;:
                    return options.addStyle(getContentData(false));
                case &quot;.less&quot;:
                    console.error(&quot;.......&quot;);
            }
        },
        log(type, ...args) {
            console.log(type, ...args);
        },
    };</code></pre></div>



<p>"vue3_sfc_loader_options"は、「vue3-sfc-loader」でSFCを読み込むときのオプションです。<br>読み込んだSFCファイルから外部のモジュールをimportできるオプションになっています。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-reference-link">

<a rel="noopener noreferrer" href="https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14#issuecomment-908849863" title="Is it possible to import from an ES6 module in a component (SFC) ? ?? Issue #14 ?? FranckFreiburger/vue3-sfc-loader" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/e8ba901917fc72ce3d25524e176ef712.jpg" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Is it possible to import from an ES6 module in a component (SFC) ? ?? Issue #14 ?? FranckFreiburger/vue3-sfc-loader</div><div class="blogcard-snippet external-blogcard-snippet">Hi, First I wan&#039;t to thank you for this librairy which is going to be very useful for me. I can&#039;t manage to import from ...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/FranckFreiburger/vue3-sfc-loader/issues/14" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>    ////////////////////////////////////////////////////////////////////////////////
    // Vue.js アプリケーションインスタンス
    ////////////////////////////////////////////////////////////////////////////////
    const app = Vue.createApp({
        components: {
            &quot;hello-world&quot;: Vue.defineAsyncComponent(() =&gt;
                loadModule(
                    &quot;../wp-content/themes/cocoon-child-master/vue-components/hello_world.vue&quot;,
                    vue3_sfc_loader_options
                )
            ),
        },
        template: `&lt;hello-world /&gt;`,
    });
    app.mount(&quot;#app&quot;);</code></pre></div>



<p>"Vue.createApp"で、Vueのアプリケーションインスタンスを作成した後、"app.mount("#app");"で、最初に作成した&lt;div&gt;タグに、作成したアプリケーションインスタンスをマウントしています。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>                loadModule(
                    &quot;../wp-content/themes/cocoon-child-master/vue-components/hello_world.vue&quot;,
                    vue3_sfc_loader_options
                )
</code></pre></div>



<p>「vue3-sfc-loader」の"loadModule"関数で、SFCファイルを読み込みます。<br>今回は、"hello_world.vue"という名前のSFCファイルを"../wp-content/themes/cocoon-child-master/vue-components/"フォルダの下に置いています。</p>



<p>「ちょいプラ素材」のブログは、WordPressのテーマに「<a rel="noopener noreferrer" href="https://wp-cocoon.com/" target="_blank">Cocoon<span class="fa fa-external-link external-icon anchor-icon"></span></a>」を使っています。<br>なので、「<a rel="noopener noreferrer" href="https://wp-cocoon.com/" target="_blank">Cocoon<span class="fa fa-external-link external-icon anchor-icon"></span></a>」の子テーマ「<a rel="noopener noreferrer" href="https://wp-cocoon.com/downloads/#toc3" target="_blank">cocoon-child-master<span class="fa fa-external-link external-icon anchor-icon"></span></a>」の下に"vue-components"というフォルダを作りました。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>        components: {
            &quot;hello-world&quot;: Vue.defineAsyncComponent(() =&gt;</code></pre></div>



<p>読み込んだSFCは、"hello-world"という名前のコンポーネントになります。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>        template: `&lt;hello-world /&gt;`,</code></pre></div>



<p>"hello-world"コンポーネントを&lt;hello-world&gt;タグでHTML要素として配置します。</p>



<h3 class="wp-block-heading"><span id="toc7">"hello_world.vue"の中身</span></h3>



<p>"hello_world.vue"の中身は、Vueの公式ガイド「<a rel="noopener noreferrer" href="https://v3.ja.vuejs.org/guide/single-file-component.html" target="_blank">単一ファイルコンポーネント<span class="fa fa-external-link external-icon anchor-icon"></span></a>」で紹介されている単純なテンプレート構文の例のSFCです。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;script&gt;
export default {
  data() {
    return {
      greeting: &#39;Hello World!&#39;
    }
  }
}
&lt;/script&gt;

&lt;template&gt;
  &lt;p class=&quot;greeting&quot;&gt;{{ greeting }}&lt;/p&gt;
&lt;/template&gt;

&lt;style&gt;
.greeting {
  color: red;
  font-weight: bold;
}
&lt;/style&gt;</code></pre></div>



<p>"greeting"というテンプレートを"color: red;"と"font-weight: bold;"のスタイルで表示するというものです。<br>"greeting"というテンプレートの文字列は、"Hello World!"です。</p>



<h2 class="wp-block-heading"><span id="toc8">まとめ</span></h2>



<p>「vue3-sfc-loader」ライブラリを使えば、WordPressの「カスタム HTML」ブロックから、VueのSFCを読み込むことができます。<br>「カスタム HTML」ブロックには、SFCのロード処理だけを書いて、実際にやりたい表示や処理は、SFC（1つの「*.vue」ファイル）にまとめることができます。<br>さらに凝った表示や処理をさせたい場合は、適宜、いくつかのSFCに分割すれば良いでしょう。</p>



<p>この方法で、WordPressサイトに簡単にVueを導入し、WordPressサイトのページ中に、複雑な表示や処理を実装することができます。</p>



<p>次は、もう少し面白いSFCの例として、WordPressの投稿に「<a rel="noopener noreferrer" href="https://www.chartjs.org/" target="_blank">Chart.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>」のチャート（グラフ）を表示してみましょう。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%abvue3%e3%81%aesfc%e3%82%92%e8%aa%ad%e3%81%bf%e8%be%bc%e3%82%93%e3%81%a7chart-js%e3%81%ae%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e8%a1%a8%e7%a4%ba/" title="WordPressの投稿にVue3のSFCを読み込んでChart.jsのチャートを表示する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">WordPressの投稿にVue3のSFCを読み込んでChart.jsのチャートを表示する</div><div class="blogcard-snippet internal-blogcard-snippet">WordPressの投稿に「Chart.js」をラップしたVueのSFCを読み込み、チャート（グラフ）を表示します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.05.26</div></div></div></div></a>
</div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>


]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88%e3%82%92/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>そろそろVue3を使ってみるか</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/%e3%81%9d%e3%82%8d%e3%81%9d%e3%82%8dvue3%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b%e3%81%8b/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/%e3%81%9d%e3%82%8d%e3%81%9d%e3%82%8dvue3%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b%e3%81%8b/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sat, 02 Apr 2022 14:25:57 +0000</pubDate>
				<category><![CDATA[Vue3]]></category>
		<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=10511</guid>

					<description><![CDATA[目次 Vue.jsは、とっても楽しいVue3へ移行使いたいのはローカルのブラウザ環境WordPressで作成されたWebサイトが表示されるまでの流れサーバー側にインストールしたNode.jsでJavaScriptを使う場 [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-16" checked><label class="toc-title" for="toc-checkbox-16">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">Vue.jsは、とっても楽しい</a></li><li><a href="#toc2" tabindex="0">Vue3へ移行</a></li><li><a href="#toc3" tabindex="0">使いたいのはローカルのブラウザ環境</a><ol><li><a href="#toc4" tabindex="0">WordPressで作成されたWebサイトが表示されるまでの流れ</a></li><li><a href="#toc5" tabindex="0">サーバー側にインストールしたNode.jsでJavaScriptを使う場合</a></li><li><a href="#toc6" tabindex="0">クライアント側のブラウザで動作するVueとは？</a></li><li><a href="#toc7" tabindex="0">CDNからVueを読み込む</a></li></ol></li><li><a href="#toc8" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">Vue.jsは、とっても楽しい</span></h2>



<p>2017年頃、ネットでReactとかVueといったJavaScriptのフレームワークの話題を頻繁に目にするようになって、自分のWordPressサイトのフロントエンドでも、ReactかVueを使ってみたいと思い始めました。</p>



<p>ReactにするかVueにするか、いろいろ調べた結果、</p>



<ul class="wp-block-list"><li>既存のJavaScriptのプログラムに少しずつ導入できそうなこと</li><li><a rel="noopener noreferrer" href="https://jp.vuejs.org/v2/guide/" target="_blank">Vue2の日本語サイト<span class="fa fa-external-link external-icon anchor-icon"></span></a>のイントロダクションの説明がとてもわかりやすかったこと</li></ul>



<p>から、Vue.js（当時のバージョンは、2.xだったので、Vue2と呼ぶ）を使い始めました。</p>



<p>Vue2を使うまでは、JQueryを使ってHTMLの要素を動的に操作したりしていましたが、いざ、Vue2を使い始めると、</p>



<p>「なんて便利なの！」<br>「もっと早く使えば良かった。」</p>



<p>という感じで、ドハマりしてしまいました。</p>



<p>何より、JavaScriptの変数やプロパティーが変わると、更新が必要なDOMが自動で置き換わるリアクティブな動作が心地いいんです。</p>



<p>状態の変化に応じて、自分でHTML要素をJQueryで変更する面倒な作業には、もう戻れません。</p>



<p>「<a href="https://www.kabanoki.net/category/vue-js/">カバの樹<span class="fa fa-external-link external-icon anchor-icon"></span></a>」さんのサイトなどで紹介されているVueのライブラリも便利そうなものが多く、気に入ったVueライブラリを自分のサイトに組み込むのが楽しい作業になりました。</p>



<h2 class="wp-block-heading"><span id="toc2">Vue3へ移行</span></h2>



<p>Vue.jsは、2020年の9月にメジャーバージョンが2.xから3.0にアップし、さまざまな改良が加えられました。</p>



<p>いろいろネットの情報を調べてみると、Vue.js本体を2.xから3.0に単純に差し替えるだけではダメで、自分の書いたJavaScriptのプログラムを変更しないといけないことがわかりました。</p>



<p>以下のように、Vueアプリケーションを組み込む、最初のコードから違います。</p>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>// Vue2の場合
var app = new Vue({
  el: &#39;#app&#39;,
    …
})</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>// Vue3の場合
Vue.createApp(Counter).mount(&#39;#app&#39;)</code></pre></div>



<p>ということで、ちょっと面倒臭くなり、しばらく放っておきました。</p>



<p>ただ、HTMLのテーブルにいろいろな機能を追加するために、ずっと利用させてもらってきたJQueryの「<a href="https://mottie.github.io/tablesorter/docs/">teblesorter<span class="fa fa-external-link external-icon anchor-icon"></span></a>」というライブラリを、テーブル用Vueライブラリ「<a rel="noopener noreferrer" href="https://borisflesch.github.io/vue-good-table-next/" target="_blank">vue-good-table-next<span class="fa fa-external-link external-icon anchor-icon"></span></a>」へ置き換えるのを機に、Vue3に移行することにしました。</p>



<h2 class="wp-block-heading"><span id="toc3">使いたいのはローカルのブラウザ環境</span></h2>



<p>ここで一つ注意があります。</p>



<p>ネットでVueの情報を閲覧すると、そのほとんどが、サーバー側に<a rel="noopener noreferrer" href="https://nodejs.org/ja/" target="_blank">Node.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>をインストールして、その<a rel="noopener noreferrer" href="https://nodejs.org/ja/" target="_blank">Node.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>の環境でVueを実行させる話です。</p>



<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box information-box">
<p>Node.jsは、WindowsやMACなど、手元（ローカル）のPCにインストールすることもできます。<br>ただし、ローカルのPCにインストールしたNode.jsの環境は、あくまでサーバーとしての位置づけです。<br>ローカルPCの中に、仮想のサーバーを作るイメージです。</p>
</div>



<p>この「ちょいプラ素材」のブログで取り上げるのは、サーバー側にインストールした<a rel="noopener noreferrer" href="https://nodejs.org/ja/" target="_blank">Node.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>環境の話ではなく、手元（ローカル）のブラウザ環境でVue3を利用する方法です。</p>



<h3 class="wp-block-heading"><span id="toc4">WordPressで作成されたWebサイトが表示されるまでの流れ</span></h3>



<ul class="wp-block-list"><li><strong>クライアント側</strong>：手元（ローカル）のブラウザ環境</li><li><strong>サーバー側</strong>：サーバー環境</li></ul>



<p>の区別を理解するために、WordPressで作成されたWebサイトの情報やコンテンツが、ローカルPCのブラウザに表示されるまでの流れを説明します。</p>



<p>この「ちょいプラ素材」のブログも、WordPressを利用したWebサイトです。<br>皆さんの使っているブラウザから、「ちょいプラ素材」にアクセスしたとき、「ちょいプラ素材」のコンテンツがブラウザに表示されるまでの流れを下図で説明します。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1131" height="784" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/9f66f4eeb893681239eb177b24b14459.png" alt="" class="wp-image-10534" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/9f66f4eeb893681239eb177b24b14459.png 1131w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/9f66f4eeb893681239eb177b24b14459-500x347.png 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/9f66f4eeb893681239eb177b24b14459-800x555.png 800w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/9f66f4eeb893681239eb177b24b14459-300x208.png 300w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/9f66f4eeb893681239eb177b24b14459-768x532.png 768w" sizes="(max-width: 1131px) 100vw, 1131px" /></figure>



<ol class="marusuuji wp-block-list"><li>ブラウザから「ちょいプラ素材」のURLを指定してWebサーバーにアクセスします。<br>　</li><li>Webサーバーは、URLを解釈して、URLに応じたPHPプログラムを実行します。<br><span class="fz-14px">Webサーバーには、Linuxサーバーで利用されるAPACHE、NGINX、OpenLiteSpeed</span><span class="fz-14px">や</span><span class="fz-14px">、Windowsサーバーで利用されるIISなどがあります。</span><br>　</li><li>PHPプログラムは、MySQLを経由して、データベースに保存されているコンテンツ（文章やデータ）を読み出します。<br><span class="fz-14px">MariaDBなどMySQL互換のデータベースサーバーが使われることもあります。</span><br>　</li><li>データベースから読み出されたコンテンツは、PHPプログラムによって処理され、Webサーバーを通して、HTML / CSS / JavaScript の形式でクライアント側に送られます。<br>　</li><li>ブラウザは、クライアント側に送られたHTML / CSS を解釈し、画面に表示します。<br>JavaScriptが含まれるWebページでは、JavaScriptのプログラムを実行します。<span class="fz-16px"><span class="fz-14px"><br>JavaScript（場合によっては、JavaScriptのjQueryライブラリ、JavaScriptのフレームワークのVue.jsなど）を利用するとHTMLの要素を動的に変更することができます。<br>「ちょいプラ素材」では、JavaScriptライブラリやVueライブラリを使って、表やグラフを表示したり、ユーザーインターフェースを構成したりしています。</span></span><br>　</li><li>ブラウザはクライアント側にあるので、ブラウザからサーバー側のデータベースに直接アクセスできません。<br>ユーザーがインターフェースを操作して入力したパラメーターをサーバーに送ったり、表やグラフの元になるデータをサーバーに要求したりする場合は、Ajax通信を使います。<br><span class="fz-16px"><span class="fz-14px">URLを指定したアクセスでは、Webページ全体の表示が更新（リセット）されてしまいますが、Ajax通信を使うと、Webページの表示をリセットしないで、クライアントとサーバーの間でデータのやりとりができます。<br>Ajax通信は、jQueryライブラリやフレームワークのVue.jsにaxiosを組み合わせて利用した方が楽に処理できます。</span></span></li></ol>



<div class="wp-block-group is-layout-flow wp-block-group-is-layout-flow">
<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>
</div>



<p>余談になりますが、2022年4月現在、「<a rel="noopener noreferrer" href="https://w3techs.com/technologies/details/cm-wordpress" target="_blank">W<sup>3</sup>Techs<span class="fa fa-external-link external-icon anchor-icon"></span></a>」の調査データによると、全世界のWebサイトの43%がWordPressを利用しています。<br>コンテンツ管理システムでのシェアは、64.5%です。</p>



<p>これだけ広くWordPressが使われるようになった理由は、WordPressがリリースされた当時、一番メジャーだった以下のサーバーシステムを組み合わせて構成したので、ITエンジニアに抵抗感なく受け入れられたからだと思います。</p>



<ul class="wp-block-list"><li><strong>Webサーバー：</strong>APACHE</li><li><strong>アプリケーションサーバー：</strong>PHP</li><li><strong>データベースサーバー：</strong>MySQL</li></ul>



<h3 class="wp-block-heading"><span id="toc5">サーバー側にインストールしたNode.jsでJavaScriptを使う場合</span></h3>



<p>先ほど、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>ネットでVueの情報を閲覧すると、そのほとんどが、サーバー側にNode.jsをインストールして、そのNode.jsの環境でVueを実行させる話です。</p></blockquote>



<p>と説明しました。</p>



<p>上図で示したように、WordPressのアプリケーションサーバーは、PHPを使っています。</p>



<p>WordPress以外の一部のWebサイトでは、サーバーにNode.jsをインストールし、サーバー側でもJavaScriptが動作する環境を用意して、この環境で動作するJavaScriptをアプリケーションサーバーとして使うことがあります。</p>



<p>Vueは、JavaScriptのフレームワークですから、当然、サーバー側のNode.js環境でも動作します。<br>ネットに溢れているVueの情報は、サーバー側のNode.js環境の話がほとんどです。</p>



<h3 class="wp-block-heading"><span id="toc6">クライアント側のブラウザで動作するVueとは？</span></h3>



<p>では、「クライアント側のブラウザで動作するVue」とは、どういう話でしょうか？</p>



<p>上図で、</p>



<ol start="4" class="marusuuji-4 wp-block-list"><li>データベースから読み出されたコンテンツは、PHPプログラムによって処理され、Webサーバーを通して、HTML / CSS / JavaScript の形式でクライアント側に送られます。<br>　</li><li>ブラウザは、クライアント側に送られたHTML / CSS を解釈し、画面に表示します。<br>JavaScriptがが含まれるWebページでは、JavaScriptのプログラムを実行します。</li></ol>



<p>と説明しました。</p>



<p>クライアント側に送られたJavaScript（④）は、ブラウザで実行（⑤）されますが、このブラウザで実行されるJavaScriptでも、Vueを動作させることができます。</p>



<p>「クライアント側のブラウザで動作するVue」とは、ブラウザで実行（⑤）されるJavaScriptで、Vueを利用するという意味です。</p>



<h3 class="wp-block-heading"><span id="toc7">CDNからVueを読み込む</span></h3>



<p>ブラウザで動作するJavaScriptでVueを利用するためには、Vue本体（Vue.js）を読み込む必要があります。</p>



<p>上図の④で、Webサーバーから送られるJavaScriptに、Vue本体を含めても良いのですが、</p>



<ul class="wp-block-list"><li>サーバー側の処理や通信トラフィックに負荷がかかる</li><li>個々のサーバーで、Vue本体のバージョン管理をするのは大変</li></ul>



<p>という理由で、実際には行われていません。</p>



<p>では、どうするか？</p>



<p>④で送られるHTMLやJavaScriptの中に、Vue本体を読み込む処理（コード）を埋め込みます。<br>Vue本体を読み込むコードは、1行で書けるほどの小さいサイズなので、④で送られるHTMLやJavaScriptのデータ量はほとんど増えません。</p>



<p>以下に、実際のコードの例を示します。</p>



<div class="hcb_wrap html"><pre class="prism line-numbers lang-html" data-lang="HTML"><code>&lt;!-- HTMLから読み込む場合 --&gt;
&lt;script src=&quot;https://unpkg.com/vue@next&quot;&gt;&lt;/script&gt;</code></pre></div>



<div class="hcb_wrap javascript"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>// JavaScriptから読み込む場合
import Vue from &quot;https://cdn.jsdelivr.net/npm/vue@3.2.31/dist/vue.esm-browser.js&quot;;</code></pre></div>



<p>上記のコードで、「3.2.31」は、Vueのバージョンです。<br>メジャーバージョンが「3」なので、Vue3を読み込んでいます。</p>



<p>また、Vue本体を「<a href="https://unpkg.com/browse/vue@3.2.31/dist/">https://unpkg.com<span class="fa fa-external-link external-icon anchor-icon"></span></a>」や「<a href="https://cdn.jsdelivr.net/npm/vue@next/dist/">https://cdn.jsdelivr.net<span class="fa fa-external-link external-icon anchor-icon"></span></a>」といった、CDNサイトから読み込んでいます。</p>



<p>CDNは、「Content Delivery Network：コンテンツデリバリーネットワーク」の略で、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>ウェブサーバーの負荷を軽減する目的で、ウェブコンテンツを効率的かつスピーディーに配信できるように工夫されたネットワーク</p></blockquote>



<p>の仕組みです。</p>



<h2 class="wp-block-heading"><span id="toc8">まとめ</span></h2>



<p>今後、「ちょいプラ素材」では、ローカルのブラウザ環境でVue3を使う方法を説明します。</p>



<p>具体的には、</p>



<ul class="wp-block-list"><li>ブラウザ環境で、SFC（Single-File Component：単一ファイルコンポーネント、別名 *.vueファイル）を使う方法</li><li>美しいグラフを作成できる有名なJavaScriptライブラリ「<a rel="noopener noreferrer" href="https://www.chartjs.org/" target="_blank">Chart.js<span class="fa fa-external-link external-icon anchor-icon"></span></a>」をVue3で使う方法</li><li>テーブル用の高機能なVueライブラリ「<a rel="noopener noreferrer" href="https://borisflesch.github.io/vue-good-table-next/" target="_blank">vue-good-table-next<span class="fa fa-external-link external-icon anchor-icon"></span></a>」をVue3で使う方法</li></ul>



<p>などを紹介しようと思います。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e3%82%b5%e3%82%a4%e3%83%88%e3%81%a7vue3%e3%81%ae%e5%8d%98%e4%b8%80%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%b3%e3%83%b3%e3%83%9d%e3%83%bc%e3%83%8d%e3%83%b3%e3%83%88%e3%82%92/" title="WordPressのサイトでVue3の単一ファイルコンポーネントを使う" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/SFC-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">WordPressのサイトでVue3の単一ファイルコンポーネントを使う</div><div class="blogcard-snippet internal-blogcard-snippet">「vue3-sfc-loader」を使うと、「Node.js」が無いブラウザ環境でもVue3の単一ファイルコンポーネントを使うことができます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2025.10.18</div></div></div></div></a>
</div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%abvue3%e3%81%aesfc%e3%82%92%e8%aa%ad%e3%81%bf%e8%be%bc%e3%82%93%e3%81%a7chart-js%e3%81%ae%e3%83%81%e3%83%a3%e3%83%bc%e3%83%88%e3%82%92%e8%a1%a8%e7%a4%ba/" title="WordPressの投稿にVue3のSFCを読み込んでChart.jsのチャートを表示する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/Chartjs-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">WordPressの投稿にVue3のSFCを読み込んでChart.jsのチャートを表示する</div><div class="blogcard-snippet internal-blogcard-snippet">WordPressの投稿に「Chart.js」をラップしたVueのSFCを読み込み、チャート（グラフ）を表示します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.05.26</div></div></div></div></a>
</div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-related">

<a href="https://vitorec.co.jp/choi-plus-sozai/wordpress%e3%81%ae%e6%8a%95%e7%a8%bf%e3%81%ab%e3%82%bd%e3%83%bc%e3%83%88%e3%82%84%e3%83%9a%e3%83%bc%e3%82%b8%e3%83%8d%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%81%ae%e6%a9%9f%e8%83%bd%e3%82%92%e6%8c%81/" title="WordPressの投稿にソートやページネーションの機能を持ったテーブルを実装する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-160x90.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-160x90.png 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-120x68.png 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2022/04/vue-good-table-next-320x180.png 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">WordPressの投稿にソートやページネーションの機能を持ったテーブルを実装する</div><div class="blogcard-snippet internal-blogcard-snippet">VueのSFCを介して「vue-good-table-next」を使うと、WordPressの投稿に多機能なテーブルを手軽に実装できます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.07.25</div></div></div></div></a>
</div>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>


]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/%e3%81%9d%e3%82%8d%e3%81%9d%e3%82%8dvue3%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b%e3%81%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>「ちょいプラ素材」　StarServerのハイスピードプランに乗り換えました</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/%e3%80%8c%e3%81%a1%e3%82%87%e3%81%84%e3%83%97%e3%83%a9%e7%b4%a0%e6%9d%90%e3%80%8d%e3%80%80starserver%e3%81%ae%e3%83%8f%e3%82%a4%e3%82%b9%e3%83%94%e3%83%bc%e3%83%89%e3%83%97%e3%83%a9%e3%83%b3%e3%81%ab/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/%e3%80%8c%e3%81%a1%e3%82%87%e3%81%84%e3%83%97%e3%83%a9%e7%b4%a0%e6%9d%90%e3%80%8d%e3%80%80starserver%e3%81%ae%e3%83%8f%e3%82%a4%e3%82%b9%e3%83%94%e3%83%bc%e3%83%89%e3%83%97%e3%83%a9%e3%83%b3%e3%81%ab/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sat, 11 Sep 2021 03:22:24 +0000</pubDate>
				<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=10381</guid>

					<description><![CDATA[目次 ずっとminibirdサーバーを使っていたハイスピードプランが永久半額？サポートに確認ハイスピードプランの申し込み「ちょいプラ素材」のサーバー移動StarServerの評価まとめ ずっとminibirdサーバーを使 [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-18" checked><label class="toc-title" for="toc-checkbox-18">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">ずっとminibirdサーバーを使っていた</a></li><li><a href="#toc2" tabindex="0">ハイスピードプランが永久半額？</a></li><li><a href="#toc3" tabindex="0">サポートに確認</a></li><li><a href="#toc4" tabindex="0">ハイスピードプランの申し込み</a></li><li><a href="#toc5" tabindex="0">「ちょいプラ素材」のサーバー移動</a></li><li><a href="#toc6" tabindex="0">StarServerの評価</a></li><li><a href="#toc7" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">ずっとminibirdサーバーを使っていた</span></h2>



<p>このブログ「ちょいプラ素材」では、2014年10月から、自分の体験をベースに、気になったコトやモノ、ヒトを少しづつ紹介してきました。</p>



<p>個人的な情報発信が目的なので、レンタルサーバーを選ぶにあたって、私が最も重視したのはコスパです！<br>以下の記事でも紹介していますが、最初に選んだレンタルサーバーは、WordPressも使えて、月275円（税込み）で自分のブログが簡単に開設できる<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">ネットオウル<span class="fa fa-external-link external-icon anchor-icon"></span></a>さんのminibirdサーバーでした。</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-reference">

<a href="https://vitorec.co.jp/choi-plus-sozai/%e3%83%ac%e3%83%b3%e3%82%bf%e3%83%ab%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e3%82%92%e9%81%b8%e3%81%b6%e3%80%80wordpress%e3%82%82%e4%bd%bf%e3%81%88%e3%82%8b%e6%9c%88250%e5%86%86%e3%81%ae%e6%a0%bc/" title="レンタルサーバーを選ぶ　WordPressも使える月250円の格安サーバーが意外とすごい" class="blogcard-wrap internal-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2014/11/elections-450166_1280-160x90.jpg" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2014/11/elections-450166_1280-160x90.jpg 160w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2014/11/elections-450166_1280-120x67.jpg 120w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2014/11/elections-450166_1280-320x180.jpg 320w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2014/11/elections-450166_1280-250x141.jpg 250w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">レンタルサーバーを選ぶ　WordPressも使える月250円の格安サーバーが意外とすごい</div><div class="blogcard-snippet internal-blogcard-snippet">WordPressにも対応した格安レンタルサーバーを選択するときに考慮したポイントをまとめます。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://vitorec.co.jp/choi-plus-sozai" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">vitorec.co.jp</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2018.07.15</div></div></div></div></a>
</div>



<p>その後、 minibirdサーバーは、StarServerに名称を変えましたが、以下のスペックと 月275円（税込み） の価格はそのまま継承されたので、私は、ずっと StarServer ライトプラン（旧ミニバード）というプランを使ってきました。</p>



<ul class="wp-block-list"><li>月 275円（税込み）のお手頃価格（12ヶ月契約）。</li><li>当然、WordPressに対応している。</li><li>ディスク容量 50GBなので、しばらくは容量不足になることはないだろう。<br>　→ SterServer移行時に、160GBに増量された。</li><li>50個までのマルチドメインに対応している。</li><li>1,000個までのサブドメインに対応している。</li><li>MySQLデータベースが5つまで持てる。</li><li>メールアドレス 500個。</li></ul>



<h2 class="wp-block-heading"><span id="toc2">ハイスピードプランが永久半額？</span></h2>



<p>久しぶりにネットオウルさんのサイトに行ったところ、何やら見過ごせない<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">キャンペーン<span class="fa fa-external-link external-icon anchor-icon"></span></a>が目に留まりました。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-official">

<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" title="低価格×高性能でコスパ最強！ブログ・ホームページなら【スターレンタルサーバー】" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/737b2424d3b9a595e7f40c1b42523ece.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">低価格×高性能でコスパ最強！ブログ・ホームページなら【スターレンタルサーバー】</div><div class="blogcard-snippet external-blogcard-snippet">レンタルサーバーの【スターレンタルサーバー】は、手頃な価格で使える高性能レンタルサーバーです。オールNVMe・無料独自SSL・WordPressが使える高速サーバー環境が利用可能で、高速・サポート充実のプランを253円から提供。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://www.star.ne.jp/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">www.star.ne.jp</div></div></div></div></a>
</div>



<ul class="wp-block-list"><li>3年契約であれば、値段変わらずの 月 275円（税込み）でハイスピードプランに乗り換えられる。</li><li>ディスク容量 320GBに倍増。</li><li>無制限のマルチドメイン。</li><li>無制限のサブドメイン。</li><li>無制限のMySQLデータベース。</li><li>無制限のメールアドレス。</li></ul>



<p class="has-black-color has-text-color has-large-font-size">「<span class="bold-red">無制限</span>のオンパレードや！」</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="400" height="266" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/14bb524d2f1459838c9a400252c0d694.jpg" alt="" class="wp-image-10383" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/14bb524d2f1459838c9a400252c0d694.jpg 400w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/14bb524d2f1459838c9a400252c0d694-300x200.jpg 300w" sizes="(max-width: 400px) 100vw, 400px" /></figure>



<p>私が重要視したのは、MySQLデータベースが無制限に設定できるという点です。</p>



<p>せっかくマルチドメイン対応で、複数のWordPressサイトが運用できるので、それぞれのサイトごとにMySQLデータベースは使い分けたい。<br>マルチドメインも MySQLデータベースも無制限は、とっても魅力的なんです！</p>



<p>キャンペーン期間が2021年10月7日までだったので、さっそく、ハイスピードプランへの乗り換え検討を始めました。</p>



<h2 class="wp-block-heading"><span id="toc3">サポートに確認</span></h2>



<p>まず、サポートに問い合わせしたのは、</p>



<p>「 この<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">キャンペーン半額キャンペーン<span class="fa fa-external-link external-icon anchor-icon"></span></a>は、継続利用の私にも適用されるのか？ 」</p>



<p>です。<br>回答は、</p>



<p>「適用されます。」<br>「ただし、ハイスピードプランのサーバーを新たに新規申し込みしてください。」</p>



<p>とのことでした。<br>ネットオウルさんの<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">SterServer<span class="fa fa-external-link external-icon anchor-icon"></span></a>は、 どのプランも「2週間の無料お試し期間」があるので、躊躇なく申込できます。<br> 「2週間の無料お試し期間」の申し込みにあたっては、支払方法を選んだり、クレジットカード番号などの入力も必要ないので、文字どおり「まずは、お試し」感覚です。</p>



<p>解約手続きを忘れても、費用が発生することもありません。</p>



<h2 class="wp-block-heading"><span id="toc4">ハイスピードプランの申し込み</span></h2>



<p>申し込みはいたって簡単。</p>



<p> <a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">SterServer<span class="fa fa-external-link external-icon anchor-icon"></span></a>のサイトにアクセスして、ページの上の方にある、</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="540" height="60" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/0c2cab54b851b60f795f5a5eeb06d75f.png" alt="" class="wp-image-10385" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/0c2cab54b851b60f795f5a5eeb06d75f.png 540w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/0c2cab54b851b60f795f5a5eeb06d75f-500x56.png 500w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/0c2cab54b851b60f795f5a5eeb06d75f-300x33.png 300w" sizes="(max-width: 540px) 100vw, 540px" /></figure>



<p>ボタンを押した後、プラン一覧表で希望のプランを選び、表の下にある「申し込む」ボタンを押します。</p>



<p>「Netowl スターサーバー申込フォーム」のページ移動するので、このページの「新規会員登録の流れ」の手順に沿って申し込むだけです。</p>



<p>申し込みが完了したら、<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">SterServer<span class="fa fa-external-link external-icon anchor-icon"></span></a>のサーバーIDが取得できます。</p>



<h2 class="wp-block-heading"><span id="toc5">「ちょいプラ素材」のサーバー移動</span></h2>



<p>新しくWordPressを始められる方は、この移動の手順は不要です。</p>



<p>私は、「ちょいプラ素材」のサーバー移動が目的なので、まず、「ちょいプラ素材」で使っているドメインのデータをバックアップします。</p>



<p>私は、WordPressの「<a rel="noopener noreferrer" href="https://ja.wordpress.org/plugins/all-in-one-wp-migration/" target="_blank">All-in-One WP Migration<span class="fa fa-external-link external-icon anchor-icon"></span></a>」を使ってブログデータのバックアップをしています。</p>



<p>バックアップが完了したら、旧サーバーIDから移動したいドメインを削除します。<br>ドメインを削除すると、このドメインに紐づいているデータも完全に削除されてしまうので、データのバックアップは確実に実行してください。</p>



<p>次に、新しいサーバIDに、旧サーバーIDから削除したドメインを追加します。</p>



<p class="has-medium-font-size">「旧サーバーIDからドメインを削除」&#x27a1;「新しいサーバーIDに削除したドメインを追加」</p>



<p>という手順は、ドメインのネームサーバーの変更が発生します。<br>なので、最大24時間ほど、元のドメインのサイトにアクセスできなくなります。</p>



<p>私は、サイトにしばらくアクセスできなくなることを許容し、手順が簡単なこの方法を選びました。</p>



<h2 class="wp-block-heading"><span id="toc6">StarServerの評価</span></h2>



<p>ちなみに、今回、<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">SterServer<span class="fa fa-external-link external-icon anchor-icon"></span></a>のハイスピードプランに乗り換えるに当たって、他社のレンタルサーバーとの比較も行いました。</p>



<p>以下、レンタルサーバーの比較サイトを見ると、<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">SterServer<span class="fa fa-external-link external-icon anchor-icon"></span></a>の評価は、10位 / 10位中でした。</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-reference">

<a rel="noopener noreferrer" href="https://yokaport.com/server-ranking/?gclid=CjwKCAjwhOyJBhA4EiwAEcJdcV29dRcElursg7cDDGE2nvxy3feHKLTH8DorB3kyORcsfWIjmz7WKBoCBzoQAvD_BwE" title="【徹底比較】レンタルサーバーおすすめランキング【速度・料金・安定性】" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/5a2f1eb995b863392bda3334ba18ff1a.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">【徹底比較】レンタルサーバーおすすめランキング【速度・料金・安定性】</div><div class="blogcard-snippet external-blogcard-snippet">本記事では、日本国内で提供されているレンタルサーバーのうち、初心者にもおすすめのレンタルサーバーを人気、速度、料金、安定度、レビュー、評価点などで独自に比較集計し、おすすめレンタルサーバーランキングとしてランキング形式でまとめています。これ...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://yokaport.com/server-ranking/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">yokaport.com</div></div></div></div></a>
</div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>月額138円～利用できる格安レンタルサーバーです。格安なので機能・性能は良くありませんが、他の格安サーバーと比べ過去に目立った事故等起こしておらず、安定した運用を行えます。ただし、性能は良くありません。長所は「安い」それだけです。</p></blockquote>



<p class="has-large-font-size">長所は<span class="bold-red">「安い」</span>それだけです。</p>



<p class="has-large-font-size">いいんです！</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="240" height="240" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/8f2502da9ad44f8bb7366dafa6a636a1.png" alt="" class="wp-image-10406" srcset="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/8f2502da9ad44f8bb7366dafa6a636a1.png 240w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/8f2502da9ad44f8bb7366dafa6a636a1-100x100.png 100w, https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/2021/09/8f2502da9ad44f8bb7366dafa6a636a1-150x150.png 150w" sizes="(max-width: 240px) 100vw, 240px" /></figure>



<p>改めて、他社のレンタルサーバーと比較してみましたが、「永久半額キャンペーン」を利用すれば、コスパは断トツです。<br>乗り換えする意味を改めて確信できました。</p>



<p>あと、速度が遅いとありますが、皆さんどうでしょうか？<br>「ちょいプラ素材」の表示、遅いですか？</p>



<p>私は、ほとんど気になりません。</p>



<p>あと、7年間、ネットオウルさんを利用していますが、ネット障害などの事故はありません。<br>とっても安定しています。</p>



<h2 class="wp-block-heading"><span id="toc7">まとめ</span></h2>



<p>今回、たまたま見かけた、<a rel="noopener noreferrer" href="https://www.star.ne.jp?ref=NAmn2ins" target="_blank">SterServer<span class="fa fa-external-link external-icon anchor-icon"></span></a>のハイスピードプラン「永久半額キャンペーン」を利用して、「ちょいプラ素材」のブログのサーバーを移行しました。</p>



<p>「ちょいプラ素材」にしばらくアクセスできなくなった方がいらっしゃると思いますが、無事、サーバーの移動も完了し、「ちょいプラ素材」も再開できました。</p>



<p>引き続き、「ちょいプラ素材」をよろしくお願いします。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/%e3%80%8c%e3%81%a1%e3%82%87%e3%81%84%e3%83%97%e3%83%a9%e7%b4%a0%e6%9d%90%e3%80%8d%e3%80%80starserver%e3%81%ae%e3%83%8f%e3%82%a4%e3%82%b9%e3%83%94%e3%83%bc%e3%83%89%e3%83%97%e3%83%a9%e3%83%b3%e3%81%ab/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cocoon　WordPressのテーマを換えました</title>
		<link>https://vitorec.co.jp/choi-plus-sozai/cocoon%e3%80%80wordpress%e3%81%ae%e3%83%86%e3%83%bc%e3%83%9e%e3%82%92%e6%8f%9b%e3%81%88%e3%81%be%e3%81%97%e3%81%9f/</link>
					<comments>https://vitorec.co.jp/choi-plus-sozai/cocoon%e3%80%80wordpress%e3%81%ae%e3%83%86%e3%83%bc%e3%83%9e%e3%82%92%e6%8f%9b%e3%81%88%e3%81%be%e3%81%97%e3%81%9f/#respond</comments>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sun, 01 Jul 2018 09:21:06 +0000</pubDate>
				<category><![CDATA[ブログサイトの立ち上げ方]]></category>
		<category><![CDATA[日々のコト]]></category>
		<guid isPermaLink="false">https://vitorec.co.jp/choi-plus-sozai/?p=8818</guid>

					<description><![CDATA[目次 WordPressのテーマを換えました「Cocoon」を使ってみた不具合や課題もちらほらよし、「Cocoon」に換えよう！インデックス画面のサムネイル画像が表示されないカード形式を選ぶカードのサムネイル画像の再生成 [&#8230;]]]></description>
										<content:encoded><![CDATA[
  <div id="toc" class="toc tnt-number-detail toc-center tnt-number_detail border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-20" checked><label class="toc-title" for="toc-checkbox-20">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">WordPressのテーマを換えました</a></li><li><a href="#toc2" tabindex="0">「Cocoon」を使ってみた</a><ol><li><a href="#toc3" tabindex="0">不具合や課題もちらほら</a></li></ol></li><li><a href="#toc4" tabindex="0">よし、「Cocoon」に換えよう！</a></li><li><a href="#toc5" tabindex="0">インデックス画面のサムネイル画像が表示されない</a><ol><li><a href="#toc6" tabindex="0">カード形式を選ぶ</a></li><li><a href="#toc7" tabindex="0">カードのサムネイル画像の再生成</a></li><li><a href="#toc8" tabindex="0">サムネイル画像がない</a></li><li><a href="#toc9" tabindex="0">暫定対策</a></li></ol></li><li><a href="#toc10" tabindex="0">まとめ</a></li><li><a href="#toc11" tabindex="0">その後</a><ol><li><a href="#toc12" tabindex="0">原因</a></li><li><a href="#toc13" tabindex="0">HTMLソース</a></li><li><a href="#toc14" tabindex="0">対策</a></li></ol></li></ol>
    </div>
  </div>

<h2><span id="toc1">WordPressのテーマを換えました</span></h2>
<p>この「ちょいプラ素材」のブログを立ち上げたときから使っているWordPressのテーマ「Simplicity」を後継の「Cocoon」に換えました。</p>
<p>&nbsp;</p>
<p>一昨日、「Simplicity」のホームページに行くと、</p>
<p><strong>Simplicity2.6.9公開。細かな修正のみ。</strong>と題して、新しいバージョンの「Simplicity」がアップされていました。</p>
<p>&nbsp;</p>
<p>気になったのは、作者のわいひらさんの以下のコメント。</p>
<blockquote>
<p>今は、Cocoonテーマの正式版に向けて開発中なので、ちょっとした不具合修正のみです。</p>
</blockquote>
<p>&nbsp;</p>
<p><strong>「Cocoon？」</strong><br />
<strong>「何それ？」</strong><br />
<strong>「なんか作ってんの？」</strong></p>
<p>&nbsp;</p>
<p>というわけで、「Cocoon」でGoogle検索すると、トップに</p>
<p class="r" style="padding-left: 30px;"><a href="https://nelog.jp/cocoon">無料WordPressテーマ「Cocoon（コクーン）」を公開しました - 寝ログ<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>
<p>と出てきました。</p>
<p><a rel="noopener noreferrer" href="https://nelog.jp/" target="_blank">寝ログ<span class="fa fa-external-link external-icon anchor-icon"></span></a>は、わいひらさんの個人サイトです。</p>
<p>&nbsp;</p>
<h2><span id="toc2">「Cocoon」を使ってみた</span></h2>
<p>「Cocoon」の正体が知りたい方は、以下オフィシャルサイトにアクセスしてください。</p>

<a rel="noopener noreferrer" href="https://wp-cocoon.com/" title="Cocoon" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/75b272d5c162b0e3d6c69c9d1f35cb0f.jpg" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Cocoon</div><div class="blogcard-snippet external-blogcard-snippet">SEO・高速化・モバイルファースト最適化済みのシンプルな無料Wordpressテーマ。100％GPLテーマです。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://wp-cocoon.com/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">wp-cocoon.com</div></div></div></div></a>
<p>&nbsp;</p>
<p>私もこのサイトで「Cocoon」の特徴を確認しました。</p>
<ul>
<li>コンテンツの幅がカスタマイズできる</li>
<li>ヘッダやアピールエリアにパララックス効果が設定できる</li>
<li>テーマ独自のカスタマイズ画面でカスタマイズができる</li>
<li>ビジュアルエディターで簡単に吹き出しを挿入できる</li>
</ul>
<p>などなど、一目で気に入ってしまいました。</p>
<p>何と言っても、作者がわいひらさんというのが安心できます。</p>
<p>&nbsp;</p>
<p>まだ、正式版ではないので、「ちょいプラ素材」のWordPressのテーマをいきなり「Cocoon」変えるわけにはいきませんが、なる早で使って見たくて、急ぎユーザー登録をし、最新版のVer.0.7.5をダウウンロード。</p>
<p>ローカルPCの環境にさっそく導入してみました。</p>
<p>&nbsp;</p>
<h3><span id="toc3">不具合や課題もちらほら</span></h3>
<p>使ってみて、一番困ったのが、</p>
<ul>
<li>画面上部のグローバルナビにカテゴリを設定すると、カテゴリの説明文が表示されてしまう</li>
</ul>
<p>といった小さな不具合です。</p>
<p>ただ、この件に関しては、半日ほど試行錯誤して解決策が見つかりました。</p>
<p>&nbsp;</p>
<p>さらに、新しく追加された便利機能ゆえの悩みも。</p>
<ul>
<li>「本文上にアイキャッチを表示する」という機能を使うと、もともと、記事ごとに自分で挿入していた画像とダブってしまう</li>
<li>新しく追加された「目次」機能を使うと、自分で追加していた目次とダブってしまう</li>
</ul>
<p>これは、一つずつ、記事のコンテンツを手直しして行けば済む話です。</p>
<p>&nbsp;</p>
<h2><span id="toc4">よし、「Cocoon」に換えよう！</span></h2>
<p>半日そこそこですが、ローカル環境で使ってみて大きな問題もなかったので、「ちょいプラ素材」のWordPressのテーマを換えることに決めました。</p>
<p>「Cocoon」のテーマをアップロードして、「Simplicity」から「Cocoon」にスイッチするのは、いとも簡単な作業です。</p>
<p>ところが、大きな問題が発生していまいました。</p>
<p>&nbsp;</p>
<h2><span id="toc5">インデックス画面のサムネイル画像が表示されない</span></h2>
<p>今回発生したトラブルは、インデックス画面で一覧表示されるカードのサムネイル画像に関する問題でした。</p>
<p>しかも、スマートフォンなど、画面サイズが小さいデバイスで閲覧したときだけ発生します。</p>
<p>このトラブルの原因究明と対策に、ほぼ1日かかっていまいました。</p>
<p>&nbsp;</p>
<h3><span id="toc6">カード形式を選ぶ</span></h3>
<p>「Cocoon」は、ホームページなどのインデックス画面で記事が一覧表示されるときに、次の7種類のカード形式を選ぶことができます。</p>
<ol>
<li>エントリーカード</li>
<li>大きなカード（先頭のみ）</li>
<li>大きなカード</li>
<li>縦型カード2列</li>
<li>縦型カード3列</li>
<li>タイルカード2列</li>
<li>タイルカード3列</li>
</ol>
<p>&nbsp;</p>
<p>詳しくは、以下のページを参照してください。</p>

<a rel="noopener noreferrer" href="https://wp-cocoon.com/index-entry-card-type/" title="エントリーカードの設定方法（一覧ページのカードの種類）" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/02a64bfcf2ab4ea3f60a9e113abd01d2.jpg" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">エントリーカードの設定方法（一覧ページのカードの種類）</div><div class="blogcard-snippet external-blogcard-snippet">インデックスページ（一覧ページ）のカードスタイルの見本です。スタイルの変更方法も。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://wp-cocoon.com/index-entry-card-type/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">wp-cocoon.com</div></div></div></div></a>
<p>&nbsp;</p>
<p>私は、「5．縦型カード3列」を選びました。</p>
<p>&nbsp;</p>
<h3><span id="toc7">カードのサムネイル画像の再生成</span></h3>
<p>一つ一つのカードの横幅は、ここで選んだ「カード形式」に加え、別途自分で設定した「コンテンツの幅」（表示画面の幅）で決まります。</p>
<p>なので、これらの設定を変更したときには、カードに表示するサムネイル画像の幅も変わってしまいます。</p>
<p>ということで、「Cocoon」では、以下のページでも、<a rel="noopener noreferrer" href="https://ja.wordpress.org/plugins/regenerate-thumbnails/" target="_blank">Regenerate Thumbnails<span class="fa fa-external-link external-icon anchor-icon"></span></a>プラグインを使って、サムネイル画像を再生成することを薦めています。</p>

<a rel="noopener noreferrer" href="https://wp-cocoon.com/regenerate-thumbnails/" title="テーマが利用しているサムネイルを再生成して最適化する方法（画像の大きさを揃える）" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/uploads/cocoon-resources/blog-card-cache/beb5d8acc8a570081055023953b0f3dc.jpg" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">テーマが利用しているサムネイルを再生成して最適化する方法（画像の大きさを揃える）</div><div class="blogcard-snippet external-blogcard-snippet">Force Regenerate Thumbnailsプラグインを用いて、テーマ上のサムネイルを再生成し、画像できるだけ綺麗に表示する方法の紹介です。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://wp-cocoon.com/regenerate-thumbnails/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">wp-cocoon.com</div></div></div></div></a>
<p>&nbsp;</p>
<p>私もローカル環境で、サムネイル画像を再生成し、インデックス画面のカードにサムネイル画像が正しく表示されることを確認していました。</p>
<p>&nbsp;</p>
<h3><span id="toc8">サムネイル画像がない</span></h3>
<p>WordPressのテーマを「Simplicity」から「Cocoon」に切り替えた後、念のため、スマフォでアクセスして確認すると、トップページの記事一覧にサムネイル画像が全くありません。</p>
<p>まずは、原因を探る必要があります。</p>
<p>この原因究明の流れを「Cocoon」の新機能の吹き出しを使って説明します。</p>
<p>&nbsp;</p>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>あれ？<br />
よく見ると、200ほどある記事のうち、4つほどの記事には、ちゃんとサムネイル画像がついているな。</p>
</div>
</div>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>サムネイル画像の再生成がうまくいってなかったのかな？<br />
もう一度、再生成してみるか？</p>
</div>
</div>
<p>ダメです。</p>
<p>&nbsp;</p>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>キャッシュの問題かな？</p>
<p>キャッシュをクリアしてみるか。</p>
</div>
</div>
<p>ダメです。</p>
<p>&nbsp;</p>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>プラグインが悪さをしているかもしれない。</p>
<p>全てのプラグインを無効にしてみよう。</p>
</div>
</div>
<p>ダメです。</p>
<p>&nbsp;</p>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>インデック画面のHTMLソースを確認してみよう。</p>
</div>
</div>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>あれ？</p>
<p>サムネイル画像が表示されない記事で求められている、<br />
　AAAA-342x192.jpg<br />
というサイズの画像が見つからないぞ！</p>
</div>
</div>
<div class="speech-wrap sb-id-5 sbs-flat sbp-l sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-child-master/images/author.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>逆に、サムネイル画像が表示される記事では、</p>
<p>　BBBB-320x180.jpg</p>
<p>というサイズの画像が求められていて、このサイズのサムネイル画像は、ちゃんと生成されているな。</p>
</div>
</div>
<p>ビンゴです！</p>
<p>&nbsp;</p>
<p>先に述べたように、自分で選んだ「カード形式」と「コンテンツの幅」によって、最適なサムネイル画像のサイズを計算しているようなのですが、何らかの要因で、最適なサイズのサムネイル画像が生成されていないようです。</p>
<p>&nbsp;</p>
<h3><span id="toc9">暫定対策</span></h3>
<p>暫定対策として、「Cocoon」の子テーマの<strong>functions.php</strong>に、</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-php" data-lang="PHP"><code>add_image_size('thumb342', 342, 192, true);</code></pre>
</div>
<p>と記入した後、再度、<a rel="noopener noreferrer" href="https://ja.wordpress.org/plugins/regenerate-thumbnails/" target="_blank">Regenerate Thumbnails<span class="fa fa-external-link external-icon anchor-icon"></span></a>プラグインを実行し、要求される 342 × 192 のサイズのサムネイル画像を生成します。</p>
<p>&nbsp;</p>
<p>これで、インデックス画面にスマフォでアクセスしたときでも、無事、記事の一覧にサムネイル画像が表示されるようになりました。</p>
<p>&nbsp;</p>
<p>「ちょいプラ素材」のホームページにスマフォでアクセスした方の中には、</p>
<div class="speech-wrap sb-id-2 sbs-stn sbp-r sbis-cb cf">
<div class="speech-person">
<figure class="speech-icon"><img decoding="async" class="speech-icon-image" src="https://vitorec.co.jp/choi-plus-sozai/wp-content/themes/cocoon-master/images/woman.png" alt="" /></figure>
</div>
<div class="speech-balloon">
<p>今日は、なんか表示がおかしいわね？</p>
</div>
</div>
<p>と思われた方もいらっしゃるかもしれません。</p>
<p>ご迷惑をおかけしました。</p>
<p>&nbsp;</p>
<h2><span id="toc10">まとめ</span></h2>
<p>サムネイル画像が表示されないというトラブルに見舞われましたが、なんとか、「ちょいプラ素材」のWordPressのテーマを「Simplicity」から「Cocoon」に切り替えることができました。</p>
<p>この不具合については、「Cocoon」の不具合報告フォーラムで、わいひらさんに報告しておきます。</p>
<p>&nbsp;</p>
<p>また、「Simplicity」には、4年近くお世話になりました。</p>
<p>このテーマの改良とともに、私自身もWordPressやPHP、JavaScriptなどの理解を深めることができました。</p>
<p>本当にありがとうございました。</p>
<p>&nbsp;</p>
<p>今後、「ちょいプラ素材」は、「Cocoon」を使って記事を書いていきます。</p>
<p>まだ、アイキャッチ画像がダブって表示されたり、一部、未対応のところも残っていますが、引き続き、よろしくお願いします。</p>
<p>&nbsp;</p>
<h2><span id="toc11">その後</span></h2>
<p>「Cocoon」の不具合報告フォーラムで報告したところ、わいひらさんが丁寧に対応いただき、無事に解決しました。</p>
<p>&nbsp;</p>
<h3><span id="toc12">原因</span></h3>
<p>当初、私は、「Cocoon」のカスタマイズ設定で、</p>
<ul>
<li>コンテンツ幅：1080px</li>
<li>カード形式：縦型カード3列</li>
</ul>
<p>を設定していました。</p>
<p>なので、カードの幅は、</p>
<p style="padding-left: 30px;">1080px / 3 ＝ 360px</p>
<p>になります。</p>
<p>ただし、カードは、左右それぞれ9pxのpaddingエリアを持っているので、</p>
<p style="padding-left: 30px;">360px - (9px × 2) = 342px</p>
<p>サムネイル画像の幅は、342pxになります。</p>
<p>&nbsp;</p>
<p>この後、私は、コンテンツ幅が少し広いことが気になり、</p>
<ul>
<li>コンテンツ幅：800px</li>
<li>カード形式：縦型カード3列（変更なし）</li>
</ul>
<p>の設定に変更しました。</p>
<p>すると、カードの幅は、</p>
<p style="padding-left: 30px;">800px / 3 ＝ 266.666px</p>
<p>になり、左右8pxのpaddingエリアを差し引いて、サムネイル画像の幅は、</p>
<p>266px - (8px × 2) = 250px</p>
<p>になります。<br />
なお、paddingエリアのサイズは、コンテンツ幅の大小に応じて、若干変更されるようです。</p>
<p>&nbsp;</p>
<p>コンテンツ幅が1080pxのときも800pxのときも、<a rel="noopener noreferrer" href="https://ja.wordpress.org/plugins/regenerate-thumbnails/" target="_blank">Regenerate Thumbnails<span class="fa fa-external-link external-icon anchor-icon"></span></a>プラグインを実行すると、それぞれに応じた342pxもしくは250pxの幅のサムネイルが再生成されます。</p>
<p>ところが、最初の設定の際、サムネイル画像の再生成処理を私が途中でキャンセルしたみたいで、投稿によって、342px幅のサムネイル画像があったり無かったりの状態になってしまったようです。</p>
<p>&nbsp;</p>
<h3><span id="toc13">HTMLソース</span></h3>
<p>さらにややこしいことに、コンテンツ幅を1080pxから800pxに変更した後も、HTMLソースには、サムネイル画像の&lt;img&gt;タグに</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-html" data-lang="HTML"><code>srcset="https://…/AAA-250x141.jpg 250w, https://…/AAA-342x192.jpg 342w"</code></pre>
</div>
<p>のように、不要になったコンテンツ幅1080pxのときの <strong>https://…/AAA-342x192.jpg 342w</strong> の記述が残ってしまいます。</p>
<p>342px幅のサムネイル画像が生成されてない状態で、HTMLにこの記述が残っていると、サムネイル画像が表示されない不具合が起こります（アクセスするデバイスの表示画面解像度によって、不具合が起こらないこともある）。</p>
<p>&nbsp;</p>
<h3><span id="toc14">対策</span></h3>
<p>サムネイル画像の再生成に<a rel="nofollow noopener noreferrer" href="https://ja.wordpress.org/plugins/force-regenerate-thumbnails/" target="_blank">Force Regenerate Thumbnails<span class="fa fa-external-link external-icon anchor-icon"></span></a>プラグインを使うことで解決しました。</p>
<p>このブラグインは、わいひらさんから紹介いただきました。</p>
<p>&nbsp;</p>
<p>このプラグインを使うと、古いサイズのサムネイル画像をすべて削除した後で、サムネイル画像を再生成するので、必要なサイズのサムネイル画像のみに整理できます。</p>
<p>同時に、HTMLソースの不要な <strong>https://…/AAA-342x192.jpg 342w</strong> の記述もなくなり、HTML記述とサムネイル画像のサイズの整合性が取れます。</p>
<p>&nbsp;</p>
<p>ということで、一件落着です。</p>
<p>わいひらさん、ありがとうございました。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vitorec.co.jp/choi-plus-sozai/cocoon%e3%80%80wordpress%e3%81%ae%e3%83%86%e3%83%bc%e3%83%9e%e3%82%92%e6%8f%9b%e3%81%88%e3%81%be%e3%81%97%e3%81%9f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
