0

我是 VueJs 的新手,目前只尝试加载一些数据并使其对所有 vue 组件全局可用。实现这一目标的最佳方法是什么?我有点卡住了,因为全局变量有时似乎变为,我不知道为什么。

在我的 main.js 中,我创建了三个全局 Vue 实例变量:

let globalData = new Vue({
  data: {
    $serviceDiscoveryUrl: 'http://localhost:40000/api/v1',
    $serviceCollection: null,
    $clientConfiguration: null
  }
});
Vue.mixin({
  computed: {
    $serviceDiscoveryUrl: {
      get: function () { return globalData.$data.$serviceDiscoveryUrl },
      set: function (newUrl) { globalData.$data.$serviceDiscoveryUrl = newUrl; }
    },
    $serviceCollection: {
      get: function () { return globalData.$data.$serviceCollection },
      set: function (newCollection) { globalData.$data.$serviceCollection = newCollection; }
    },
    $clientConfiguration: {
      get: function () { return globalData.$data.$clientConfiguration },
      set: function (newConfiguration) { globalData.$data.$clientConfiguration = newConfiguration; }
    }
  }
})

在我的 App.vue 组件中,我加载了所有数据:

<script>
  export default {
    name: 'app',
    data: function () {
      return {
        isLoading: true,
        isError: false
      };
    },
    methods: {
      loadAllData: function () {
        this.$axios.get(this.$serviceDiscoveryUrl)
          .then(
            response => {
              this.$serviceCollection = response.data;

              let configurationService = this.$serviceCollection.services.find(obj => obj.key == "ProcessConfigurationService");

              this.$axios.get(configurationService.address + "/api/v1/clientConfiguration").then(
                response2 => {
                  this.$clientConfiguration = response2.data;
                }
              );
              this.isLoading = false;
            })
      }
    },
    created: function m() {
      this.loadAllData();
    }
  }
</script>

但是当我尝试访问时,$clientConfiguration它似乎null不时出现,我不知道为什么。例如,当我尝试构建导航侧边栏时:

    beforeMount: function () {
      let $ = JQuery;
      let clients = [];
      if (this.$clientConfiguration === null)
        console.error("client config is <null>");

      $.each(this.$clientConfiguration, function (key, clientValue) {
        let processes = [];
        $.each(clientValue.processConfigurations, function (k, processValue) {
          processes.push(
            {
              name: processValue.name,
              url: '/process/' + processValue.id,
              icon: 'fal fa-project-diagram'
            });
        });

        clients.push(
          {
            name: clientValue.name,
            url: '/client/' + clientValue.id,
            icon: 'fal fa-building',
            children: processes
          });
      });

      this.nav.find(obj => obj.name == 'Processes').children = clients;
4

1 回答 1

1

最可能的原因是null只是初始值。加载数据是异步的,因此您需要等待加载完成,然后再尝试创建依赖该数据的任何组件。

您有一个isLoading标志,我猜这是您在显示任何组件之前尝试等待加载完成(可能通过合适的v-if)。但是,它目前只等待第一个请求,而不是第二个。所以这:

this.$axios.get(configurationService.address + "/api/v1/clientConfiguration").then(
  response2 => {
    this.$clientConfiguration = response2.data;
  }
);
this.isLoading = false;

需要是:

this.$axios.get(configurationService.address + "/api/v1/clientConfiguration").then(
  response2 => {
    this.$clientConfiguration = response2.data;
    this.isLoading = false;
  }
);

如果问题不是那个初始值,那么您需要弄清楚将其设置为null. 这应该很容易,只需debugger在您的 setter 中添加一条语句:

$clientConfiguration: {
  get: function () { return globalData.$data.$clientConfiguration },
  set: function (newConfiguration) {
    if (!newConfiguration) {
      debugger;
    }
    globalData.$data.$clientConfiguration = newConfiguration;
  }
}

除了 的问题之外null,如果您使用的是 Vue 2.6+,我建议您看一下Vue.observable,这是一种比创建新的 Vue 实例更简单的创建反应性对象的方法。

就我个人而言,我可能会通过放置一个反应对象Vue.prototype而不是使用全局 mixin 来实现所有这些。这假设你甚至需要对象是反应性的,如果你不这样做,那么这一切都比它需要的复杂一些。

于 2019-07-08T11:08:42.293 回答