Liquid Snippets by ALSEL
🔌 API連携/JSON出力/JS統合上級

Vue コンポーネントのデモ

Vue コンポーネント、スロット、プロップ、Vuex ストア、グローバルミックス、カスタムディレクティブを一堂に展示するセクション。Shopify Theme Lab フレームワークの主要機能をインタラクティブに試せる。

用途
Vue ベースの Shopify テーマ開発で、コンポーネント設計のパターン集やリファレンス画面として配置。開発チーム向けのデモページや、ドキュメントサイト、テーマビルダーのテンプレートとして活用する。
設置場所
shopify/sections/vue-examples.liquid に配置。テンプレートやカスタムセクション一覧から「Vue examples」をドラッグ&ドロップして任意のページに追加する。src/vue/components、mixins、directives、store フォルダの各サンプルファイルがあることが前提。
注意点
このセクションは Shopify Theme Lab フレームワーク(uicrooks 製)が導入済みのテーマ環境でのみ動作する。Vue コンポーネント(render-my-component、renderless-my-component)と Vuex ストア(my-module)がバンドルビルド時に正しく登録されていないと表示されない。セクション内のコンポーネント名はファイルパスルール(src/vue/components/render/my-component.vue → <render-my-component>)に従っており、カスタマイズ時にファイル名またはパスを変更するとコンポーネント参照が壊れるため注意が必要。
タグ:vuevuexcomponentslotpropdirectiveframework

コード

162 行 / liquid
<div class="container">
  <div class="shopify-theme-lab">
    <h1 class="shopify-theme-lab__headline">
      Shopify Theme Lab 🧪
    </h1>

    <p class="shopify-theme-lab__text">
      Customizable modular development environment for blazing-fast Shopify theme creation.
    </p>

    <div class="shopify-theme-lab__examples">
      <!--
        * if "name: 'MyComponent'" is defined inside a vue file, it can be referenced as <my-component></my-component>
        * otherwise the component will be named after the file path starting from the components/ directory
        * for src/vue/components/render/my-component.vue it's: <render-my-component></render-my-component>
      -->

      <div class="shopify-theme-lab__example">
        <!-- render component example: src/vue/components/render/my-component.vue -->
        <render-my-component
          :shopify-data="{
            shopName: '{{ shop.name }}',
            shopDomain: '{{ shop.domain }}',
            shopEmail: '{{ shop.email }}',
            shopCurrency: '{{ shop.currency }}'
          }"
        >
          <div class="shopify-theme-lab__subline">
            Vue component with slots and props
          </div>
        </render-my-component>

        <!-- global mixin: src/vue/mixins/global.mixin.js -->
        <div>
          <div class="shopify-theme-lab__subline">
            Global Vue mixin
          </div>

          <div>
            NODE_ENV: {% raw %}{{ env }}{% endraw %}
          </div>
        </div>

        <!-- global directive: src/vue/directives/global.directive.js -->
        <div>
          <div class="shopify-theme-lab__subline">
            Global Vue directive
          </div>

          <div v-my-directive>
            this text
          </div>
        </div>
      </div>

      <div class="shopify-theme-lab__example">
        <!-- renderless component example: src/vue/components/renderless/my-component.vue -->
        <renderless-my-component v-slot="{ visible, toggle }">
          <div>
            <div class="shopify-theme-lab__subline">
              Renderless Vue component + Vuex
            </div>

            <div>
              Vuex “my-module” state “visible” is set to <strong>{% raw %}{{ visible }}{% endraw %}</strong>
            </div>

            <button @click="toggle" class="shopify-theme-lab__button">
              Click me!
            </button>
          </div>
        </renderless-my-component>

        <!-- vuex module: src/vue/store/my-module.js -->
        <div>
          <div class="shopify-theme-lab__subline">
            Vuex anywhere!
          </div>

          <div>
            Vuex “my-module” state “visible” is set to <strong>{% raw %}{{ $store.state['my-module'].visible }}{% endraw %}</strong>
          </div>

          <button
            class="shopify-theme-lab__button"
            @click="$store.dispatch('my-module/toggle')"
          >
            Click me, too!
          </button>
        </div>
      </div>
    </div>
  </div>
</div>

<component is="style">
.shopify-theme-lab {
  background: rgb(240,240,240);
  border-radius: 10px;
  padding: 30px;
  margin: 20px 0;
}

.shopify-theme-lab__headline {
  font-size: 24px;
  font-weight: 700;
  text-align: center;
  margin-bottom: 10px;
}

.shopify-theme-lab__subline {
  font-size: 16px;
  font-weight: 700;
}

.shopify-theme-lab__text {
  font-size: 18px;
  text-align: center;
  margin-bottom: 40px;
}

.shopify-theme-lab__examples {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 40px;
}

.shopify-theme-lab__example {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.shopify-theme-lab__button {
  color: rgb(255,255,255);
  background: rgb(0,0,0);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border-radius: 4px;
  padding: 5px 15px;
  margin-top: 5px;
}

.shopify-theme-lab__button:hover {
  background: rgb(70,70,70);
}
</component>

{% schema %}
{
  "name": "Vue examples",
  "class": "vue-section",
  "presets": [
    {
      "name": "Vue examples"
    }
  ]
}
{% endschema %}

出典・ライセンス

License:
MIT

このコードは uicrooks 著作の MIT ライセンスソースです。 原本の著作権は uicrooks が保有します。日本語訳は ALSEL によるものです。

関連項目

🔌 API連携/JSON出力/JS統合中級

定期販売プランのデータ属性生成

商品バリアントと定期販売プランの ID を HTML data 属性として動的に生成するスニペット。ループで複数プランの ID を data-sellingId-1、data-sellingId-2 のように番号付けして出力する。

📁 theme-tools·MIT·9
🔌 API連携/JSON出力/JS統合中級

カスタム要素の親コンポーネント

Web Components の親要素(`<parent-element>`)でラップし、子スニペットを描画するコンポーネント。カスタム要素に依存した構造を実装する際のテンプレート。

📁 theme-tools·MIT·10
🔌 API連携/JSON出力/JS統合上級

javascript タグ内の JS コード整形

Liquid の `{% javascript %}` タグ内に記述した JavaScript コードを Prettier で自動整形する。純粋な JS であれば完全整形、Liquid 変数を含む場合はインデント調整のみで対応する。

📁 theme-tools·MIT·30
🔌 API連携/JSON出力/JS統合上級

JavaScriptタグ内のコード整形テスト

Liquid の {% javascript %} タグ内に埋め込まれた JavaScript コードを Prettier で整形するテストケース。純粋な JS、Liquid 混在、タブ設定、シングルクォート対応など複数のシナリオをカバーしている。

📁 theme-tools·MIT·38
🔌 API連携/JSON出力/JS統合上級

クイズ結果用の商品データとフィルタ条件を JSON 出力

選択したコレクションの全商品を JSON 形式で抽出し、クイズの回答ごとに設定されたフィルタ条件(価格・タグ・タイプ・ベンダー・オプション)と紐づけることで、JavaScript 側でリアルタイムに商品をマッチングできるようにする。

📁 Sections·MIT·93
🔌 API連携/JSON出力/JS統合上級

サードパーティ製アプリの遅延読み込み最適化

Shopify に統合されたサードパーティ製アプリスクリプトの読み込み方式を管理画面から制御し、ページ表示速度を改善するセクション。スクロール、ユーザーインタラクション、または即座読み込みのいずれかに切り替えられる。

📁 Sections·MIT·769