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

The effect

Conclusion: I will become a god, come on.