2

我正在尝试在 Vue.js(与 vuex 一起用于状态管理)项目中使用vega-embed 。基本上,后端提供一个 Vega json 对象,前端通过带有点击事件的 HTTP GET 请求获取该对象。但是,我必须单击两次才能显示绘图,并且第一次单击事件总是会触发错误“ Uncaught (in promise) TypeError: Cannot read property '$schema' of null”。有人可以帮我调试吗?非常感谢。详情如下图:

vue组件文件:

<template>
  <button @click.native="fetchCars(); displayVegaPlot()">fetch cars</button>
  <div id="vega-example"></div>
</template>

<script>
  import {default as vegaEmbed} from 'vega-embed'
  import {
  mapState
} from 'vuex'

  export default {
    name: 'VegaExample',
    props: {
      component_msg: String
    },
    methods: {
      fetchCars () {
        this.$store.dispatch('fetchCars')
      },
      displayVegaPlot () {
        vegaEmbed('#vega-example', this.vega_cars, {actions: false})
      }
    },
    computed: {
    ...mapState([
      'vega_cars'
    ])
    }
  }
</script>

...和商店js文件:

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)

export default new Vuex.Store({
  strict: true,
  state: {
    error: '',
    vega_cars: null
  },

  mutations: {
    SET_CARS: (state, cars) => {
      state.vega_cars = cars
    },
    SET_ERROR: (state, error) => {
      state.error = error
    }
   }

  actions: {
    fetchCars: (context) => {
      axios.get(`vega_cars`)
        .then(response => context.commit('SET_CARS', response.data))
        .catch(error => context.commit('SET_ERROR', error))
    }
  }
4

1 回答 1

0

非常感谢@TommyF 的评论,在阅读了一些文档之后,我想我找到了解决方案(显然作为网络应用程序开发的新手,Vue我不知道Vue提供了一个特殊的watch工具)。因此,在组件 Vue 文件中,可以设置 a 来显示 Vega 图,而不是声明一个displayVegaPlot命令式调用的方法watch,只要vega_cars更改值:

    watch: {
    vega_cars: (spec) => {
      console.log('$store.state.vega_cars changed value')
      if (spec) {
        vegaEmbed('#vega-example', spec, {actions: false})
      }
    }
  }

当然...mapState(['vega_cars'])需要放入computed

于 2018-11-16T23:22:19.860 回答