我想创建从API中提取的动态侧边栏链接。 这是我与之合作的主题: https://admin.vuebulma.com/#/
请注意侧边栏中包含子项列表的图表链接。
我想发表一个API请求 - 比如图表,并为API请求中的每个元素返回创建每个子节点(请参阅charts.js)。
在下面的示例中,数据对象是硬编码的 - 我想删除它并使用for循环为api request.body
中的每个元素动态创建每个子节点。import * as types from '../../mutation-types'
import lazyLoading from './lazyLoading'
import charts from './charts'
import components from './components'
import dashboard from './dashboard'
// show: meta.label -> name
// name: component name
// meta.label: display label
const state = {
items: [
dashboard,
charts,
components
]
}
const mutations = {
[types.EXPAND_MENU] (state, menuItem) {
if (menuItem.index > -1) {
if (state.items[menuItem.index] && state.items[menuItem.index].meta) {
state.items[menuItem.index].meta.expanded = menuItem.expanded
}
} else if (menuItem.item && 'expanded' in menuItem.item.meta) {
menuItem.item.meta.expanded = menuItem.expanded
}
}
}
export default {
state,
mutations
}
import lazyLoading from './lazyLoading'
export default {
name: 'Charts',
path: '/charts',
meta: {
icon: 'fa-bar-chart-o',
expanded: false,
link: 'charts/index.vue'
},
component: lazyLoading('charts', true),
children: [
{
name: 'Chartist',
path: 'chartist',
component: lazyLoading('charts/Chartist'),
meta: {
link: 'charts/Chartist.vue'
}
},
{
name: 'Chartjs',
path: 'chartjs',
component: lazyLoading('charts/Chartjs'),
meta: {
link: 'charts/Chartjs.vue'
}
},
{
name: 'Peity',
path: 'peity',
component: lazyLoading('charts/Peity'),
meta: {
link: 'charts/Peity.vue'
}
},
{
name: 'Plotly',
path: 'plotly',
component: lazyLoading('charts/Plotly'),
meta: {
link: 'charts/Plotly.vue'
}
}
]
}
<template>
<aside class="menu app-sidebar animated" :class="{ slideInLeft: show, slideOutLeft: !show }">
<p class="menu-label">
General
</p>
<ul class="menu-list">
<li v-for="(item, index) in menu">
<router-link :to="item.path" :exact="true" :aria-expanded="isExpanded(item) ? 'true' : 'false'" v-if="item.path" @click.native="toggle(index, item)">
<span class="icon is-small"><i :class="['fa', item.meta.icon]"></i></span>
{{ item.meta.label || item.name }}
<span class="icon is-small is-angle" v-if="item.children && item.children.length">
<i class="fa fa-angle-down"></i>
</span>
</router-link>
<a :aria-expanded="isExpanded(item)" v-else @click="toggle(index, item)">
<span class="icon is-small"><i :class="['fa', item.meta.icon]"></i></span>
{{ item.meta.label || item.name }}
<span class="icon is-small is-angle" v-if="item.children && item.children.length">
<i class="fa fa-angle-down"></i>
</span>
</a>
<expanding v-if="item.children && item.children.length">
<ul v-show="isExpanded(item)">
<li v-for="subItem in item.children" v-if="subItem.path">
<router-link :to="generatePath(item, subItem)">
{{ subItem.meta && subItem.meta.label || subItem.name }}
</router-link>
</li>
</ul>
</expanding>
</li>
</ul>
</aside>
</template>
<script>
import Expanding from 'vue-bulma-expanding'
import { mapGetters, mapActions } from 'vuex'
export default {
components: {
Expanding
},
props: {
show: Boolean
},
data () {
return {
isReady: false
}
},
mounted () {
let route = this.$route
if (route.name) {
this.isReady = true
this.shouldExpandMatchItem(route)
}
},
computed: mapGetters({
menu: 'menuitems'
}),
methods: {
...mapActions([
'expandMenu'
]),
isExpanded (item) {
return item.meta.expanded
},
toggle (index, item) {
this.expandMenu({
index: index,
expanded: !item.meta.expanded
})
},
shouldExpandMatchItem (route) {
let matched = route.matched
let lastMatched = matched[matched.length - 1]
let parent = lastMatched.parent || lastMatched
const isParent = parent === lastMatched
if (isParent) {
const p = this.findParentFromMenu(route)
if (p) {
parent = p
}
}
if ('expanded' in parent.meta && !isParent) {
this.expandMenu({
item: parent,
expanded: true
})
}
},
generatePath (item, subItem) {
return `${item.component ? item.path + '/' : ''}${subItem.path}`
},
findParentFromMenu (route) {
const menu = this.menu
for (let i = 0, l = menu.length; i < l; i++) {
const item = menu[i]
const k = item.children && item.children.length
if (k) {
for (let j = 0; j < k; j++) {
if (item.children[j].name === route.name) {
return item
}
}
}
}
}
},
watch: {
$route (route) {
this.isReady = true
this.shouldExpandMatchItem(route)
}
}
}
</script>
不知道为什么我无法弄清楚如何做到这一点。
更新
以下是我调用的API的示例:
[
{
"id": 1,
"name": "test1",
"os": "windows",
"url": "https://test.com"
},
{
"id": 2,
"name": "test2",
"os": "ios",
"url": "https://test.com"
},
{
"id": 1,
"name": "test3",
"os": "windows",
"url": "https://test.com"
},
]
答案 0 :(得分:0)
在import { browser } from 'protractor';
const waitLimit = 15000;
browser.wait(() => {
return myHtmlElement.isDisplayed();
}, waitLimit);
store
在组件
中创建const state = {
chartsRoutes: []
}
属性
computed
使用computed: {
chartsRoutes () {
return this.$store.state.chartsRoutes
}
}
将v-for
呈现为组件中的chartsRoutes
创建变种以修改商店和路由器
router-link
制作动作
// import router
const mutations = {
'update-charts-routes': function (state, payload) {
const { chartsRoutes } = payload
state.chartsRoutes = chartsRoutes.map(r => {
return {
path: '/your/custom/path/according/to/response'
// other params
}
})
router.addRoutes(state.chartsRoutes)
}
}
派遣行动
const actions = {
'reload-charts': function ({commit, dispatch}, data) {
return new Promise((resolve, reject) => {
const r = {
method: 'get',
url: data.url,
// add more options, e.g. header or auth
}
axios.request(r)
.then(resp => {
commit('update-charts-routes', { chartsRoutes: resp.data })
resolve()
})
.catch(err => {
// handle error
reject(err)
})
}
}
}
}