Shareable Component + Vuex Best Practice

vuex

#1

When using Vuex, I push mutation logic into Vuex, and keep it away from the component.

However, I found when building shareable components, that I don’t want the user to have to repeat implementing too much logic in each store which the component can be used with…

Do ppl usually bring that logic back into the component? and keep the required Vuex dependencies as lean as possible?

Perhaps there’s other ways of going about things…


#2

If the logic is needed to let the component work properly. Than the logic should be placed in the component, a component should be standalone and shouldn’t require VueX to be installed.


#3

Thanks for this.

Thing is, we have a filter components, that is used in different places across the site.

As a user uses the filters, we want to save the filter state(s) for different pieces of data…

Understand where you’re coming from, just seems unavoidable…


#4

You could emit values from your filter component to your client specific component and commit to the state in that component.


#5

Aha. Good idea, I need to think about that now : )


#6

Hi,

You can register a vuex module in the created part of your component. If you use a required prop on your component to define the vuex module path like this :

this.$store.registerModule('module/path/'+this.prop, this.myModule )

each instance of the component can have its own store with minimal implementation. You can even go further if you need conditional getters/actions depending on other props (this MyModule above).


#7

Could a functional component with scoped slots come to the rescue here?

<vuex-link path="foo/bar" slot-scope="{commit}">
  <component @change="commit" />
</vuex-link>

Just an idea, I haven’t used scoped slots for ages, but it might be a way to encapsulate the vuex-specific code in the wrapper, and the rest of it in the markup. You could register <vuex-link> as a global component and use it where needed.

Then again, maybe a mixin would be simpler:

mixins: [
    vuexLink('foo/bar') // adds a `commit()` method
]

#8

Mm don’t know for sure. Feels like abusing the scoped slot, because someone else can use the slot to change the way component is rendered. When you only want to commit the value that’s send back from component to store.


#9

So it turns out it is possible:

Feels like abusing the scoped slot, because someone else can use the slot to change the way component is rendered

Nope, the slot is in the Vuex data provider, and the it allows anything to be rendered, but provides the api to to the store.

As you can see, it works, but is not particularly elegant.

Thanks to Adam Wathan for the idea.


#10

Nice! Didn’t know this was possible.
So you could wrap other things also and pass data back to parent this way?


#11

Yeah, Adam Wathan’s course covers this, and he calls them “Data Provider” components:

It’s very cool!