so i have a Toolbar Item component:
<template>
<div
class="flex cursor-pointer items-center justify-center rounded-full border-2 border-gray-300 p-1 shadow-sm transition-all duration-300 hover:scale-110 hover:bg-black hover:text-white"
@click="$emit('event')"
:class="isActive ? 'bg-black text-white' : ''"
>
<Icon @click="setActive()" :icon="icon" />
</div>
</template>
<script setup>
import { Icon } from '@iconify/vue'
import { defineProps, defineEmits } from 'vue'
import { ref } from 'vue'
const props = defineProps({
icon: String
})
const emits = defineEmits({
event: String
})
const isActive = ref(false)
function setActive() {
isActive.value = !isActive.value
console.log(isActive.value)
}
</script>
<style scoped></style>
that is a child for Toolbar:
<template>
<div class="flex gap-2 rounded-3xl border-2 border-gray-300 p-2 shadow-md">
<TipTapToolbarItem icon="ooui:bold-b"></TipTapToolbarItem>
<TipTapToolbarItem icon="clarity:italic-line"></TipTapToolbarItem>
<TipTapToolbarItem icon="fa-solid:strikethrough"></TipTapToolbarItem>
<TipTapToolbarItem icon="mingcute:heading-1-fill"></TipTapToolbarItem>
<TipTapToolbarItem icon="mingcute:code-fill"></TipTapToolbarItem>
<TipTapToolbarItem icon="tabler:blockquote"></TipTapToolbarItem>
<TipTapToolbarItem icon="octicon:horizontal-rule-16"></TipTapToolbarItem>
</div>
</template>
<script setup>
import TipTapToolbarItem from './TipTapToolbarItem.vue'
</script>
<style scoped></style>
i know i can use v-for...
and then i use the Toolbar
<template>
<TipTapToolbar></TipTapToolbar>
<editor-content class="h-[200px] w-[200px] bg-blue-500" placeholder="tiptap" :editor="editor" />
</template>
ToolbarItem -> Toolbar -> EditorCompontn
how can i use emits here if the Toolbar Item compnent is a child for Toolbar that is a child for a component where is is used? For every item there is a diffrent function..
I think I can use the global store, but is there any other option?
2
Answers
I am not sure, how the data should flow, but for this kind of parent-child communication you are missing the "listener" part.
Documentation: https://vuejs.org/guide/components/events.html
As ToolbarItem emits event with name event (would suggest to change it to something more descriptive :)), try to add listener for it to the parent component with method, that should be called, when the event happens…
e.g.
If you just need parent-child communication, then emits and props are totally fine ways how to do it (and if you don’t mind to couple both components together), for anything more complex a state management is a better option. Probably Pinia would be the best at the current time…
If it’s still not working, try to install Vue.js Devtools and check what is emmited and how…
What you could do is emit and listen to an event using the root element of vue.
This is only if you want to avoid making emits throughout all of your nested child components until you get to the parent one. Here is an example applied to your case:
Child
Top Level Parent
Otherwise a simple chained emit will do just fine
ToolbarItem
TipTapToolbar
EditorCompontn