【问题标题】:How to pass value from one child component to another in VueJS?如何在 VueJS 中将值从一个子组件传递到另一个子组件?
【发布时间】:2020-05-08 09:20:05
【问题描述】:

完整源代码:https://github.com/tenzan/menu-ui-tw

演示:https://flamboyant-euclid-6fcb57.netlify.com/

目标:

ItemsListItemImageMenu.vue 的子组件。我需要将image_urlItemsList 传递给ItemImage,以便在左侧的项目按时间间隔自动更改后更改右侧的图像。

  • 左侧:组件ItemsList.vue
  • 右侧:组件ItemImage.vue

组件 Menu.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

【问题讨论】:

    标签: javascript vue.js vuejs2 tailwind-css vue-props


    【解决方案1】:

    在 ItemsList 组件中使用 image_url 发出一个事件,并在 Menu 组件中将 image_url 作为道具传递给 ItemImage 组件。我在下面的代码框里做了这个检查一下。

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

    【讨论】:

      【解决方案2】:

      您可以尝试使用emitting an event 从子组件到父组件。

      在您的子组件 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);
        }
      

      然后在你的父组件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
              }
          }
      }
      

      我无法测试它,但我希望它有所帮助。

      你也可以在这里查看this的答案。

      附:使用 Vuex 将使这项任务变得容易得多。

      【讨论】:

      • 谢谢。我目前无法测试,但我不会点击。我看到你提到了一个@click 事件...
      • 抱歉,我没有意识到这些行是按时间间隔选择的。然后你只需要将发射事件放在setInterval() 函数中,其中属性highlight 设置为true。我更新了我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 2020-12-30
      • 1970-01-01
      • 2021-10-31
      • 2020-05-22
      • 1970-01-01
      相关资源
      最近更新 更多