0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

公式ホームページのIntro to Vue 3クラス7 (Class & Style Binding)

Last updated at Posted at 2022-02-08

7. Class & Style Binding

クラス https://www.vuemastery.com/courses/intro-to-vue-3/event-handling-vue3

VS Codeから該当フォルダを選択して、開きます。その後に、配下のgit部分をクリックして、ブランチをL7-startへ入れ替えてください。

ブランチ切り替え方法 https://qiita.com/phjg81/items/e6695eb2334d9297a318

今日のポイントはアップデータに基づいてクラスとスタイルのバインドを行うことです。

main.js
const app = Vue.createApp({
    data() {
        return {
            cart:0,
            product: 'Socks',
            brand: 'Vue Mastery',
            image: './assets/images/socks_blue.jpg',
            inStock: false,
            details: ['50% cotton', '30% wool', '20% polyester'],
            variants: [
              { id: 2234, color: 'green', image: './assets/images/socks_green.jpg' },
              { id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg' },
            ]
        }
    },
    methods: {
        addToCart() {
            this.cart += 1
        },
        updateImage(variantImage) {
            this.image = variantImage
        }
    }
})


index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Vue Mastery</title>
    <!-- Import Styles -->
    <link rel="stylesheet" href="./assets/styles.css" />
    <!-- Import Vue.js -->
    <script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script>
  </head>
  <body>
    <div id="app">
      <div class="nav-bar"></div>

      <div class="cart">Cart({{ cart }})</div>
      
      <div class="product-display">
        <div class="product-container">
          <div class="product-image">
            <img v-bind:src="image">
          </div>
          <div class="product-info">
            <h1>{{ product }}</h1>
            <p v-if="inStock">In Stock</p>
            <p v-else>Out of Stock</p>
            <ul>
              <li v-for="detail in details">{{ detail }}</li>
            </ul>

            <div 
              v-for="variant in variants" 
              :key="variant.id" 
              @mouseover="updateImage(variant.image)"
            >{{ variant.color }}</div>
            <button class="button" @click="addToCart">Add to Cart</button>
          </div>
        </div>
      </div>
    </div>

    <!-- Import App -->
    <script src="./main.js"></script>

    <!-- Mount App -->
    <script>
      const mountedApp = app.mount('#app')
    </script>
  </body>
</html>

スタイルバインド

greenやblueの文字を各色の丸として表示して、それにマウスオーバー時に靴下の色が変わるようにやりましょう。
まずは、variantのdivに下記のようにcolor-circleクラスを追記して、styleをバインドするために:styleとして、追記します。
:styleへ変更することにより、内部はjavascriptになります。それで、スタイルの属性名がcamelCaseにするか、''に囲めて書く必要があります。他には全体のバインドも可能です。

index.html
:style="{ backgroundColor: variant.color }"
<!-- 又は -->
:style="{ 'background-color': variant.color }"
<!-- 又は -->
:style="styles"
main.js
const app = Vue.createApp({
    data() {
        return {
            ...
            styles: {
               color: 'red',
               fontSize: '14px'
            }
        }
    },
    methods: {
        ...
    }
})


その後に、内部の「{{ variant.color }}」を削除します。

index.html
            <div 
              v-for="variant in variants" 
              :key="variant.id" 
              @mouseover="updateImage(variant.image)"
              class="color-circle"
              :style="{ backgroundColor: variant.color }"
            ></div>
            <button class="button" @click="addToCart">Add to Cart</button>
          </div>

style.cssはassetsフォルダは以下にあります。color-circleは既にあるので、何もやる必要はないです。
image.png

style.css
.color-circle {
  width: 50px;
  height: 50px;
  margin-top: 8px;
  border: 2px solid #d8d8d8;
  border-radius: 50%;
}

image.png

クラスバインド

inStockデータがfalseの場合には「Add to Cart」を非活性化表示して、trueの場合には「Add to Cart」を活性化表示して見ます。

index.html
<button class="button" @click="addToCart">Add to Cart</button>
index.html:disabled追記
<button class="button" :disabled="!inStock" @click="addToCart">Add to Cart</button>

見た目も活性化による区分ができるようにやります。

style.css
.disabledButton {
  background-color: #d8d8d8;
  cursor: not-allowed;
}
index.html:class追記
<button class="button" :class="{ disabledButton: !inStock }" :disabled="!inStock" @click="addToCart">Add to Cart</button>

image.png

条件でやるクラスと固定のクラスを両方する場合は下記のように結合され、適応されます。

index.html
            <div 
              v-for="variant in variants" 
              :key="variant.id" 
              @mouseover="updateImage(variant.image)"
              class="color-circle"
              :style="{ backgroundColor: variant.color }"
            ></div>
index.html:class追記
            <div 
              v-for="variant in variants" 
              :key="variant.id" 
              @mouseover="updateImage(variant.image)"
              class="color-circle"
              :class="{ active: activeClass }"
              :style="{ backgroundColor: variant.color }"
            ></div>
main.js:activeClass追記
const app = Vue.createApp({
    data() {
        return {
            ...
            activeClass: true
        }
    },
    methods: {
        ...
    }
})


レンダリング後は下記のものになります。

index.html
<div class="color-circle active"></div>

三項演算子

index.html
            <div 
              v-for="variant in variants" 
              :key="variant.id" 
              @mouseover="updateImage(variant.image)"
              class="color-circle"
              :class="{ active: activeClass }"
              :style="{ backgroundColor: variant.color }"
            ></div>
index.html:三項演算子追記
            <div 
              v-for="variant in variants" 
              :key="variant.id" 
              @mouseover="updateImage(variant.image)"
              class="color-circle"
              :class="[ isActive? activeClass : '' ]"
              :style="{ backgroundColor: variant.color }"
            ></div>
main.js:isActive追記
const app = Vue.createApp({
    data() {
        return {
            ...
            isActive: true
        }
    },
    methods: {
        ...
    }
})


今回の課題はinStockがfalseの場合、商品イメージにout-of-stock-imgクラスをバインドして見たください。

課題確認
main.js
const app = Vue.createApp({
    data() {
        return {
            cart:0,
            product: 'Socks',
            brand: 'Vue Mastery',
            image: './assets/images/socks_blue.jpg',
            inStock: false,
            details: ['50% cotton', '30% wool', '20% polyester'],
            variants: [
              { id: 2234, color: 'green', image: './assets/images/socks_green.jpg' },
              { id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg' },
            ]
        }
    },
    methods: {
        addToCart() {
            this.cart += 1
        },
        updateImage(variantImage) {
            this.image = variantImage
        }
    }
})

index.html
            <!-- solution -->
            <img :class="{ 'out-of-stock-img': !inStock }" v-bind:src="image">  

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?