Shopifyテーマ+ vuejs +カスタム要素


これは2部投稿です
  • 第1部思想(現)

  • 力を利用するWeb Components 今あなたのお気に入りのJavaScriptフレームワークを使用してフレームワークのagnostic複雑なUIを作成することが可能です.最近、私はvue-custom-element Shopifyテーマを構築する.私の最初のこれまでの個人的なブログ記事であるこの記事では、私はアイデアとそれを実装することに直面した課題を説明するつもりです.

    なぜ
    それは主にVuejsで開発し、そのアプリケーションの端を動かして私の個人的な好みです.あなたが従来のShopifyテーマより柔軟であるテーマで終わるとわかります.

    考え
    簡単に言えば、アイデアは、液体のテンプレートファイルのカスタム要素を使用して、それらにデータを渡すことですprops and slot 例えば、次のようにして液体オブジェクトを受け入れるカスタム要素ですorders プロップ
    <my-orders orders="{{-customer.orders | json-}}"></my-orders>
    

    液体は固体ではない
    買い物使いLiquid ファイルBlade あなたがラーラヴの世界から来た場合、しかし、違いはブレードが開発者と液体のために設計されているということです.
    ここでカートの項目を表示するには、最小限のスニペットですtemplates/cart.liquid ファイル
    <table class="responsive-table">
      <thead>
        <tr>
          <th colspan="2">Product</th>
          <th>Price</th>
          <th>Quantity</th>
          <th>Total</th>
        </tr>
      </thead>
      <tbody>
        {% for item in cart.items %}
          <tr >
            <td>
              {% if item.image != blank %}
              <a href="{{ item.url | within: collections.all }}">
                {{ item | img_url: '240x240' | img_tag: item.title }}
              </a>
              {% endif %}
            </td>
            <td>
              <a href="{{ item.url }}">{{ item.product.title }}</a>
    
              {% unless item.product.has_only_default_variant %}
                <p>{{ item.variant.title }}</p>
              {% endunless %}
    
              <p>{{ item.vendor }}</p>
    
              {%- assign property_size = item.properties | size -%}
    
              {% if property_size > 0 %}
                {% for p in item.properties %}
                    {% unless p.last== blank %}
                        {{ p.first }}:
                        {% if p.last contains '/uploads/' %}
                            <a href="{{ p.last }}">{{ p.last | split: '/' | last }}</a>
                        {% else %}
                            {{ p.last }}
                        {% endif %}
                    {% endunless %}
                {% endfor %}
            {% endif %}
    
              <a href="/cart/change?line={{ forloop.index }}&amp;quantity=0">
                <small>Remove</small>
              </a>
            </td>
    
            <td data-label="{{ 'cart.label.price' | t }}">
                {% if item.original_line_price != item.line_price %}
                    {{ item.price | money }} <s>{{ item.original_price | money }}</s>
                {% else %}
                    {{ item.price | money }}
                {% endif %}
            </td>
    
            <td>
              <input
                type="number"
                name="updates[]"
                id="updates_{{ item.key }}"
                value="{{ item.quantity }}"
                min="0"
              />
            </td>
    
            <td>
              {{ item.line_price | money }}
            </td>
          </tr>
    
          {% endfor %}
        </td>
      </tbody>
    </table>
    
    退屈!私は2008年に感じる!また、ユーザーが数量を更新するときには、静的なときに、彼らは項目を削除すると、ページを再読み込みするページを読み込みます.最新のルックアンドフィールを追加するには(別名.より良いUX)のための唯一の方法は、フォームの提出を防ぐためにJQueryやJSコードを追加するにはCart API そしてDOMを操作する.
    私が液体について理解しないもう一つのことは、それがビューと一緒にロジックを実装するのを奨励するということです.それは解読できず、コードを維持するのが難しい.それはBaldeのケースではありません.なぜなら、Shopifyでは不可能なロジックを抽象化するためのオプションを持っているからです.

    カスタム要素
    カスタム要素を使用すると、いくつかの楽しみを持っているVuejsにすべてを移動することが可能です.その意味でtemplates/cart.liquid がなる.
    {% if cart.item_count > 0 %}
      <cart-items items:'{{-cart.items | json-}}'></cart-items>
    {% else %}
      <p>Cart is empty</p>
    {% endif %}
    
    すごい!今、我々はそれを使用することができますvuejsを使用します.

    VUEコンポーネント
    The CartItems.vue ファイルをカスタム要素として登録することができますvue-custom-element パッケージ.
    <template>
      <LineItem v-for="line in cartItems" :key="line.id" :item="line"> </LineItem>
    </template>
    
    <script>
      export default {
        props: ["items"],
        data() {
          return {
            cartItems: [],
          };
        },
        created() {
          this.cartItems = parseJson(this.items);
        },
      };
    </script>
    
    ここで我々は受け入れるitems Propとして、それがJSONストリングであるので、我々は使用する必要がありますJSON.parse オブジェクトに変換するには.

    国家管理
    カートの項目をアプリケーションの状態とし、他のすべてのコンポーネントにアクセスできます.たぶん、我々はヘッダーでカートアイコンにカウンターを示す必要があります.それは我々の状態を使用することができ、それは楽に反応する.ユーザーがカートにアイテムを追加するとき.我々は、カートの状態を変異即座に私たちの小さなカウンタが更新されます.
    そのためには、すべての状態管理ライブラリを使用することができますVuex . VUEXインスタンスを作成し、登録されているすべてのカスタム要素に渡すことができます.
    しかし、問題は、これはスパではない、VUEXのストアは、メモリ内の状態は、いつでも別のShopifyルートに移動するVEUXストアデータが破壊されます.そこに簡単な解決策があります.我々は、州で永続することができますwindow.LocalStorage . そのように、我々はVuexがロードされるとき、LocalStorageから店を水和させます.
    反応性を除いて、これに対するもう一つの利点は、それが我々に重要な小さなUX改善を提供するということです.私は多くのユーザーが新しいタブでPDPページを開いている間、製品リストを閲覧して気づいた.それから、あなたが製品ページに行って、あなたのカートに1を加えるならば、他のタブは州についてのどんな考えも持ちません.それで、彼らはあなたのUX開発者を幸せにするつもりでない再び再びリフレッシュする必要があります.
    今、我々は国家を維持しているので、我々も聞くことができます
    window.addEventListener('storage', function (event) {...})
    
    そして、状態を変異します.ビンゴ!あなたがカートに製品を加えるならば、すべての開いたタブは最新版を得ます.

    次は何
    私は、実装とプロジェクト構造を詳細に説明します.
    当初公開https://ajahandideh.com/shopify-theme-vuejs-custom-elements-part-1-the-idea/