I successfully get data from an external js file (long Json process, exports promise function), but the data it's not been added to the component on the first try. I have to enter in a different component and then when returning the data is shown.
I have tried using the beforeCreate() method, but it hasn't help, the condole.log(data) shows the information, but the component is not.
<template>
<div class="roomsBar">
<div class="roomsArea">
<li v-for="building in allBuildings" :key="building">
<a v-on:click="clicked(building)">{{building}}</a>
</li>
</div>
</div>
</template>
<script>
import {menuData as menuData} from '../controllers/navigation.js';
export default {
name: 'Buildings',
data() {
return {
allBuildings: window.menu
}
},
methods: {
clicked: function(item){
this.$router.push({ path: '/navigation/'+item })
}
},
beforeCreate() {
window.menu = [];
menuData().then((data) => { // Recover the data from 'Navigation.js'
console.log(data);
for (const element of data) { // Filter data and only add building to the menu
window.menu.push(element.building);
}
console.log(window.menu);
});
}
}
</script>
<style scoped>
.roomsBar {
width: 100%;
height: 100%;
background-color: #fff;
}
li {
list-style-type: none;
}
a {
cursor: pointer;
color: #42b983;
}
</style>
I need that the data to be showed on the first try.
I'm actually new in vue by the way.
The reason this isn't working is because Vue cannot track when window.menu
changed, and is therefore unable to re-render as such.
Your entire use of window
for this is dubious at best. Consider the following:
let menuData = function() { return new Promise(function(resolve, reject) { setTimeout(function() { return resolve([{ name: 'test' }, { name: 'test 2' } ]); }, 100); }); } let component = Vue.component('test', { name: 'Buildings', template: '<ul><li v-for="item in allBuildings">{{item.name}}</li></ul>', data: () => ({ allBuildings: [] }), beforeCreate() { menuData().then((data) => { this.$set(this.$data, 'allBuildings', data); }); } }); let app = new Vue({ el: "#app" });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <test></test> </div>
With this small rewrite, we achieved multiple things:
window
), preferring to leverage a property of your object itself$set
More information about $set
/ Vue.set
is available on the Vue documentation and is the main way to store and update reactive data.
Regarding the for
loop and filtering, if you are never going to refresh this component's data, it is perfectly fine to keep push
ing to the array, like so:
menuData().then((data) => {
for (const element of data) {
this.$data.allBuildings.push(element);
}
});
Vue.js directly supports most array mutation methods straight on the data object itself; if you find yourself in the case where you need to filter an array, making use of those or building the array separately then $set
ting it would also work.
Try this. You should initialize allBuildings with empty array, not with non-existing object which causes the error.
export default {
name: 'Buildings',
data() {
return {
allBuildings: []
}
},
methods: {
clicked: function(item){
this.$router.push({ path: '/navigation/'+item })
}
},
beforeCreate() {
window.menu = [];
menuData().then((data) => {
for (const element of data) {
window.menu.push(element.building);
}
this.allBuildings = window.menu;
});
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.