In my app, I have 4 components:
- App.vue
- ProfileCardSlider
- ProfileCard
- ColorPicker
The idea is users would be able to update the background color of their ProfileCard using the element.
I can't work out how I can get the color value from the input and then emit that value up to the parent (App.vue in this case). In App.vue I believe I also need a color data property which this emitted value would then update and pass down as props to the ProfileCard.
These are my two components:
App.vue
import ProfileCardSlider from "./components/ProfileCardSlider.vue";
import ColorPicker from "./components/ColorPicker.vue";
export default {
components: {
ProfileCardSlider,
ColorPicker,
},
data() {
return {
color: "red",
};
},
methods: {
updateColor() {
this.color = color;
},
},
};
</script>
<template>
<ColorPicker :color="color" @select-color="updateColor" />
<ProfileCardSlider :color="color" />
</template>
ColorPicker.vue
<script>
export default {
props: ["color"],
methods: {
selectColor(color) {
this.$emit('update-color', color)
},
},
};
</script>
<template>
<div >
<h2 >Card background colour:</h2>
<input type="color" @change="selectColor" />
</div>
</template>
CodePudding user response:
Using v-model and props in the correct way can help achieve this.
- In your
App.vue
, use the color data property as hex (best practice to use in props), i.e #000000, and bind the color property to v-model toColorPicker
component. - Then in
ColorPicker
component, use the value prop which is the v-model binding fromApp.vue
, and emit an input event on color input updating. - At last, listen to the color-changing event in
App.vue
to pass the updated color toProfileCardSlider.vue
.
So, the final code should be-
App.vue
<template>
<div>
<ColorPicker v-model="color" @input="updateColor" />
<ProfileCardSlider :color="color" />
</div>
</template>
<script>
import ProfileCardSlider from "./components/ProfileCardSlider.vue";
import ColorPicker from "./components/ColorPicker.vue";
export default {
name: "App",
data() {
return {
color: "#ffffff",
};
},
components: {
ProfileCardSlider,
ColorPicker,
},
methods: {
updateColor(color) {
this.color = color;
},
},
};
</script>
ColorPicker.vue
<template>
<div >
<h2 >Card background colour:</h2>
<input
type="color"
:value="value"
@input="$emit('input', $event.target.value)"
/>
</div>
</template>
<script>
export default {
name: "ColorPicker",
props: ["value"]
};
</script>
<style>
</style>
ProfileSlider.vue
(I take some dummy code for this component as you didn't mention in the question but the logic would be the same.)
<template>
<div >
<div :style="{ background: color }">
<h4><b>John Doe</b></h4>
<p>Architect & Engineer</p>
</div>
</div>
</template>
<script>
export default {
name: "ProfileCardSlider",
props: {
color: {
required: true,
},
},
};
</script>
<style>
.card {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
width: 40%;
}
.container {
padding: 2px 16px;
}
</style>
You should see that when you will change the color from the color input which is inside ColorPicker.vue
, the card inside ProfileSlider.vue
will have an updated color.