2

In my project, I want to add some Ajax loaded menu items to my CoreUI sidebar in Vue. I already found a working solution, but it's kind of hacky and might have timing issues. Therefore I want to ask you, if there is a proper or at least better solution.

I also found this question from a few days ago, but it doesn't have an answer yet.

// main.js
new Vue({
    el: '#app',
    router,
    icons,
    template: '<App/>',
    components: {
        App
    },
    data: {
        clientConfiguration: null
    },
    created: async function () {
        let svcResult = await this.$http.get('Picking/ViewerSettings');
        this.clientConfiguration = svcResult.data;
        this.$children[0].$children[0].$children[0].$data.nav[0]._children[0].items =
            svcResult.data.map(vc => ({
                name: vc.name,
                to: 'test/' + vc.name,
                icon: 'cil-spreadsheet'
            }));
    }
})

// _nav.js
export default [
    {
        _name: 'CSidebarNav',
        _children: [
            {
                _name: 'CSidebarNavDropdown',
                name: 'Lists',
                to: '/test',
                icon: 'cil-list-numbered',
                items: []
            },
            // ...
        ]
    }
]

1 Answer 1

4

The _nav.js file is just an example of data structure that can be rendered by CRenderFunction component docs

The idea behind CRenderFunction is that you can render components from the Array/Object.

In your case, you have two options:

  • generate CRenderFunction object on backend,
  • generate CRenderFunction object on frontend by computed properties, based on data you got from the backend

Here is the example of the second approach:

in template

<CRenderFunction flat :content-to-render="navItems"/>

in script:

//example array that you receive from backend
const menuItems = [
  { 
    name: 'first item',
    to: '/first',
    icon: 'cil-user'
  },
  { 
    name: 'second item',
    to: '/second'
  },
  { 
    name: 'third item',
    to: '/third'
  }
]

export default {
  computed: {
    navItems () {
      return [
        {
          _name: 'CSidebarNav',
          _children: this.sidebarNavChildren
        }
      ]
    },
    sidebarNavChildren () {
      return menuItems.map(menuItem => {
        return {
          _name: 'CSidebarNavItem',
          name: menuItem.name,
          to: menuItem.to,
          icon: menuItem.icon || 'cil-spreadsheet'
        }
      })
    }
  }
}

navItems computed property result:

[{"_name":"CSidebarNav","_children": [
  {"_name":"CSidebarNavItem","name":"first item","to":"/first","icon":"cil-user"}, 
  {"_name":"CSidebarNavItem","name":"second item","to":"/second","icon":"cil-spreadsheet"}, 
  {"_name":"CSidebarNavItem","name":"third item","to":"/third","icon":"cil-spreadsheet"}
 ]
}]
Sign up to request clarification or add additional context in comments.

1 Comment

Hi there .. i have same problem.. after your answer i think i understood better, everything seems logical. i have done as you described but nothing happens.. there is no error, but there is no rendered menu as well

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.