const detailsTemplate = `

Details

`; const productTemplate = `

{{ title }}

Available?

In stock

Out of stock

Shipping: {{ shipping }}

Colors

Sizes

`; const tabsTemplate = `
{{ tab }}

Reviews

There are no reviews yet.

`; let eventBus = new Vue(); Vue.component("product-details", { props: { details: { type: Array, required: true, }, }, template: detailsTemplate, }); Vue.component("product-review", { template: `

Please correct the following errror(s):

Would you recommend this product?

`, data() { return { name: null, recommend: null, review: null, rating: null, errors: [], } }, methods: { onSubmit(evt) { this.errors = []; if (this.name && this.review && this.rating && this.recommend) { const productReview = { name: this.name, rating: this.rating, recommend: this.recommend, review: this.review, }; eventBus.$emit("review-submitted", productReview); this.name = null; this.rating = null; this.recommend = null; this.review = null; } else { for (const field of ["name", "rating", "recommend", "review"]) { if (!this[field]) { this.errors.push(`${field} required`); } } } } } }); Vue.component("product-tabs", { props: { reviews: { type: Array, required: true, } }, template: tabsTemplate, data() { return { selectedTab: "Reviews", tabs: ["Reviews", "Make a Review"], } } }); Vue.component("product", { props: { isPremium: { type: Boolean, required: true, } }, template: productTemplate, // Computer properties are cached until dependencies change. // => cheaper than methods. computed: { image() { const image = this.variants[this.selectedVariant].variantImage; return image; }, inStock() { return this.variants[this.selectedVariant].variantQuantity > 0; }, shipping() { if (this.isPremium) { return "Free"; } return "2.99 €"; }, title() { return [this.brand, this.product].join(' '); } }, data() { return { brand: "Vue Mastery", description: "Chaussettes montantes", details: [ "80% cotton", "20% polyester", "Gender-neutral", ], inventory: 15, link: "https://www.google.com/search?q=vuejs+socks", product: "Socks", reviews: [], selectedVariant: 0, sizes: [34, 36, 38, 40, 42, 44, 46], variants: [ { variantId: 2234, variantColor: "green", variantImage: "./assets/img/vmSocks-green-onWhite.jpg", variantQuantity: 10, }, { variantId: 2235, variantColor: "blue", variantImage: "./assets/img/vmSocks-blue-onWhite.png", variantQuantity: 0, }, ] } }, methods: { addToCart() { this.variants[this.selectedVariant].variantQuantity--; this.$emit("add-to-cart", this.variants[this.selectedVariant].variantId); }, removeFromCart() { this.variants[this.selectedVariant].variantQuantity++; this.$emit("remove-from-cart", this.variants[this.selectedVariant].variantId); }, updateImage(index) { this.selectedVariant = index; } }, mounted() { eventBus.$on('review-submitted', productReview => { this.reviews.push(productReview); }); } }); const app = new Vue({ el: "#app", data: { cart: [], isPremium: false, }, methods: { removeItem(id) { console.log("removeItem", id); const index = this.cart.indexOf(id); if (index > -1) { this.cart.splice(index, 1); } }, updateCart(id) { console.log("updateCart", id); this.cart.push(id); } } });