@aadams you were asking about Meteor Accounts in Vue, so here’s my take on the matter, using accounts-password package without Blaze templates and passing the user to Vuex.
It’s less complicated than in my own stuff (no validation etc and without Jade so more people can learn from it), but it does its job. Most probably few things could be done better and I’m counting on you guys to point them out.
How do you think, what should be the best practices for accounts management in Vue? How do you organize it in your projects?
One more thing, the project uses Vuex2 from npm, not Akryum’s package which is still based on Vuex1. That will most probably change when Vuex2 package is ready.
Thanks for this @gusto. I haven’t looked at the project yet, but have a quick question. How are you integrating with the Accounts package when you don’t have the Accounts package installed in your project? Is there an alternative API that allows you to hook into it?
Once we have the API via accounts-password, we just need to make the appropriate calls and build the access forms in order to integrate with it. It’s more work to be sure, but doable!
More work, but worth it. I’ve been doing it with Blaze anyways, because accounts-ui doesn’t satisfy my needs, f.e. doesn’t check if the user / email is available.
that must be in config somewhere. For life of me I can’t get Meteor.user() into vue data space or somewhere near that other than blunt {{Meteor.user()}} in template. Meteor.user() is recognized by akryum-vue, but it won’t overwrite on top of vue data as if doing user.find() {which won’t work}.
The Vuex action below works for me. I call it in the created hook of my main component. I commit to three properties - whole user object, string with username or guest and string with user Id
fetchMeteorUser({commit}) {
Tracker.autorun(() => {
const user = Meteor.user()
commit('updateCurrentUser', user)
commit('updateUsername', user ? user.username : 'guest')
commit('updateUserId', user ? user._id : null)
})
}
I’m not sure what the content of your this.$store.userGet is.
Probably, I should rewrite my methods so that it only commits user object and add getters for username and userId. But I got used to this structure so for now I keep it as it’s working fine.
Apparently that breaks app if state.user is undefined when you state.user.prop in getters, so you really did the right thing (at very least on first load it will break). I made issue of it here (that Meteor.user() is difficult to access): https://github.com/Akryum/meteor-vue-component/issues/118
meteorUser: state => state.meteorUser ? state.meteorUser : {},
That said, it’s a common situation that we want a user object to contain more fields that just what Meteor.user() returns, so we get it from additional publication.
So how do you actually access subscription if “this” isn’t available in component router hook. I was told to use the global one by Akryum, but then should I just call the subscriptions in there instead then?
Here’s a little trick allowing to wait until Meteor.user() is available in vue-router navigation guards.
This can be used either to restrict the access for guests or to make sure that the component doesn’t get created before Meteor.user() is available. That second use case can be also done by v-if on <router-view> though.
If used on the parent route level, it automatically covers all the children routes.
If there is such a need, it can be even used to make whole Vue instance in /client/main.js wait until Meteor.user() is ready, but I am not sure if that is a good practice. Potentially it can be useful with Meteor 1.5’s dynamic imports.
BeforeEnter hook and next() function are explained in the navigation guards chapter of vue-router documentation.
import { Meteor } from 'meteor/meteor'
import { Tracker } from 'meteor/tracker'
export default () => {
return new Promise((resolve, reject) => {
Tracker.autorun((c) => {
// stop computation when Meteor.user() is ready
Meteor.user() !== undefined && c.stop()
// return false if user is a guest
Meteor.user() === null && resolve(false)
// return true if user is logged in
Meteor.user() && resolve(true)
})
})
}