I am trying to learn Vuex and build struct of my vue 3 app.
And could't find answer about scope of modules.
The struct of my app described on img.
Related
I'm trying to write SSR-friendly code, keeping in mind a potential migration of my app from SPA to SSR. One of the principles of such code is to avoid statefull singletons which can cause cross request state pollution
The problem comes when I need to use an instance of Vuex, Vue-router, Vue-i18n etc. outside of Vue component. Because the solution in all the respective SO answers is... You guessed it. To create and export a statefull singleton in a separate js file and then import it all over the app:
Vue-router: https://stackoverflow.com/a/43562210/11208064
Vuex: https://stackoverflow.com/a/47575742/11208064
Vue-i18n: https://stackoverflow.com/a/66695008/11208064
A simple example
// store.js
export default new Vuex.Store() {} // this is a singleton
// someOtherModule.js
import { store } from './store.js'
Pinia has covered the issue in the docs. They recommend to access the pinia instance via app.$pinia. However they don't specify how do I access the app instance itself.
Also the problem is not limited to these libraries. We write our own modules which work in a similar manner.
Researching the issue I came across this article. It suggests to wipe module cache, so each time you require it all the code is executed again, making it fresh and stateless. Sounds pretty sophisticated, but maybe this is the way? And if not, what is the recommended solution?
I'm building a library of stencil.js components that will be published on npm.
Internally, my components use sub-components that I do not wish to expose to the outside world.
Is there a way to define a "private" components that can be used internally by other components in the same namespace, but are not exposed externally?
You can simply create a functional component which allows you to only render it inside of you parent web component, without exposing it externally.
Functional components:
aren't compiled into web components,
don't create a DOM node, don't
have a Shadow DOM or scoped styles,
don't have lifecycle hooks, are
stateless.
Please check this doc, it is quite straight forward to use it:
https://stenciljs.com/docs/functional-components
Summary: Can Vuex modules be made $store references in .vue components (instead of referring to the Global Store as it is now after Vue.use(Vuex)) ?
Details:
I read this: vuex modules and I get that the global store can be composed as a bunch of vuex modules.
This is great but is there also a way to make these vuex modules the $store references within vue components instead of $store pointing to the global store (as it is now ?).
This will be mighty useful (IMO) since vue components then have to only be aware of its local store's references (or their own vuex modules); and, how they compose the global store.
Please advise.
I have set up a rather large Vuex project with multiple modules.
https://vuex.vuejs.org/en/modules.html
To grab the example of a getter a getter from a search module could be addressed like so:
computed: {
filters() {
return this.$store.state.search.filters;
}
}
Because I need to access the state of the module by referencing the search property in my property chain do I still need to namespace my module?
The documentation states the following:
By default, actions, mutations and getters inside modules are still
registered under the global namespace - this allows multiple modules
to react to the same mutation/action type.
https://vuex.vuejs.org/en/modules.html#namespacing
But if the module is under its own property in the store isn't the only conflict that could happen between modules themselves, which can easily be prevented by a simple naming convention of the files?
What am I missing here?
But if the module is under its own property in the store isn't the only conflict that could happen between modules themselves, which can easily be prevented by a simple naming convention of the files?
No, you misunderstand. The state itself is properly namespaced, but mutations, actions and getters are still collected on a global level so you can e.g. dispatch one Action and several actions from different modules react to it.
That's the default behavior, but the good news is, that there's an option to namespace mutations, actions and getters: "namespaced: true".
it's documented here: https://vuex.vuejs.org/en/modules.html#
Scroll down to the "Namespacing" section.
As I am trying to play with evolutionary algorithms and building visualization tools of the process, I'd like to use VueJs with P5Js.
I have this code: (SO) Playing with Evolutionary Algorithms on Codepen.io
The problem is that Vue instance's data population does not update properly.
Here what I tried to do:
Pass the global objet Game as Vue instance's data. Then population get updated properly, but the data is so big that everything get laggy;
Populate Game.population array when declared, but it does not work: P5JS throw me an error createVector() is not defined;
Populate Game.population array in Vue instance's beforeCreate() method. It does not work neither. Giving me an other error;
Proxy Game.population by an other object Data declared globally or in Vue instance's beforeCreate() method, for curating interesting cells data (I don't need the pos attribute) and so avoiding createVector() error. It is a dead end;
Thinking about hoisting, I wondered if VueJS was initialized before P5JS run. It is the case. But I can't figure how to change that.
What is the issue here? How should I refactor my script so Vue instance's data and Game.population can be linked?
This solution isn't as pretty as throwing your Game object into the Vue instance, but it works.
Forked here: https://codepen.io/andymerskin/pen/LyoEmW
Here's what I changed:
Added a computed getter/setter for population, giving you a clean way to render the array's length in the template, and the ability to assign it in your Game loop using app.population = Game.population in your Game.doPopulatePacks routine.
Changed data.property in the Vue instance to _property to keep the naming conventions paired up for use inside the computed property. It does come with the caveat that it's no longer proxied to avoid conflicts with Vue's internal properties, since we're leaning on the computed property in the template.
(Currently, there isn't a clear convention for defining private properties in a Vue instance, even though underscores _ are the preference in JS more broadly.)
And with that, you'll see in the forked demo that your game's population stays up to date in the UI.