Home > Mobile >  Vue: Toggle Button with Data from Child to Parent
Vue: Toggle Button with Data from Child to Parent

Time:12-17

I have a parent component that has numerous containers. Each container has an image and some buttons.

I have over simplified the parent and child components below. When a button is clicked that is within the child component, I would like to toggle the class on an element that is in the parent container. I would like to effect each image individually, not globally. How do I do this?

parent:

<template>
  <div>
    <div :>
      <img src="/path">
    </div>
    <toggleButtons/>
  </div>

  <div>
    <div :>
      <img src="/path">
    </div>
    <toggleButtons/>
  </div>
</template>

<script>
import toggleButtons from './toggleButtons'
export default {
  name: "parent",
  components: {
    toggleButtons
  }
};
</script>

child:


<template>
  <div >
    <a @click="mock = false">Proto</a>
    <a @click="mock = true">Mock</a>
  </div>
</template>

<script>
export default {
  name: "toggleButtons",
  data() {
    return {
      mock: false
    }
  }
};
</script>

CodePudding user response:

Oversimplified example of how you can pass data from child to parent:

Child:

<a @click="$emit('mockUpdated', false)">Proto</a>
<a @click="$emit('mockUpdated', true)">Mock</a>

Parent (template):

<toggleButtons @mockUpdated="doSomething" />

Parent(methods):

doSomething(value) {
  // value will be equal to the second argument you provided to $emit in child
}

CodePudding user response:

There is nothing to do with slots in your case. You need "emit event" to parent from button, and pass mock data to update img states. Slot is a very different thing. There are multiple ways to achive your goal. One way can be something like this:

parent

<AppImage v-for="img in imageData" :key="img.id" :image="img"/>

data() {
  iamges: ["yourPath1", "yourPath2"] 
},
computed: {
  imageData() {
    // adding ID is almost always a good idea while creating Vue apps.
    return this.images.map(x => {
      id: Math.floor(Math.random() * 1000),
      path: x
    })
  }
}

Image.vue

<img :path="image.path" :class={ active: mock} />
<toggleButtons @toggled=changeImageState />

props: [image],
data() {
  mock: ''
},
methods: {
  changeImageState(event) {
    this.mock = event
  }
}

ToggleButtons.vue

<a @click="toggleMock(false)">Proto</a>
<a @click="toggleMock(true)">Mock</a>

emits: ['toggled']
methods: {
  toggleMock(val) {
    this.$emits('toggled', val)
  }
}

Please read the code and let me know if you have any question.

  • Related