0

I have a very basic site using Vue.JS, VueX, and Vue-Router.

I have two routes defined: '#/' and '#/account/' These routes are populated with two components in .vue files, loaded dynamically at page load via http-vue-loader (to avoid dealing with webpack/etc since the project is so small).

The '#/' view is a static component.

The '#/account' view displays the user's first and last name in <input type="text"> boxes.

If I navigate to the '#/account' page from the '#/', the first/last name are populated properly. But if I then refresh the browser, the textboxes become empty and don't re-populate until after I navigate to another route and back again.

The data in this component are being loaded from the global VueX store, which is being commit()ted on page load as the result of an AJAX call.

Why won't these fields populate upon a page refresh?

Pertinent code:

main.js: (loaded as <script type="module"> from main html file)

const store = new Vuex.Store({ state: { user: {firstname: '', lastname: ''} }, mutations: { updateUser(state, user){ state.user = { ...user } } } }) $(document).ready(function() { let templates = {} templates.home = httpVueLoader('./templates/home.vue') templates.account = httpVueLoader('./templates/account.vue') templates.not_found = httpVueLoader('./templates/404.vue') // Set up routes: const routes = [ { path: '/', component: templates.home }, { path: '/account', component: templates.account }, // Not found: (place this route last) { path: '*', component: templates.not_found } ] const router = new VueRouter({ routes }) // Start Vue app: const app = new Vue({ router, store, components: { } }).$mount('#vueApp') checkLogin() // Check if user is logged in - if so, populate VueX store with user info. function checkLogin() { // Check if user is already logged on. console.log("Checking for login...") Get({ url: 'https://[api-url]/v1/auth' }) .then((result) => { console.log("Result: ", result) if (result.data.logged_in) { loadUI() store.commit('updateUser', result.data.user) } else { logout() } }) } 

account.vue:

<template> ... <input type="text" class="form-control" id="txtFirstname" aria-describedby="txtFirstnameHelp" v-model="firstname"> ... <input type="text" class="form-control" id="txtLastname" aria-describedby="txtLastnameHelp" v-model="lastname"> ... </template> <script> module.exports = { data: function() { return { firstname: this.$store.state.user.firstname, lastname: this.$store.state.user.lastname } }, ... </script> <style scoped> </style> 
0

1 Answer 1

1

The fix is that these properties should be declared as computed properties, instead of returning them in the data object:

in Account.vue:

module.exports = { data: function() { return {

 } }, computed: { firstname: function() { return this.$store.state.user.firstname }, lastname: function() { return this.$store.state.user.lastname } }, 

...

Sign up to request clarification or add additional context in comments.

2 Comments

Correct! I suggest explaining why in your answer though
I don't think this works on Vue3. I get error Parsing error: In strict mode code, functions can only be declared at top level or inside a block. (6:19) I am able to access my data in the template using myStore.rates but if I refresh the page it's all gone, because when the page loads the data is not loaded yet.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.