<template>
<!--
When isLoading is true, the <div> is in the DOM, the <p> is not.
When isLoading is false, Vue will remove the <div> and add the <p> to the DOM,
at which point <MyComponent> will be created and passed the fetched data.
-->
<div v-if="isLoading">
Loading...
{{ myData.if.you.try.to.access.properties.here.it.will.error }}
</div>
<p v-else>
{{ myData.you.can.access.properties.now.that.myData.is.loaded }}
<MyComponent :data="myData.you.can.pass.data.to.components.now"/>
</p>
</template>
<script>
export default {
data: () => ({
isLoading: false,
myData: null,
}),
async created () {
try {
this.isLoading = true
await this.fetchData()
// Make sure to handle errors :)
} finally {
this.isLoading = false
}
},
methods: {
async fetchData () {
const res = await axios.get('/api/myData')
this.myData = res.data.myData
}
}
}
</script>
Save yourself hours of pain, and learn how "this" works.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
<script>
export default {
data () {
return {
goodData: this.goodMethod() // this == vue
}
},
data: function () {
return {
goodData: this.goodMethod() // this == vue
}
}
data: vm => ({
badData: this.badMethod(), // this == window
goodData: vm.goodMethod() // vm == vue
}),
computed: {
badComputed: () => this.badData, // this == window
goodComputed: vm => vm.goodData, // vm == vue
goodComputed2 () {
console.log(this) // vue
}
goodComputed3: function () {
console.log(this) // vue
},
goodComputed4: {
get: vm => vm.goodData, // vm == vue
set(val) {
this.goodData = val // this == vue
}
}
},
methods: {
badMethod: () => {
console.log(this) // window
},
goodMethod () {
console.log(this) // vue
},
goodMethod2: function () {
console.log(this) // vue
},
// Function doesn't reference "this", so an arrow function is fine here.
doesntMatter: () => 1 + 1
},
mounted: () => {
console.log(this) // window
},
watch: {
badData: () => {
console.log(this) // window
}
},
created () {
// BAD
// The "function" keyword affects the value of "this".
axios.get().then(function (response) {
console.log(this) // window
})
// GOOD
// An arrow function causes the function to inherit the "this" value from the
// parent scope, in this case, the scope of the created() function.
axios.get().then(response => {
console.log(this) // vue
})
// GOOD
// Prefer arrow functions, but saving the value of "this" in a higher scope will also work.
const self = this
axios.get().then(function (response) {
console.log(this) // window
console.log(self) // vue
})
// BAD
// Obviously this doesn't just apply to axios callbacks, it applies to any callback.
setTimeout(function () {
console.log(this) // window
}, 0)
// GOOD
setTimeout(() => {
console.log(this) // vue
}, 0)
// You can avoid some of these "gotchas" with async/await, refer to the
// fetchData() method in the earlier "Async calls" section.
},
}
</script>