I want to create context menu. By the nature of the contextmenu depending on the location of usage the entries differ. Therefor I am trying to create a Vue.js 3 component that allows a list to be defined within its innerHtml, rather than passing the list as a prop.
A example usage I have in mind should look like the following example:
<!-- when using in a list of articles -->
<contextMenu>
<item name="copy" @click="copyMethod"/>
<item name="delete" @click="deleteMethod"/>
</contextMenu>
<!-- in a list of users -->
<contextMenu>
<item name="edit user" @click="editMethod"/>
<item name="delete user" @click="deleteMethod"/>
</contextMenu>
as far as I unterstood, slots
are not the solution to my problem since they seem to be the inverse.
Something like this but without the list as property
const ContextMenu = {
template:
`<div>
<span v-for="entry in entries" :key="entry.name">
<router-link :to="entry.to" >
<v-button>{{ entry.name }}</v-button>
</router-link>
</span>
</div>`
}
CodePudding user response:
I think the slots
are exactly what you need in this case.
const { createApp, ref } = Vue;
const vButton = {
props: ['name'],
template: `<button type="button" :name="name"><slot></slot></button>`
}
const ContextMenuItem = {
components: { vButton },
props: ['entry'],
template: `<router-link :to="entry.to"><v-button>{{ entry.name }}</v-button></router-link>`
}
const ContextMenu = {
components: { ContextMenuItem },
template: `<div><slot></slot></div>`
}
const App = {
components: {
vButton, ContextMenuItem, ContextMenu
},
methods: {
copyMethod() { console.log('copyMethod()')},
editMethod() { console.log('editMethod()')},
deleteMethod() { console.log('deleteMethod()')},
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<!-- when using in a list of articles -->
<context-menu>
<context-menu-item :entry="{ name: 'copy'}" @click="copyMethod"></context-menu-item>
<context-menu-item :entry="{ name: 'delete'}" @click="deleteMethod"></context-menu-item>
</context-menu>
<br />
<!-- in a list of users -->
<context-menu>
<context-menu-item :entry="{ name: 'edit-user'}" @click="editMethod"></context-menu-item>
<context-menu-item :entry="{ name: 'delete-user'}" @click="deleteMethod"></context-menu-item>
</context-menu>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>