为什么vue.js组件在第一次尝试时不显示获取的数据?

时间:2019-02-14 22:57:47

标签: javascript json vue.js

我成功地从一个外部js文件中获取了数据(长时间的Json过程,导出了promise函数),但是第一次尝试时并没有将其添加到组件中。我必须输入其他组件,然后在返回数据时显示。

我尝试使用beforeCreate()方法,但是它没有帮助,condole.log(data)显示信息,但是组件却没有。

<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>

我需要在第一次尝试时显示数据。

我实际上是个新人。

2 个答案:

答案 0 :(得分:1)

之所以不起作用,是因为Vue无法跟踪window.menu的更改时间,因此无法照此重新渲染。

为此您整个window的使用是可疑的。请考虑以下内容:

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>

通过这种小的重写,我们实现了很多事情:

  • 您不再依赖存储在此项之外的数组(即window),而更倾向于利用对象本身的属性
  • Vue现在清楚地知道数组何时更改,因为我们正在调用$set
  • 两者之间的联系现在很明确

Vue documentation上提供了有关$set / Vue.set的更多信息,这是存储和更新响应数据的主要方法。


关于for循环和过滤,如果您永远不会刷新该组件的数据,则最好将push保留到数组中,就像这样:

menuData().then((data) => {
  for (const element of data) {
    this.$data.allBuildings.push(element);
  }
});

Vue.js直接在数据对象本身上支持most array mutation methods;如果您发现自己需要过滤数组,使用数组或单独构建数组,则$set设置它也可以。

答案 1 :(得分:0)

尝试一下。您应该使用空数组初始化allBuildings, 不存在会导致错误的对象。

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;
    });
  }
}