Reputation: 2758
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>
Upvotes: 0
Views: 580
Reputation: 2758
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 }
},
...
Upvotes: 1