3👍
The ready()
hook does not exist in Vue.js 2.
You could place your Ajax code in many hooks. It is more common to use one of the following lifecycle hooks:
beforeCreate()
created()
beforeMount()
mounted()
.
What should guide your decision, then? There’s somethings you must consider.
First: Vue’s initialization code is executed synchronously.
This means, technically, any asynchronous code you run in any of those hooks will only respond after all of those hooks end. See demo:
new Vue({
el: '#app',
beforeCreate() {
setTimeout(() => { console.log('fastest asynchronous code ever (started at beforeCreate)') }, 0);
console.log('beforeCreate hook executed');
},
created() {
console.log('created hook executed');
},
beforeMount() {
console.log('beforeMount hook executed');
},
mounted() {
console.log('mounted hook executed');
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
Check the console.
</div>
In other words, if you make an Ajax call in beforeCreate
, no matter how fast the API responds, the response will only be processed way later, way after the created()
has been executed.
Which hook to use?
- Need just to trigger a call as soon as possible?
- Use
beforeCreate()
- Why?
- It runs sooner than any of those hooks, but…
- Use
- Need to read from or modify
data
right away?- Use
created()
- Why?
- Use
- Need anything that is generated after
created()
?- Use
beforeMount()
- Why?
- I don’t know anything that isn’t available at
created()
and is available atbeforeMount()
other than the compiledthis.$options.render
render function (see source as well), so this case must really be a rare situation.
- I don’t know anything that isn’t available at
- Use
- Need anything from the DOM (e.g. a
ref
)?- Use
mounted()
- Why? Because those are only available at the
mounted()
hook.
- Use
When using Vuex to manage state globally
As mentioned in comments, a common approach is to use Vuex to manage your application’s state globally. In that case, the requests should be started in Vuex actions. Your component, then, in any lifecycle hook (or method), would dispatch the actions. See demo below.
const store = new Vuex.Store({
strict: true,
state: {
people: []
},
mutations: {
populate: function (state, newPeople) {
state.people = newPeople
}
},
actions: {
fetchPeople ({ commit }) {
axios.get('https://reqres.in/api/users').then(function (response) {
commit('populate', response.data.data)
}, function () {
console.log('error')
})
}
}
});
Vue.component('mycomp', {
computed: Vuex.mapState(['people']),
template: `
<ul>
<li v-for="p in people">
{{ p.first_name }} {{ p.last_name }}
</li>
</ul>
`
});
new Vue({
store,
el: '#app',
created() {
this.$store.dispatch('fetchPeople');
},
computed: Vuex.mapState(['people']),
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
In parent:
<ul>
<li v-for="p in people">
{{ p.first_name }} {{ p.last_name }}
</li>
</ul>
<hr>
In custom component (the very same data, fetched only once):
<mycomp></mycomp>
</div>
- [Vuejs]-How can I prevent other characters from being inputted on an input except numbers using Javascript
- [Vuejs]-Vue 3: Field is not updating value