When attempting to call the event outside of the component, the functionality of the event in VUE.js does not work

Currently, I am working on a small product page following the guidelines from this Vue.js tutorial. The page consists of a product component which includes an "add to cart" button. However, the actual cart is located outside the component in index.html, so the cart property is stored within the root vue app (identified by the id 'app').

Issue: I need assistance with getting the "add to cart" button to update the cart quantity. I'm having trouble implementing this functionality using the methods addToCart and updateCart as demonstrated in the tutorial.

If anyone can provide guidance on resolving this matter, your help would be greatly appreciated! Thank you in advance!

Vue.component('product', {
    props: {
      premium: { // definition removed for brevity
      },
    template: `
    /* Continued component code */
    `,
    data() {
    // Data object content removed for brevity
      
        variants: [ // Variant data details removed for brevity
            {
              variantId: 2234,
              variantQuantity: 15,
              variantColor: "green",
              variantImage: "./assets/vmSocks-green.jpg"     
            },
            {
              variantId: 2235,
              variantQuantity: 0,
              variantColor: "blue",
              variantImage: "./assets/vmSocks-blue.jpg"
            }
        ]
      }
    },
    methods: {
    // Methods implementation omitted for brevity
    },
    computed: {
    // Computed properties definition omitted for brevity
    }
  })
  
  var app = new Vue({
    el: '#app',
    data: {
      premium: true,
      cart: 0
    },
    methods: {
        updateCart() {
          this.cart += 1
        }
    }
  })

/* CSS styles omitted for brevity */ 
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewpoint" content="width=devide-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
        <title>Vue app</title>
    </head>
    <body>
        <div class="nav-bar"></div>

        <div id="app">
            <div class="cart">
                <p>Cart({{ cart }})</p>
            </div>
            
            <product :premium="premium" @add-to-cart="updateCart"></product>    
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="prior.js"></script>
    </body> 
</html>

Answer №1

Revise This:

 <button :class="{ disabledButton: !inStock }" v-on:click="add-to-cart" :disabled="!inStock">Add to Cart</button>

Instead, make it like this:

 <button :class="{ disabledButton: !inStock }" v-on:click="addToCart" :disabled="!inStock">Add to Cart</button>

So the function now is addToCart, and it will emit an event called add-to-cart

You can also trigger the emit onClick without adding a separate function:

 <button :class="{ disabledButton: !inStock }" v-on:click="$emit('add-to-cart')" :disabled="!inStock">Add to Cart</button>

Vue.component('product', {
    props: {
      premium: {
        type: Boolean,
        required: true
      }
    },
    template: `
    <div id="product">
    
      <div class="product-image">
      <img :src="image" />      
      </div>
      
      <div class="product-info">
      
        <h1>{{ title }}</h1>
        <p>Shipping: {{ shipping }}</p>
        
        <p v-if="inStock">In Stock</p>
        <p v-else>Out of Stock</p>
        
        <h2>Details</h2>
        <ul>
          <li v-for="detail in details">{{ detail }}</li>
        </ul>

        <h3>Colors:</h3>
        <div v-for="(variant,index) in variants" :key="variant.variantId">
          <div class="color-box" :style="{ backgroundColor: variant.variantColor }" @mouseover="updateProduct(index)"></div>
        </div>

        <button :class="{ disabledButton: !inStock }" v-on:click="addToCart" :disabled="!inStock">Add to Cart</button>
      </div>

    </div>
    `,
    data() {
      return {
        product: "Socks",
        brand: "Vue Mastery",
        selectedVariant: 0,
        details: ["80% cotton", "20% polyester", "Gender-neutral"],
        variants: [
            {
              variantId: 2234,
              variantQuantity: 15,
              variantColor: "green",
              variantImage: "./assets/vmSocks-green.jpg"     
            },
            {
              variantId: 2235,
              variantQuantity: 0,
              variantColor: "blue",
              variantImage: "./assets/vmSocks-blue.jpg"
            }
        ]
      }
    },
    methods: {
      addToCart() {
        this.$emit('add-to-cart')
      },
      updateProduct(index) {
        this.selectedVariant = index
      }
    },
    computed: {
      title() {
        return this.brand + ' ' + this.product
      },
      image() {
        return this.variants[this.selectedVariant].variantImage
      },
      inStock() {
        if (this.variants[this.selectedVariant].variantQuantity > 0) {
          return true
        } else {
          return false
        }
      },
      shipping() {
        if (this.premium) {
          return "Free"
        } else {
          return 2.99
        }
      }
    }
  })
  
  var app = new Vue({
    el: '#app',
    data: {
      premium: true,
      cart: 0
    },
    methods: {
        updateCart() {
          this.cart += 1
        }
    }
  })
body {
  font-family: tahoma;
  color:#282828;
  margin: 0px;
}

.nav-bar {
  background: linear-gradient(-90deg, #84CF6A, #16C0B0);
  height: 60px;
  margin-bottom: 15px;
}

.product {
  display: flex;
  flex-flow: wrap;
  padding: 1rem;
}

img {
  border: 1px solid #d8d8d8;
  width: 70%;
  margin: 40px;
  box-shadow: 0px .5px 1px #d8d8d8;
}

.product-image {
  width: 80%;
}

.product-image,
.product-info {
  margin-top: 10px;
  width: 50%;
}

.color-box {
  width: 40px;
  height: 40px;
  margin-top: 5px;
}

.cart {
  margin-right: 25px;
  float: right;
  border: 1px solid #d8d8d8;
  padding: 5px 20px;
}

button {
  margin-top: 30px;
  border: none;
  background-color: #1E95EA;
  color: white;
  height: 40px;
  width: 100px;
  font-size: 14px;
} 

.disabledButton {
  background-color: #d8d8d8;
}

.review-form {
  width: 400px;
  padding: 20px;
  margin: 40px;
  border: 1px solid #d8d8d8;
}

input {
  width: 100%;  
  height: 25px;
  margin-bottom: 20px;
}

textarea {
  width: 100%;
  height: 60px;
}

.tab {
  margin-left: 20px;
  cursor: pointer;
}

.activeTab {
  color: #16C0B0;
  text-decoration: underline;
}
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewpoint" content="width=devide-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
        <title>Vue app</title>
    </head>
    <body>
        <div class="nav-bar"></div>

        <div id="app">
            <div class="cart">
                <p>Cart({{ cart }})</p>
            </div>
            
            <product :premium="premium" @add-to-cart="updateCart"></product>    
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="prior.js"></script>
    </body> 
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Stop images from flipping while CSS animation is in progress

I've been developing a rock paper scissors game where two images shake to mimic the hand motions of the game when a button is clicked. However, I'm facing an issue where one of the images flips horizontally during the animation and then flips bac ...

Include new items in the li tag using JavaScript

Hello, I am looking to dynamically add elements to an LI element when a link is clicked. I have successfully added elements to a DIV using the following code snippet: I came across a similar question on Which "href" value should I use for JavaScript links ...

Comparative analysis within the JSON object

I have a sample JSON object with the following format: var data = [{"value":"S900_Aru","family":"S400"}, {"value":"S500_Aru","family":"S400"}, {"value":"2610_H","family":"A650"}] The first two values are related to the same f ...

Encountered an issue when trying to establish the session description: An error occurred while attempting to set the remote answer SDP: Request was made in an inappropriate state

Using Angular JS to Get Room Id/Token from Server Side for WebSocket Connection Code Snippet Used in Application - app.controller("videoCallingController", ["$scope", "$location", "$rootScope", "$localStorage", 'AuthenticationService', "CommonS ...

Movement and physics mechanics for players using Physi.js

As I work on a basic game using Three.js for rendering and Physijis for physics, my question can be applied to games in general. In games, players often display movement that appears disconnected from the physics engine. They can accelerate instantly and ...

What is the best way to increase the font size without resizing the parent input element?

Is there a way to increase the font size in this text box without enlarging the box itself? Any suggestions or advice would be appreciated! https://i.sstatic.net/91pon.jpg. Below is my CSS code for reference (the class of the form is 'box'). .bo ...

Manipulating data with Entity Framework using Knockout and AngularJS

When creating a knockout restful service, the first attempt was successful. However, upon implementing it in Angular, there were issues with the database displaying an ID with other fields labeled as undefined. Trying to fix this, I recreated the WCF Servi ...

Use javascript/ajax to create a dynamic dropdown menu

I have successfully retrieved data from an ajax and JSON request on another php page. Using json parse, I was able to extract two array strings. JAVASCRIPT: if (xmlhttp.readyState==4 && xmlhttp.status==20 { var data = JSON.parse(xmlhttp.respon ...

What is the best way to handle the select event for a jQuery UI autocomplete when there are images involved?

Looking for help with creating an autocomplete feature with images on this jsfiddle. Despite trying to capture the event when a user selects an image, it doesn't seem to work properly: $("#input").autocomplete({ //source: tags, so ...

Determine the vertical scrolling and the width of the window in a specific function

I need assistance with displaying a div based on the window width. The requirement is for the div to show when the window width is 1350px or wider. However, if the window is narrower than 1350px, the following rules apply: 1) The div should be hidden if t ...

Nested div elements maintain background-image continuity

Is it possible to maintain the background image of the body within a child div that has a red background color with opacity? * { box-sizing: border-box; } body { background-image: url('https://d6scj24zvfbbo.cloudfront.net/306f4bc782c04bbe4939f8c ...

Having some trouble getting the text to float alongside an image properly in HTML and CSS

I'm having trouble positioning my text next to an image. I've tried floating it to the right and even using a flexbox, but nothing seems to be working well. Here is the code I have... <div class="tab-content"> <div clas ...

Tug and release technique

If you visit this website, you will find a detailed explanation of a drag-and-drop algorithm. Focusing on the initial code snippet provided in the article, it emphasizes the importance of using document in document.addEventListener('mousemove', ...

Is it possible to target all children with CSS3 if a certain number of children are present?

I've been racking my brain trying to select all children if there are x or more children present. I want to be able to select all child elements if there are at least x children. So far, I've managed to target all children when there are exactl ...

Unable to simultaneously execute TypeScript and nodemon

Currently, I am in the process of developing a RESTful API using Node.js, Express, and TypeScript. To facilitate this, I have already installed all the necessary dependencies, including nodemon. In my TypeScript configuration file, I made a modification to ...

Enhancing Rails: Tailoring the flash message to suit individual needs

I am embarking on my journey with ruby on rails and could use some guidance with the following scenario. In the application.html.erb file, flash messages are configured to fade out after a few seconds by default. <div id="message" class="modal alert a ...

In a carousel slider, the height and width of divs are not set to specific dimensions

For a code snippet, you can visit this link: here The html: <html lang="en"> <head> <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,700i|Merriweather:300,400,700" rel="stylesheet"> <link href="https://ma ...

Filter error - Unable to retrieve property 'toLowerCase' from null value

When filtering the input against the cached query result, I convert both the user input value and database values to lowercase for comparison. result = this.cachedResults.filter(f => f.prj.toLowerCase().indexOf((this.sV).toLowerCase()) !== -1); This ...

Repeating every 3 to 6 months on later.js commencing from a specified date

Currently, I am working on setting up recurring events every 3 and 6 months using the later.js library which can be found at https://github.com/bunkat/later. The code implementation looks like this: // Assuming my value.scheduled_date is set to 2018-09-0 ...

Creating Sub Menu in Blogger with pageListJSON

I am looking to enhance the menu on my blog by adding a sub-menu structure. Specifically, I want to organize my menu to include "Manual Testing" and "Automated Testing" as sub-menus under the main category of "Testing". Testing Manual Testing Automated ...