Should a child component have access to the store?

javascript, vue-component, vue.js, vuejs2, vuex

Solution

You're pretty much in the area of "primarily opinion-based," but I'll put in my two cents: The store is a global; lean toward having things manipulate it directly, rather than putting layers between it and components.

However, if the components you're using to implement your program have much promise of reusability, you might want to implement them in the usual encapsulated way, pushing the store interaction up.

But mostly I think manipulate the store directly.

Problem

Disclaimer: sorry this is going to be a bit long So I'm working on an intermediately complex app using Vue JS and Vuex. This is my first Vue SPA project so I'm facing some difficulties with architectural choices, particularity with the question "who should know about the store?" I'll describe my problem with a dummy example: Say we have a `Post` component that has 3 states to get switched with a button: - Read: the component shows the `title` and `text`. - Update: the component shows `title` input and `text` input - Create: the same component is used for creating a new post, so it's just like update but with empty values. First Approach: the component handles the store data: Now in order to show and update a post, the component gets an `id` prop and selects the post object from a list of posts within the store, and dispatches actions when necessary. It has an `update` internal attribute to switch between show and update states. As for the create state, a null `id` is passed to the component, so it won't fetch anything from the store and shows inputs, it dispatches insert actions. Example Code ``` const KnowledgebalePost = { name: 'Post', props: ['id'], data() { return { post: { title: '', text: '', }, state: 'show' } }, methods: { updateClicked() { this.state = 'update'; }, saveClicked() { this.state = 'show'; const postObject = { id: this.id, ...this.post }; const action = this.id ? 'updatePost' : 'addPost'; this.$store.dispatch(action, postObject); }, }, created() { if(this.id) { // just to simplify this.post = this.$store.state.posts[this.id]; } } }; ``` Comments The benefits I see in this is mainly the encapsulation of everything related to the component. It knows how to get its data and it is stand alone, all I need is to pass it an id. On the other hand, knowing too much is problematic, a lot of things outside of the scope of the component could break it. Second Approach: the component knows nothing about the store: In this approach the component would get everything as a property: `id`, `title`, `text`, and `state` to tell it if it should render inputs or just text fields. And instead of dispatching actions it would maybe emit events. Example Code ``` const IgnorantPost = { name: 'Post', props: ['id', 'title', 'text', 'state'], data() { return { post: { title: '', text: '', }, internalState: 'show' } }, methods: { updateClicked() { this.internalState = 'update'; }, saveClicked() { this.internalState = 'show'; this.$emit('saving', { id: this.id, ...this.post }); }, }, created() { this.post.title = this.title; this.post.text = this.text; this.internalState = this.state; } }; ``` Comments While this solves the dependencies problem, it just pushes some of the logic to the parent component like handling if states of the `Post` component. Also if this parent has many children other than `Post`, it'd become a very fat logic container. The End Note that my component is a lot more complex, any ideas on how to approach this particular problem? Thanks in advance, and I appreciate you reading so far.

Original source