Open dcrystalj opened 5 years ago
Getters are computed properties. And just like you can have nested objects in your component's data
, but not nested computed props, we can have nested (namespaced) state objects in vuex, but not nested getters.
So we have to do the namespacing like we do it for actions and mutations: with a slash-separated string path: 'namespace/action|mutation|getter'
.
Seen that way, the state is actually the one exception to the rule, not the getters.
It it impossible to provide an API like you proposed? no, certainly not. It's just that so far, we so far felt that getters, actions and mutations sharing the same namespace syntax makes sense.
+1 for $store.gettters.user.fullName
I understand the need to differentiate state from actions/mutations/getters however it looks much cleaner to have it in the same style as namespaced state.
Could it be possible to provide an option for this upon creating a store?
an API like you proposed? no, certainly not. It's just that so far, we so far felt that getters, actions and mutations sharing the same namespace syntax makes sense.
The way we are using vuex in our company is that we always use $store.dispatch('namespace/action') in components and we never use mutations. so far this feels ok, except possible errors in naming (less autocompletion)
to render data we use {{ $store.state.user.fullName }}
or {{ $store.getters['user/fullName'] }}
and we never use mapGetters or mapState. We could write extra getter for every state just to have things consistent, but as you know, less code less bugs + less work.
Another incosistent things in api are parameters for getters, actions and mutations; but this is for another issue.
I believe allowing to have consistant api $store.state['user/fullName']
would be better but i prefer object like style which is less prone to errors and feels less hackish.
You should use mapState or mapGetters, which make it more readable. Exemple:
import { mapState, mapGetters } from 'vuex';
export default {
computed: {
...mapState({
userFullName: state => state.user.fullName,
}),
// OR
...mapGetters({
userFullName: 'user/getUserFullName', // (getters name should be different)
}),
},
watch: {
userFullName() {
....
},
},
};
I agree, the difference in API is confusing. https://vuex.vuejs.org/guide/modules.html#binding-helpers-with-namespace
First of all, the docs do not have an example of mapGetters with moduled stores. When is comes to modules, mapActions (array declaration) is different than mapGetters(object declaration). APIs should have consistent design for an easier learn curve.
@mathieustan for large scale app we found out that using any mapXxxx is just
so we never use this helper and I can tell you how much better life is :D But I agree that in docs it is all about mapXxxx and you always get a filling that this is the way to go. I think all this mapXxxx should be removed from docs examples so the newbies would know where does things come from and not be thinking we should use it like this because it is in the docs.
another Confusing example: i think this:
...mapState([
'modulex/count'
]),
should be equal to :
...mapState('modulex', {
'modulex/count': 'count',
}),
and much more easier! but it's not!!!
if a module has many properties, there will be lots of redundant codes such as $store.state.user.a
, $store.state.user.b
, $store.state.user.c
, $store.state.user.d
,$store.state.user.e
... i do not like to repeat. Maybe you mean i could use object destructuring but i think if you use destructuring to declare as global variables it just
I found that using createnamespacedhelpers is more readable than using mapXXX.
I disagree with @dcrystalj, if each developer uses different naming for things, I think that's an issue to be discuss by the team.
// you can change the component variable name, to better describe where it comes from
...mapGetters('user', {
userName: 'name'
})
same end result as:
// user.store.js
export userStore = createNamespacedHelpers('user', module);
// component{User}.Vue
import {userStore} from './user.store.js'
...userStore.mapGetters({
userName: 'name'
})
@pikax your solution is still making code verbose and tedious.
...mapGetters('user', {
userName: 'name'
})
this is just making one more layer of abstraction dev has to hold in the head. using $store.getters.user.name would be as clear as crystal and also one line of code. Please note that when having example of one component it's not problem. This is problematic when app is huge/ multiple years of work
I actually came here looking for the opposite. I was wondering how I could access state by doing
store.state['a/b/c/count']
just like how I could do
store.getters['a/b/c/count']
Is there a way to access getters from both the root state and a namespaced module? Below, getAuthStatus
is a getter in the root state, and I'm wondering if I can access both root and the namespaced module getters in one ...mapGetters
call
...mapGetters(["getAuthStatus"]),
...mapGetters("cartModule", ["getCartData"])
@refayathaque yes, with a level of verbosity:
...mapGetters({
getAuthStatus: "getAuthStatus",
getCartData: "cartModule/getCartData"
})
@refayathaque yes, with a level of verbosity:
...mapGetters({ getAuthStatus: "getAuthStatus", getCartData: "cartModule/getCartData" })
Thank you @cuebit !
What problem does this feature solve?
The most confusing thing when using namespaced vuex is inconsistant api with state and getters.
Example: to access state
this.$store.state.user.name
to access getter
this.$store.getters['user/fullName']
This is so confusing for me and my coworkers. Is there reason to have this inconsistency?
Problem occurs when you try to watch getters example:
Current solution Is to use mapGetters() helper for getters only. Why? because of weird api. Please note that we try to avoid mapGetters, mapState helpers... due to explicitly in large app
What does the proposed API look like?
Add api for getters same as is for state.
Example:
$store.gettters.user.fullName