Vue.js v-如果不对变量做出反应

时间:2017-01-31 14:39:32

标签: javascript vue.js

我正在玩vue.js并且在使用v-if时遇到了一些困难。

我正在尝试在模板中进行条件模板渲染。在创建的方法中,变量isloaded设置为true,这将导致模板被重新呈现并让“正在加载数据”消息消失。

但是,日志显示,2s的延迟有效,所以回调已达到,但看起来我没有正确更新数据变量。

我已经尝试了几件事,现在我将“真/假”改为字符串,以便更接近官方主页上给出的示例,但仍然没有成功。我希望你能帮助我,并提前感谢你们。

请在下面找到有趣的codenippets:

var step1 = Vue.component('step1', {
  template: '#step1',
  data: function() {
    return {
      accounts: [],
      isloaded: 'false'
    }
  },
  created: function() {
    console.log("created");
    setTimeout(function() {
      console.log("times over");
      this.isloaded = 'true';
      this.accounts = [{
        id: 1234,
        name: "germany"
      }];
    }, 2000);
  },
  methods: {
    loaded: function() {
      console.log(this.isloaded === 'true');
      return this.isloaded === 'true';
    }
  }

})

new Vue({
  el: '#main'
});
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
<template id="step1">
  <div class="step1">
    <h1>Welcome please choose your account:</h1>
    <template v-if="isloaded === 'false'">
      <p>Loading Data</p>
    </template>
    <template v-else>
      <select>
        <template v-for="account in accounts">
          <option :value="account.id">{{ account.name }}</option>
        </template>
      </select>
    </template>

  </div>
</template>

<div id="main">
  <step1></step1>
</div>

4 个答案:

答案 0 :(得分:4)

来自Vue.js - Reactivity in Depth docs

  

例如,当您设置vm.someData =&#39;新值&#39;时,该组件   不会立即重新渲染。它将在下一个“tick”中更新,   刷新队列时。

如果数据在创建的生命周期钩子中发生变异,我们需要使用$nextTick更多信息可以在上面的页面中找到。

&#13;
&#13;
var step1 = Vue.component('step1', {
  template: '#step1',
  data: function() {
    return {
      accounts: [],
      isloaded: false
    }
  },
  created: function() {
    console.log("created");
    var self = this;
    setTimeout(function() {
      console.log("times over");
      self.$nextTick(function() {
        self.isloaded = true;
        self.accounts = [{
          id: 1234,
          name: "germany"
        }];
      })

    }, 2000);
  }

})

new Vue({
  el: '#main'
});
&#13;
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
<template id="step1">
  <div class="step1">
    <h1>Welcome please choose your account:</h1>
    <template v-if="isloaded===false">
      <p>Loading Data</p>
    </template>
    <template v-else>
      <select>
        <template v-for="account in accounts">
          <option :value="account.id">{{ account.name }}</option>
        </template>
      </select>
    </template>

  </div>
</template>

<div id="main">
  <step1></step1>
</div>
&#13;
&#13;
&#13;

但是,如果将正在加载数据的代码放在方法中,并从created挂钩调用该方法。它没有$nextTick

methods: {
    loadData: function() {
        var self = this;
        setTimeout(function() {
            console.log("times over");
            self.isloaded = true;
            self.accounts = [{
                id: 1234,
                name: "germany"
            }];
        }, 2000);
    }
},
created: function() {
    console.log("created");
    this.loadData();
}

答案 1 :(得分:3)

this的范围不正确。 function ()语法创建自己的范围。您可以在一个var中保存正确的范围并使用它,如下所示:

created: function() {
  var that = this
  setTimeout(function() {
    console.log("times over");
    that.isloaded = 'true';
    that.accounts = [{
      id: 1234,
      name: "germany"
    }];
  }, 2000);
},

或者,您可以使用arrow function,它不会绑定自己的thisargumentssupernew.target

created: function() {
  setTimeout(() => {
    console.log("times over");
    this.isloaded = 'true';
    this.accounts = [{
      id: 1234,
      name: "germany"
    }];
  }, 2000);
},

答案 2 :(得分:0)

有时这可能是由模板中的错误引起的。例如,我在 v-else 的情况下使用了一个未定义的方法,这就是为什么 v-if 看起来不是响应式的。如果您删除 v-else 中未定义的方法或定义该方法,问题将得到解决。

注意:即使在实例上定义了该方法,也请务必检查您是否将有效值作为参数发送。

new Vue({
  el: '#app',
  data(){
    return {
      isLoading: true
    }
  },
  mounted() {
    setTimeout(() => {
      this.isLoading = false
    }, 2000)
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <template v-if="isLoading">
    Loading...
  </template>
  <template v-else>
    loading finished
    
    {{ an_undefined_method() }}
  </template>
</div>

答案 3 :(得分:-2)

更新您的方法只有一个=,并删除返回。

methods: {
  loaded: function() {
    console.log(this.isloaded === 'true');
    this.isloaded = 'true';
  }
}