Как передать значение от одного дочернего компонента другому в VueJS? - PullRequest
3 голосов
/ 22 января 2020

Полный исходный код: https://github.com/tenzan/menu-ui-tw

Демонстрация: https://flamboyant-euclid-6fcb57.netlify.com/

Цель:

ItemsList и ItemImage являются дочерними компонентами Menu.vue. Мне нужно передать image_url от ItemsList до ItemImage, чтобы изменить изображение справа, после того, как элемент слева будет автоматически изменен по временным интервалам.

  • Левая сторона: компонент ItemsList.vue
  • Правая сторона: компонент ItemImage.vue

enter image description here

Компонент Меню. vue имеет 2 дочерних компонента:

<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 - почти пусто

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

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

ItemsList перебирает каждый элемент и выделяет его. Мне понадобится компонент ItemImage , чтобы показать изображение для этого активного / выделенного элемента. URL для изображения: item.image_url.

Ответы [ 2 ]

4 голосов
/ 22 января 2020

Создайте событие в компоненте ItemsList с помощью image_url, а в компоненте Menu передайте image_url компоненту ItemImage в качестве реквизита. Я сделал это в приведенных ниже кодах и проверить его.

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

2 голосов
/ 22 января 2020

Можно попробовать с передать событие от дочернего к родительскому компоненту.

В вашем дочернем компоненте ItemsList. vue, отправьте событие родительскому компоненту (для свойства highlight установлено значение 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);
  }

Тогда в родительском компоненте Меню. 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
        }
    }
}

Я не смог проверить это, но надеюсь, что это поможет.

Вы также можете проверить this ответ здесь.

PS Использование Vuex значительно упростит эту задачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...