• 手写vuex简版


    template

    <template>
      <div class="hello">
        <h1>{{ msg }}</h1>
        <p @click="$store.commit('add')">counter: {{$store.state.counter}}</p>
        <p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p>
        <p>{{$store.getters.doubleCounter}}</p>
      </div>
    </template>
    

    store/index.js

    import Vue from "vue";
    import Vuex from "./zhen-vuex";
    
    // this.$store
    // this.$store.state.xxx
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
        counter: 0,
      },
      mutations: {
        add(state) {
          // state从哪来?
          state.counter++;
        },
      },
      actions: {
        add({ commit }) {
          // 参数是什么,哪来的?
          setTimeout(() => {
            commit("add");
          }, 1000);
        },
      },
      getters: {
        doubleCounter(state) {
          return state.counter * 2;
        },
      },
    });

    zhen-vuex手写

    //实现目标
    // 1.插件:挂载$store
    // 2.实现Store
    
    let Vue; //首先保存Vue构造函数
    class Store {
      // 把vuex.state都变成响应式.用defineReavtive只能定义.借助new Vue能对vuex.state全部进行响应式处理
      constructor(opotions) {
        this._mutations = opotions.mutations;
        this._actions = opotions.actions;
        this._wrappedGetters = opotions.getters;
        // 定义computed选项
        const computed = {};
        this.getters = {};
        const store = this; //保存this指向
        // opotions.getters => {doubleCouter(state){}}
        Object.keys(this._wrappedGetters).forEach((key) => {
          // 获取用户定义的getter
          const fn = store._wrappedGetters[key];
          // 转换为computed可以使用的无参数的形式
          computed[key] = function() {
            return fn(store.state);
          };
          // 为getters定义只读属性(用户只能访问getters)
          Object.defineProperty(store.getters, key, {
            get: () => store._vm[key],
          });
        });
        // this.state = new Vue({
        //   data: opotions.state,
        // });
        // 对上面改写成不对外暴露的形式
        // $$state是访问不到的,会被隐藏起来
        this._vm = new Vue({
          data: {
            $$state: opotions.state,
          },
          computed,
        });
    
        // 绑定commit、dispatch的上下文store实例
        this.commit = this.commit.bind(this);
        this.dispatch = this.dispatch.bind(this);
      }
      // 对this.state进行隐藏,并不想外界去修改它,通过get的方式
      get state() {
        // _data和$data两者是一样的,
        return this._vm._data.$$state;
      }
      set state(v) {
        console.error("不能对vuex中的state进行直接修改");
      }
      commit(type, payload) {
        const entry = this._mutations[type];
        if (!entry) {
          console.error("未知mutations类型");
        }
        entry(this.state, payload);
      }
      dispatch(type, payload) {
        const entry = this._actions[type];
        if (!entry) {
          console.error("未知actions类型");
        }
        entry(this, payload);
      }
    }
    function install(_Vue) {
      Vue = _Vue;
      // Vue.use(install)的执行时间在很靠前的,这个时候还获取不到Vuex实例中,所以要巧妙的运用到Vue.mixin的beforeCreate()方法获取并挂载Vuex
      // 全局混入(每个组件都会用到)
      // 全局混入目的:延迟下面逻辑到vuex已经创建完毕并且附加到选项上时才执行
      Vue.mixin({
        beforeCreate() {
          if (this.$options.store) {
            Vue.prototype.$store = this.$options.store;
          }
        },
      });
    }
    // 为什么要{ store, install }  Vue.use(Vuex);use的是Vuex.install//export default new Vuex.Store
    export default { Store, install };
  • 相关阅读:
    [puppet]如何设置全局exec path
    noVNC配置小结
    [CloudOps]解决Windows系列镜像在Openstack上蓝屏
    解决 /usr/bin/env: php: No such file or directory
    构建一个多区域的公有云平台:Stacklab
    ssh自动添加hostkey到know_hosts
    A few thoughts about Open Source Software
    简单翻译:Understanding Linux Network Internals 2.2. net_device Structure
    近期小结
    [Music]《our love will always last》
  • 原文地址:https://www.cnblogs.com/gengzhen/p/15404940.html
Copyright © 2020-2023  润新知