Vue JS Ajax数据在加载时未填充Vue-Tribute

时间:2018-07-31 15:59:56

标签: javascript vue.js

我正在使用Vue致敬组件https://github.com/syropian/vue-tribute

最初在将“ show”数据属性设置为true时加载页面时,我得到“ No Match!”。但是,如果我在页面加载时将“ show”数据属性设置为false,然后手动将其设置为true,我将获得预期的两个结果。我尝试将函数调用包装到getTributeOptions()的“已安装,创建和更新”中,但收到的结果相同。我正在使用setTimeout()来模仿用于加载远程数据的AJAX调用。

var app = new Vue({
  el: '#myApp',
  data: function() {
    return {
      show: true,
      tributeOptions: {
        values: []
      }
    };
  },
  mounted: function() {
    this.getTributeOptions();
  },
  methods: {
    getTributeOptions: function(resource) {
      var vm = this;
      setTimeout(function() {
         vm.tributeOptions.values = [
            { key: 'Phil Heartman', value: 'pheartman' },
            { key: 'Gordon Ramsey', value: 'gramsey' }
          ];
      }, 500)
    }
  }
})

<div id="myApp">
  <div v-if="show">
    <vue-tribute :options="tributeOptions">
      <input type="text" placeholder="@" />
    </vue-tribute>
  </div>
</div>

https://codepen.io/anon/pen/QBQaNB?editors=1111

3 个答案:

答案 0 :(得分:1)

我找到了以下问题的答案:Vuejs mount the child components only after data has been loaded

更新代码:

var app = new Vue({
  el: '#myApp',
  data: function() {
    return {
      userDataLoaded: false,
      tributeOptions: {
        values: []
      }
    };
  },
  mounted: function() {
    this.getTributeOptions();
  },
  methods: {
    getTributeOptions: function(resource) {
      var vm = this;
      setTimeout(function() {
         vm.tributeOptions.values = [
            { key: 'Phil Heartman', value: 'pheartman' },
            { key: 'Gordon Ramsey', value: 'gramsey' }
          ];
        vm.dataLoaded = true;
      }, 500)
    }
  }
})

<div id="myApp">
  <template>
    <template v-if="dataLoaded">
      <vue-tribute :options="tributeOptions">
        <input type="text" placeholder="@" />
      </vue-tribute>
    </template>
  </template>
</div>

答案 1 :(得分:1)

虽然上面的解决方法可能会起作用,但问题出在您使用的库中 在https://github.com/syropian/vue-tribute/blob/master/src/index.js#L19

mounted() {
  const $el = this.$slots.default[0].elm;

  this.tribute = new Tribute(this.options);
...
}

options值仅在mounted()中使用一次,并且在更改选项时没有用于更新值的处理程序。

更好的方法是在watch中进行this.options的更改,并分别更新组件内部的值。

答案 2 :(得分:1)

选中Vue Tribute source code at Github,您将看到它只会在mount()中创建一个new Tribute实例。这意味着即使您在挂载后更改props = options的值,也不会受到任何影响。

因此,一种解决方案是确保在挂载之前tributeOptions已准备就绪,因此更新created()中的值将是一个主意。

var app = new Vue({
  el: '#myApp',
  data: function() {
    return {
      tributeOptions: {
        values: []
      }
    };
  },
  created: function () {
   this.tributeOptions.values = [
      { key: 'Phil Heartman', value: 'pheartman' },
      { key: 'Gordon Ramsey', value: 'gramsey' }
    ]
  },
  mounted: function() {
    //this.getTributeOptions();
  },
  methods: {
    getTributeOptions: function(resource) {
      var vm = this;
      setTimeout(function() {
         vm.tributeOptions.values = [
            { key: 'Phil Heartman', value: 'pheartman' },
            { key: 'Gordon Ramsey', value: 'gramsey' }
          ];
      }, 500)
    }
  }
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script src="https://unpkg.com/vue-tribute"></script>
<div id="myApp">
    <vue-tribute :options="tributeOptions">
      <input type="text" placeholder="@" />
    </vue-tribute>
</div>

另一种解决方案是在Github中下载 Vue Tribute 的源代码,然后自己实现update Tribute instance

更新:创建实现update Tribute options的{​​{3}}。

第三个解决方案是每次更新tributeOptions时通过绑定不同的密钥来强制重新安装

就像下面的演示一样。

var app = new Vue({
  el: '#myApp',
  data: function() {
    return {
      tributeOptions: {
        values: []
      },
      tributeKey: 0
    };
  },
  mounted: function() {
    this.getTributeOptions();
  },
  methods: {
    getTributeOptions: function(resource) {
      var vm = this;
      setTimeout(function() {
         vm.tributeOptions.values = [
            { key: 'Phil Heartman', value: 'pheartman' },
            { key: 'Gordon Ramsey', value: 'gramsey' }
          ];
          vm.tributeKey+=1
      }, 500)
    }
  }
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script src="https://unpkg.com/vue-tribute"></script>
<div id="myApp">
    <vue-tribute :options="tributeOptions" :key="tributeKey">
      <input type="text" placeholder="@" />
    </vue-tribute>
</div>