VueJs 中全局加载的数据偶尔为空
Global loaded data in VueJs is occasionally null
我是 VueJs 的新手,目前正在尝试仅加载一次数据并使其对所有 vue 组件全局可用。实现这一目标的最佳方法是什么?
我有点卡住了,因为全局变量有时似乎变成了 null,我不知道为什么。
在我的 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;
最可能的原因是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
。这应该很简单,只需在 setter:
中添加 debugger
语句
$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
上放置一个反应对象而不是使用全局混合来实现所有这些。这假设你甚至需要对象是反应性的,如果你不这样做,那么这一切都比它需要的要复杂一些。
我是 VueJs 的新手,目前正在尝试仅加载一次数据并使其对所有 vue 组件全局可用。实现这一目标的最佳方法是什么? 我有点卡住了,因为全局变量有时似乎变成了 null,我不知道为什么。
在我的 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;
最可能的原因是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
。这应该很简单,只需在 setter:
debugger
语句
$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
上放置一个反应对象而不是使用全局混合来实现所有这些。这假设你甚至需要对象是反应性的,如果你不这样做,那么这一切都比它需要的要复杂一些。