问题
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