v-bucket
📦 Fast, Simple, and Lightweight State Management for Vue 3.0 built with composition API, inspired by Vuex.
Content Table
Examples
Running the examples:
$ npm run dev
$ yarn dev
Running tests
$ npm run test
$ yarn test
installation
install this package from NPM:
$ npm install v-bucket
or yarn:
$ yarn add v-bucket
usage
first you need to create your bucket.
create an index.js file, then import createBucket from v-bucket to start creating your store, like this:
import { createBucket } from "v-bucket";
const bucket = createBucket({
states: {
},
mutations: {
},
getters: {
},
modules: {
}
});
export default bucket;
then import it in your app entry point, main.js like this:
import { createApp } from "vue";
import App from "./dev.vue";
import bucket from "./bucket/index";
createApp(App)
.use(bucket)
.mount("#app");
using with composition api
for using v-bucket inside the setup() function you need to import useBucket first. like this:
<script>
import { useBucket } from "v-bucket"
export default {
setup() {
const bucket = useBucket();
return {
};
}
};
</script>
using with option api
like vue 2.X apps you can access v-bucket on the vue instace outside of the setup() function. like this:
<script>
export default {
mounted() {
this.$bucket
},
methods: {
click() {
this.$bucket.commit("SET_ID", this.id);
}
}
};
</script>
you only import useBucket when you want to use it inside setup() function
states
this is a single object contains all your application states.
accessing states:
mounted() {
this.$bucket.state.id
this.$bucket.state.module1.name
},
declare states inside your bucket (index.js):
import { createBucket } from "v-bucket";
const bucket = createBucket({
states: {
id: 1,
name: "mahdi",
phone: 120304
},
mutations: {
},
getters: {
},
modules: {
}
});
export default bucket;
NOTE: states object will be reactive by default. that means they will react to changes and update based on it.
NOTE: it's better to use mutations or getters to access states.
mutations
use mutations when you need to change a state value, all mutations will take 2 parameter:
const bucket = createBucket({
mutations: {
SET_ID(state, payload)
},
});
with state, you can have access to states object and change its value by passing payload.
NOTE: payload is optional.
const bucket = createBucket({
states: {
id: 0,
count: 0
}
mutations: {
SET_ID(state, payload) {
state.id = payload
}
COUNT_UP(state) {
state.count++;
}
},
});
you can't access mutations directly. you have to call them with commit method. like this:
methods: {
click() {
this.$bucket.commit("SET_ID", 5);
this.$bucket.state.id
this.$bucket.commit("SET_ID");
}
}
getters
you can use getters to access states and their values. getters are like Vue computed methods, they will cache the state and return it only when the state value change.
const bucket = createBucket({
states: {
id: 0,
name: "mahdi",
phone: 893729837
}
getters: {
GET_ID(state) {
return state.id
}
},
});
all getters will take 1 parameter:
- state (used to access states object)
using it in your vue app:
methods: {
click() {
this.$bucket.getters["GET_ID"]
}
}
actions
Actions are like mutations. the difference is:
- They can handle asynchronous operations
- Instead of mutating the state, actions commit mutations.
const bucket = createBucket({
states: {
count: 0
}
mutations: {
increment(state) {
state.count++
}
},
actions: {
increment(context) {
context.commit("increment");
}
anotherAction({ commit }) {
commit("someMutation");
}
}
});
also you can call other actions with context.dispatch. like this:
const bucket = createBucket({
actions: {
actionOne(context) {
context.commit("someMutation");
}
actionTwo(context) {
context.dispatch("actionOne");
}
}
});
also you can't access actions directly. you have to call them with dispatch method. like this:
methods: {
click() {
this.$bucket.dispatch("increment")
}
}
the context parameter will return root istance of our bucket. this is useful when working with modules.
modules
from vuex docs:
- Due to using a single state tree, all states of our application are contained inside one big object. However, as our application grows in scale, the store can get really bloated. To help with that, Vuex allows us to divide our store into modules.
const moduleA = {
states: { ... },
mutations: { ... },
actions: { ... },
modules: { ... }
}
const moduleB = {
states: { ... },
mutations: { ... },
actions: { ... },
modules: { ... }
}
const bucket = createBucket({
modules: {
moduleA,
moduleB
}
});
bucket.state.moduleA
bucket.state.moduleB
every modules also can have their own states, mutations, actions or even modules
how to access module states
all modules will be installed under the root module. so by accessing the root state you can also have access to its children. like this:
methods: {
click() {
this.$bucket.state.moduleA.name
this.$bucket.state.moduleB.id
}
}
how to access module getters
if you remember we used bracket notation to access getters, you can access your module's getter by defining its path. like this:
methods: {
click() {
this.$bucket.getters["moduleA/get_id"];
this.$bucket.getters["moduleB/get_name]; // `moduleB`'s name state
// you can go deep as many levels as you want
this.$bucket.getters["moduleA/moduleB/moduleC/moduleH/...];
}
}
they above code represent something like this:
-root
--moduleA
--moduleB
how to access module mutations
mutations are like getters, you can access your module's mutation by defining its path. like this:
methods: {
click() {
this.$bucket.commit("moduleA/set_id");
this.$bucket.commit("moduleB/set_name); // we can access mutations by commit()
// ...
}
}
how to access module actions
actions are like getters, you can access your module's actions by defining its path. like this:
methods: {
click() {
this.$bucket.dispatch("moduleA/set_id");
this.$bucket.dispatch("moduleB/set_name); // we can access mutations by dispatch()
// ...
}
}
sometimes you need to access another module's mutation or action within the current module
since the context parameter refer to the root module, you can access all of your modules by defining their path. like this:
const moduleA = {
actions: {
commitModuleB(context) {
context.commit("moduleB/set_name");
}
dispatchModuleB(context) {
context.dispatch("moduleB/request");
}
dispatchRoot(context) {
context.dispatch("rootMutation")
}
}
};
NOTE: if you want to access a module from another module like example, you need to define your paths from root
Contribution
Please make sure to read the Contributing Guide before making a pull request.
License
MIT
Todo