如何在vue.js存储correclty中保存axios请求?

时间:2018-03-10 23:05:08

标签: javascript vue.js axios

我想创建从API中提取的动态侧边栏链接。 这是我与之合作的主题: https://admin.vuebulma.com/#/

请注意侧边栏中包含子项列表的图表链接。

我想发表一个API请求 - 比如图表,并为API请求中的每个元素返回创建每个子节点(请参阅charts.js)。

在下面的示例中,数据对象是硬编码的 - 我想删除它并使用for循环为api request.body

中的每个元素动态创建每个子节点。

/store/modules/menu/index.js

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
}

/store/modules/menu/charts.js

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'
      }
    }
  ]
}

sidebar.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"
    },
]

1 个答案:

答案 0 :(得分:0)

  1. import { browser } from 'protractor'; const waitLimit = 15000; browser.wait(() => { return myHtmlElement.isDisplayed(); }, waitLimit);

    中创建图表路线的副本
    store
  2. 在组件

    中创建const state = { chartsRoutes: [] } 属性
    computed
  3. 使用computed: { chartsRoutes () { return this.$store.state.chartsRoutes } } v-for呈现为组件中的chartsRoutes

  4. 创建变种以修改商店和路由器

    router-link
  5. 制作动作

    // 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)
      }
    }
    
  6. 派遣行动

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