Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Vue3 component with list definition in inner html

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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>`   
}

>Solution :

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>&nbsp;
        <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>&nbsp;
        <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>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading