1

i'm trying to do mini shop app in VueJS without backend, only adding items to shopping cart.

I have component One(Nmdgrey.vue), where i have e.g. boots and "Add to cart" button.

<button @click="addToCart">Add to cart</button>

And function in first component:

methods: {
addToCart() {
  const boots = { name: 'adidas nmd' };
  this.cart.push(boots);

  }
} 

And i have component Two, where i have shopping cart

<div v-for="item in cart">
  {{item.name}}
</div>

And JS

import Nmdgrey from '@/components/Nmdgrey.vue';
export default {
  name: 'Shoppingcart',
  components: 
    Nmdgrey,
  data() {
    return {
      cart: [
        { name: 'adidas adizero' },
      ]
    }
  },
 };

How i can add boots from component One to list in component Two?

I have this.cart.push(boots); in component One but it didn't work

This is what i want but button didn't work: codesandbox

1
  • That 'Add to cart' button is your entire <template> section? Commented Mar 24, 2019 at 13:00

5 Answers 5

2

Use $emit, when child components need to communicate with parent.

Refer official doc:Listening-to-Child-Components-Events

Nmdgrey.vue

<template>
  <div>
    <!-- component 1 -->
    <button @click="add">Add to cart</button>
  </div>
</template>

<script>
export default {
  name: "Numdgrey",
  methods: {
    add() {
      const boots = { name: "adidas nmd" };
      this.$emit("add", boots);
    }
  }
};
</script>

Shoppingcart.vue

<template>
  <div>
    <!-- component 2 -->
    <nmdgrey @add="addCart"></nmdgrey>
    <br>
    <div v-for="(item, index) in cart" :key="index">{{item.name}}</div>
  </div>
</template>

<script>
import Nmdgrey from "./Nmdgrey.vue";
export default {
  name: "ShoppingCart",
  components: {
    Nmdgrey
  },
  data() {
    return {
      cart: [{ name: "adidas adizero" }]
    };
  },
  methods: {
    addCart(good) {
      this.cart.push(good);
    }
  }
};
</script>

Codesandbox demo : https://codesandbox.io/s/z2qz6oy8yp

Sign up to request clarification or add additional context in comments.

Comments

1

From your post I've deduced that what you want to do is to share data from two or more Vue components. For this purpose, you could use Vuex, which provides centralized state management.

This way you could use a vuex mutation to add items to the cart, which could be used from any component. You would also be able to retrieve the cart data from any of them by using vuex getters.

2 Comments

Can you give me some tips for codesandbox.io/s/v616j13rx0 ? It's pretty simple, but u can explain me more
@porithe codesandbox.io/s/kozk1zqjkv Ive added a simple Vuex store at main.js, defining a state holding the cart data, a mutation for said data and a getter to retrieve it. OneComp uses the mutation to modify the state, while TwoComp retrieves the data via the getter. The store's structure is very rudimentary and you may want to improve it thought.
1

you need to create a post method where you take over everything you need from one page to another page. after that everything will get into the cart and you will be able to create your page.

Comments

1

Codesandbox demo : https://codesandbox.io/s/94l44j8j14

Use props to pass the values to cart component.

Nmdgrey.vue

<template>
<div>
  <b>Component 1 : NmdGrey</b><br><br>
<button v-for="(product, index) in boots" :key="index"
@click="addToCart(product.name)" >Add {{product.name}} to Cart</button>
<br><br><hr><br> 
  <shoppingcart :cart="cart" />
  </div>
</template>

<script>
import shoppingcart from './shoppingcart.vue';
export default {
name: 'Nmdgrey',
components:{shoppingcart},
data() {
    return {
      boots:[{name: 'adidas adizero'}, {name: 'puma walker'}, {name: 'nike shoe'}, {name: 'adidas plain'}],
      cart:[],
    }
  },
  methods: {
addToCart(boots) {
  this.cart.push({ name: boots });

  }
} 

}
</script>

Shoppingcart.vue

<template>
  <div>
    <b>Component 2 : Shopping cart</b>
    <br>
    <br>
    <div v-for="(product, index) in cart" :key="index">{{product.name}}</div>
  </div>
</template>

<script>
export default {
  name: "Shoppingcart",
  props: ["cart"],
  data() {
    return {};
  }
};
</script>

5 Comments

Hmm, little mistake is there, because Nmdgrey.vue component is component which have image adidas NMD, and button add to cart, i have 5 component like Nmdgrey(5 type of boots), and all components have Add to cart button, and shopping cart is another page(router)
you dont need 5 components. use a single component and have all the products in an array and list them using v-for . after user choose add to cart for eg. user chooses 3 boots. then have a button Goto Cart . when user clicks that change the route using this.$router.push('shoppingcartroute') and goto shopping cart page.
I have 5 components because i use sliders
if possible upload the code to codesandbox then i can help. Eventhough you use slider no need for 5 components for same type of products. just v-for is enough <slide v-for="product in 5products" />
codesandbox.io/s/v616j13rx0 button don't push items
1

Well, If your application is small, then you can create Vue mixins for addToCart and call it whenever you'll require in your component.

Similar to the methods, you can share data across the components with the use of mixins.

Here is the mixins official docs

Here is the working JsFiddle

Hope this helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.