Vue.js v-if not reacting to variable change
The scope of this
is incorrect. The function ()
syntax creates its own scope. You can save the correct scope in one var and use that, like following:
created: function() {
var that = this
setTimeout(function() {
console.log("times over");
that.isloaded = 'true';
that.accounts = [{
id: 1234,
name: "germany"
}];
}, 2000);
},
Alternatively, you can use arrow function, which does not bind it's own this, arguments, super, or new.target.
created: function() {
setTimeout(() => {
console.log("times over");
this.isloaded = 'true';
this.accounts = [{
id: 1234,
name: "germany"
}];
}, 2000);
},
From the Vue.js - Reactivity in Depth docs:
For example, when you set vm.someData = 'new value', the component will not re-render immediately. It will update in the next “tick”, when the queue is flushed.
With the data being mutated in the created lifecycle hook, we need to use $nextTick
More info on that can be found in the above page.
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'
});
<script src="https://unpkg.com/[email protected]/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>
However, if you place the code that is loading the data inside a method, and call that method from the created
hook. It works without $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();
}