Hello everyone, I am Lin Sanxin, a front-end rookie. Today, I will share with you a simple implementation of Vuex source code.
This time only implements state, getters, mutations, actions. Vuex consists of the install method and the Store class. The mixins in Install are the core of Vuex
This is the file directory
vuex.js
// vuex.js
let Vue;
const install = (v) = > {
console.log(v)
Vue = v;
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.store) {
// root
this.$store = this.$options.store;
} else {
this.$store = this.$parent && this.$parent.$store;
}
console.log(this.$store); }})}class Store {
constructor(options) {
this.vm = new Vue({
data: {
state: options.state
}
});
let getters = options.getters || {};
this.getters = {};
console.log(Object.keys(this.getters))
Object.keys(getters).forEach(getterName= > {
Object.defineProperty(this.getters, getterName, {
get: (a)= > {
return getters[getterName](this.state); }})})let mutations = options.mutations || {};
this.mutations = {};
Object.keys(mutations).forEach(mutationName= > {
this.mutations[mutationName] = payload= > {
mutations[mutationName](this.state, payload); }})let actions = options.actions || {};
this.actions = {};
Object.keys(actions).forEach(actionName= > {
this.actions[actionName] = payload= > {
actions[actionName](this.state, payload);
}
})
}
get state() {
return this.vm.state;
}
commit(name, payload) {
this.mutations[name](payload);
}
dispatch(name, payload) {
this.actions[name](payload); }}export default {
install,
Store
}
Copy the code
index.js
// index.js
import Vue from 'vue';
import vuex from './vuex';
Vue.use(vuex);
export default new vuex.Store({
state: {
num: 1
},
getters: {
getNum(state) {
return state.num * 2; }},mutations: { in(state, payload) { state.num += payload; }, de(state, payload) { state.num -= payload; }},actions: { in (state, payload) {
setTimeout((a)= > {
state.num += payload;
}, 2000)}}})Copy the code
main.js
// main.js
import Vue from 'vue';
import App from './App.vue'
import store from './store/index';
new Vue({
store,
el: '#app'.components: {
App
},
template: '<App/>',})let linsanxin = 1;
console.log(linsanxin)
Copy the code
App.vue
// app.vue <template> <div> {{this.$store.state.num}} {{this.$store.getters.getNum}} < button@click ="addNum"> <button @click="addNumByAsync"> </button> <div id="a">asadasd</div> </button @click='add'> add </button> <ul v-for="(item,index) in list" :key="index"> <li class="ll">{{item.name}}</li> </ul> </div> </template> <script> import img from "./asset/images/haha.jpg"; import "./asset/styles/test.css"; import "./asset/styles/global.stylus"; export default { name: "App", created() { console.log(img); }, data() { return { list: [ { name: "lin" }, { name: "lin" }, { name: "lin" }, { name: "lin" }, { name: "lin" } ] }; }, methods: { add(){ this.list.push({name:'k'}) }, addNum(){ this.$store.commit('in',2); }, addNumByAsync(){ this.$store.dispatch('in',3); }}}; </script> <style scoped lang='stylus'> #a { background: red; } </style>Copy the code