简体   繁体   中英

Why vue.js component is not showing fetched data on the first try?

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:

  • you no longer depend on an array stored outside of this item (Ie window ), preferring to leverage a property of your object itself
  • Vue now clearly knows when the array changes, as we are calling $set
  • the link between the two is now explicit

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM