How to pass value from one child component to another in VueJS?

不问归期 提交于 2020-02-03 10:20:50

问题


Full source code: https://github.com/tenzan/menu-ui-tw

Demo: https://flamboyant-euclid-6fcb57.netlify.com/

Goal:

ItemsList and ItemImage are child components to Menu.vue. I need to pass the image_url from ItemsList to ItemImage, in order to change the image on right, after item on left is changed automatically on time intervals.

  • Left side: component ItemsList.vue
  • Right side: component ItemImage.vue

Component Menu.vue has 2 child components:

<template>
  <div>
    <!-- Two columns -->
    <div class="flex mb-4">
      <div class="w-1/2 bg-gray-400">
        <ItemsList />
      </div>
      <div class="w-1/2 bg-gray-500">
        <ItemImage></ItemImage>
      </div>
    </div>
  </div>
</template>

<script>
import ItemsList from "./ItemsList";
import ItemImage from "./ItemImage";

export default {
  components: {
    ItemsList,
    ItemImage
  }
};
</script>

ItemsList.vue:

<template>
  <div>
    <div v-for="item in menuItems" :key="item.name">
      <ul
        class="flex justify-between bg-gray-200"
        :class="item.highlight ? 'highlight' : ''"
      >
        <p class="px-4 py-2 m-2">
          {{ item.name }}
        </p>
        <p class="px-4 py-2 m-2">
          {{ item.price }}
        </p>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      menuItems: [
        {
          name: "Apple",
          price: 20,
          image_url: "../assets/images/apple.jpg"
        },
        {
          name: "Orange",
          price: 21,
          image_url: "../assets/images/orange.jpg"
        },
        {
          name: "Banana",
          price: 22,
          image_url: "../assets/images/banana.jpg"
        },
        {
          name: "Grape",
          price: 23,
          image_url: "../assets/images/grape.jpg"
        }
      ]
    };
  },
  created() {
    var self = this;
    self.menuItems.map((x, i) => {
      self.$set(self.menuItems[i], "highlight", false);
    });
    var init = 0;
    setInterval(function() {
      if (init === self.menuItems.length) {
        init = 0;
      }
      self.menuItems[init].highlight = true;
      if (init === 0) {
        self.menuItems[self.menuItems.length - 1].highlight = false;
      } else {
        self.menuItems[init - 1].highlight = false;
      }
      init++;
    }, 2000);
  }
};
</script>

<style scoped>
.highlight {
  background-color: gray;
}
</style>

ItemImage.vue - almost empty

<template>
  <div><p>Hello from ItemImage component</p></div>
</template>

<script>
export default {
  props: ["image_url"]
};
</script>

ItemsList iterates through each item and highlights it. I will need component ItemImage to show an image for that active/highlighted item. URL for an image is item.image_url .


回答1:


Emit an event in ItemsList component with image_url and in Menu component pass image_url to ItemImage component as a prop. I did this in below codesandbox check it out.

https://codesandbox.io/s/wild-moon-mbto4




回答2:


You can try with emitting an event from the child to the parent component.

In your child component ItemsList.vue, emit an event to the parent component (where the highlight property is set to true):

created() {
    var self = this;
    self.menuItems.map((x, i) => {
      self.$set(self.menuItems[i], "highlight", false);
    });
    var init = 0;
    setInterval(function() {
      if (init === self.menuItems.length) {
        init = 0;
      }
      self.menuItems[init].highlight = true;

      //emit an event to trigger parent event
      this.$emit('itemIsHighlighted', menuItems[init].image_url)

      if (init === 0) {
        self.menuItems[self.menuItems.length - 1].highlight = false;
      } else {
        self.menuItems[init - 1].highlight = false;
      }
      init++;
    }, 2000);
  }

Then in your parent component Menu.vue:

<ItemsList @itemIsHighlighted="onItemHighlighted"/>
<ItemImage :image_url="this.selectedItem" ></ItemImage>

...

export default {
    data() {
        return {
            selectedItem: '' 
        } 
    }, 
    methods: {
        onItemHighlighted(value) {
            console.log(value) // someValue
            this.selectedItem = value
        }
    }
}

I couldn't test it, but I hope it helps.

You can also check this answer here.

P.S. Using Vuex would make this task a lot easier.



来源:https://stackoverflow.com/questions/59855921/how-to-pass-value-from-one-child-component-to-another-in-vuejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!