Home > Software engineering >  How render attributes in component Vue 3
How render attributes in component Vue 3

Time:11-02

I have products two types: simple and configurable:

"products" : [
  {
    "type": "simple",
    "id": 1,
    "sku": "s1",
    "title": "Product 1",
    "regular_price": {
      "currency": "USD",
      "value": 27.12
    },
    "image": "/images/1.png",
    "brand": 9
  },
  {
    "type": "configurable",
    "id": 2,
    "sku": "c1",
    "title": "Product 2",
    "regular_price": {
      "currency": "USD",
      "value": 54.21
    },
    "image": "/images/conf/default.png",
    "configurable_options": [
      {
        "attribute_id": 93,
        "attribute_code": "color",
        "label": "Color",
        "values": [
          {
            "label": "Red",
            "value_index": 931,
            "value": "#ff0000"
          },
          {
            "label": "Blue",
            "value_index": 932,
            "value": "#0000ff"
          },
          {
            "label": "Black",
            "value_index": 933,
            "value": "#000"
          }
        ]
      },
      {
        "attribute_code": "size",
        "attribute_id": 144,
        "position": 0,
        "id": 2,
        "label": "Size",
        "values": [
          {
            "label": "M",
            "value_index": 1441,
            "value": 1
          },
          {
            "label": "L",
            "value_index": 1442,
            "value": 2
          }
        ]
      }
    ],
    "variants": [
      {
        "attributes": [
          {
            "code": "color",
            "value_index": 931
          },
          {
            "code": "size",
            "value_index": 1441
          }
        ],
        "product": {
          "id": 2001,
          "sku": "c1-red-m",
          "image": "/image/conf/red.png"
        }
      },
      {
        "attributes": [
          {
            "code": "color",
            "value_index": 931
          },
          {
            "code": "size",
            "value_index": 1442
          }
        ],
        "product": {
          "id": 2002,
          "sku": "c1-red-l",
          "image": "/image/conf/red.png"
        }
      },
      {
        "attributes": [
          {
            "code": "color",
            "value_index": 932
          },
          {
            "code": "size",
            "value_index": 1441
          }
        ],
        "product": {
          "id": 2003,
          "sku": "c1-blue-m",
          "image": "/image/conf/blue.png"
        }
      },
      {
        "attributes": [
          {
            "code": "color",
            "value_index": 933
          },
          {
            "code": "size",
            "value_index": 1442
          }
        ],
        "product": {
          "id": 2004,
          "sku": "c1-black-l",
          "image": "/image/conf/black.png"
        }
      }
    ],
    "brand": 1
  }
]

The above data I get with actions (Vuex)

GET_PRODUCTS_FROM_API({ commit }) {
  return axios('http://localhost:8080/products', {
    method: 'GET',
  })
    .then((products) => {
      commit('SET_PRODUCTS_TO_STATE', products.data);
      return products;
    })
    .catch((e) => {
      console.log(e);
      return e;
    });
}

then I mutate the data:

SET_PRODUCTS_TO_STATE: (state, products) => {
    state.products = products
}

and get from in getters

PRODUCTS(state) {
    return state.products = state.products.map((product) => {
        const brand = state.brands.find((b) => b.id === product.brand)
        return {...product, brandName: brand?.title || 'no brand'}
    })
}

after which i get the data in the component

At the moment I'm stuck on how to render the color and size attributes of a configurable product. Tell me how to do it right? Do I need to write logic in vuex or parent component?

I tried to push data from parent component to child. But it stopped there again. I also tried to separate the color and size attributes separately using getters.

CodePudding user response:

For Vuex, the syntax is the following

<template>
  <div>
    <div v-for="product in products" :key="product.id">
      <span>type: {{ product.type }}</span>
      <span>type: {{ product.title }}</span>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters(['products']),
    ...mapGetters('fancyNamespace', ['products']), // if namespaced
  },
}
</script>

As of where to call it, directly into the component I guess. Otherwise, as explained here it may not be relevant to use Vuex at all.


PS: you can even rename on the fly if you want.

CodePudding user response:

Solved this issue by Computed Properties and transfer props to child components

computed: {
    getAttributeColors() {
      let attributes_colors = []
      this.product_data.configurable_options.map((item) => {
        if(item.label === 'Color') {
          attributes_colors.push(item.values)
        }
      })
      return attributes_colors
    },
    getAttributeSize() {
      let attributes_size = []
      this.product_data.configurable_options.map((item) => {
        if(item.label === 'Size') {
          attributes_size.push(item.values)
        }
      })
      return attributes_size
    }
  }
  • Related