ajax请求后刷新vue-router视图

时间:2017-03-31 06:58:25

标签: javascript ajax vuejs2 vue-router

我有一个带有两个组件的vue路由器,一个列表和一个详细视图,并带有一个返回列表视图的链接。在同一页面上,我有一个列表视图组件中显示的相同数据。

数据是通过ajax获取的,因此在绘制路由器视图时没有准备好。但是,当数据准备就绪时,非路由器列表会更新,但路由器视图不会更新。

如何与路由器视图进行通信,以便重新绘制新数据?

如果我点击非路由器列表中的某个项目,路由器视图将按预期更改为详细信息组件,如果我然后单击“显示列表”,它将更改回列表组件,但这次它填充了正确的数据。

我创建了一个包含相关代码的js-fiddle:https://jsfiddle.net/pengman/jkwvphf9/2/ (它使用setTimeout伪造ajax,但效果相同)

Html代码:

<div id="app">
Router-view:
  <router-view class="view"></router-view>
  <br>
  Unrouted list: 
  <div class="list-group">
    <router-link v-for="plante in planter" class="list-group-item" :to="{ name: 'plante', params: { nummer: plante.Nummer }}">{{ plante.Navn }} | </router-link>
  </div>
</div>

<template id="plante-listing-template">

        <ul>
            <li v-for="plante in planter">
                {{ plante.Navn }} <router-link :to="{ name: 'plante', params: { nummer: plante.Nummer }}">Vis</router-link>
            </li>
        </ul>
    </template>

    <template id="plante-detail-template">
        <div>
            plante detail template:
            <h3>{{ plante.Navn }}</h3>
            <router-link to="/">Show List</router-link>
        </div>
        <br>
    </template>

Javascript代码:

var PlanteListing = {
  template: '#plante-listing-template',

  data: function () {
    return {
      planter: this.$parent.planter
    }
  },
  watch: {
    '$route'(to, from) {
      // vi skal opdatere data, saa vi skal beregne igen 
      this.planter = this.$parent.planter;
    },
    'dataloaded'() {
      this.planter = this.$parent.planter;
    }
  }
};  

var PlanteDetail = {
  template: '#plante-detail-template',
  data: function () {
    var parent = this.$parent;
    var nummerFromRoute = this.$route.params.nummer;
    //console.log(nummerFromRoute);
    var filtered = this.$parent.planter.filter(function (item) {
      return (item.Nummer == nummerFromRoute) ? item : false;
    });

    return {
      plante: filtered[0]
    }
  },
  watch: {
    '$route'(to, from) {
      // vi skal opdatere data, saa vi skal beregne igen 
      var nummerFromRoute = this.$route.params.nummer;

      var filtered = this.$parent.planter.filter(function (item) {
        return (item.Nummer == nummerFromRoute) ? item : false;
      });
      this.plante = filtered[0];
    },
  }
};

var router = new VueRouter({
  mode: 'hash',
  base: window.location.href,
  routes: [
    { path: '/', component: PlanteListing },
    { name: 'plante', path: '/:nummer', component: PlanteDetail }
  ]
});

var app = new Vue({
  router,
  data: {
    planter: []
  },
  components: { PlanteListing: PlanteListing },
  methods: {
    getJson: function () {
      var self = this;
            /* Real code:
      $.getJSON("content/planter.json", function (param) {
        this.planter = param;
      }.bind(this));
      */
      /* Simulation code: */ 
      setTimeout(function(){self.planter = [  {    "Nummer": "0",    "Navn": "Bertha Winters"  },  {    "Nummer": "1",    "Navn": "Jeannie Small"  },  {    "Nummer": "2",    "Navn": "Mckay Joyner"  },  {    "Nummer": "3",    "Navn": "Janelle Banks"  },  {    "Nummer": "4",    "Navn": "Bray Moran"  },  {    "Nummer": "5",    "Navn": "Hooper Schwartz"  }]; console.log('data loaded')}, 500);
    }
  },
  created: function () {
    this.getJson();
  }
}).$mount('#app');

1 个答案:

答案 0 :(得分:2)

通常,您不希望组件伸出自身来获取数据(就像您使用this.$parent.planter一样)。相反,你想传递道具。为此,我对您的代码进行了一些修改。

首先,我将您的vue-router升级到最新版本。这允许您在路由上使用props参数。

var router = new VueRouter({
  mode: 'hash',
  base: window.location.href,
  routes: [
    { path: '/', component: PlanteListing },
    { name: 'plante', path: '/:nummer', component: PlanteDetail, props: true }
  ]
});

其次,您在所有路线中都使用planter,因此我在router-view上将其作为属性提供。

<router-view class="view" :planter="planter"></router-view>

这允许我们清理您的组件路径并将他们需要的数据添加为道具。

var PlanteListing = {
  template: '#plante-listing-template',
  props:["planter"]
};  

var PlanteDetail = {
  template: '#plante-detail-template',
  props:["planter", "nummer"],
  data: function () {
    var filtered = this.planter.filter(item => item.Nummer == this.nummer);
    return {
      plante: filtered[0]
    }
  }
};

没有必要告诉路由器重绘;因为数据是道具,Vue只是照顾我们。

这是您更新的fiddle