How to set initial values for data from vuex? How to set initial values for data from vuex? vue.js vue.js

How to set initial values for data from vuex?


You were right, computeds are evaluated after the initial data function is called.

Quick fix

In the comments, @Jacob Goh mentioned the following:

$store should be ready before data function is called. Therefore, firstName: this.$store.state.userProfile.firstName should just work.

export default {  name: 'EditAccount',  data() {    return {      accountInfo: {        firstName: this.$store.state.userProfile.firstName      }    }  }};

Really need computeds?

See @bottomsnap's answer, where setting the initial value can be done in the mounted lifecycle hook.

With your code, it would look like this:

import { mapState } from 'vuex';export default {  name: 'EditAccount',  computed: {    ...mapState(['userProfile'])  },  data() {    return {      accountInfo: {        firstName: ''      }    }  }  mounted() {    this.accountInfo.firstName = this.userProfile.firstName;  }};

Though it may render once without the value, and re-render after being mounted.

Container versus presentation

I explain Vue's communication channels in another answer, but here's a simple example of what you could do.

Treat the Form component as presentation logic, so it doesn't need to know about the store, instead receiving the profile data as a prop.

export default {    props: {        profile: {            type: Object,        },    },    data() {        return {            accountInfo: {                firstName: this.profile.firstName            }        };    }}

Then, let the parent handle the business logic, so fetching the information from the store, triggering the actions, etc.

<template>    <EditAccount :profile="userProfile" :submit="saveUserProfile"/></template><script>import { mapState, mapActions } from "vuex";export default {    components: { EditAccount },    computed: mapState(['userProfile']),    methods: mapActions(['saveUserProfile'])}</script>

While Jacob is not wrong saying that the store is ready, and that this.$store.state.userProfile.firstName will work, I feel this is more a patch around a design problem that can easily be solved with the solution above.


Bind your input with v-model as you were:

<div id="app">    <input type="text" v-model="firstName"></div>

Use the mounted lifecycle hook to set the initial value:

import Vue from 'vue';import { mapGetters } from 'vuex';new Vue({      el: "#app",      data: {        firstName: null      },      computed: {        ...mapGetters(["getFirstName"])      },      mounted() {        this.firstName = this.getFirstName      }    })