手写vuex

这篇具有很好参考价值的文章主要介绍了手写vuex。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

vuex

基本用法

vuex是作为插件使用,Vue.use(vuex)

最后注册给new Vue的是一个new Vuex.Store实例

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex) // Vue.use注册插件
// new Vuex.Store实例
export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

// main.js
import store from './store'

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

根实例 组件

比如这里,App是vue实例的子组件即渲染组件

import App from './App.vue'
import store from './store'

new Vue({
  router,
  store, // 每个子组件都有$store
  render: h => h(App)
}).$mount('#app')

手写vuex,vue.js,javascript,前端

getters:注册参数state

mutation: (state, payload)

actions: ({ commit, dispatch }, payload)

手写vuex,vue.js,javascript,前端

?模板编译语法

手写vuex,vue.js,javascript,前端

手写vuex: install

install:接收注入的参数Vue,那么这个插件就是不需要依赖于Vue的。

store是通过根组件传入进去的

通过Vue.mixin

手写vuex,vue.js,javascript,前端

main->app->xxx

main.js中创建实例,app.vue

也说明组件的渲染是从父到子

export default function applyMixin (Vue) {
  Vue.mixin({
    beforeCreate: vueInit
  })
}
function vueInit () {
  const options = this.$options
  if (options.store) {
    this.$store = options.store
  } else if (options.parent && options.parent.$store) {
    this.$store = options.parent.$store
  }
  // console.log('vueInit', this, this.$options.name)
}

状态实现 & 基本版实现

state实现:

getters实现:

借用computed。return结果不变,函数不会重新执行。

export default {
  data () {
    return {

    }
  },
  computed: {
    a () {
      return 'xxx'
    }

  }
}

手写vuex,vue.js,javascript,前端

mutations(actions同):

手写vuex,vue.js,javascript,前端

import applyMixin from './mixin'
let Vue
export class Store {
  constructor (options) {
    const state = options.state
    const getters = options.getters
    const computed = {}
    this.getters = {}
    Object.keys(getters).forEach(key => {
      const fn = getters[key]
      computed[key] = () => fn(this.state) // 注入state参数
      Object.defineProperty(this.getters, key, {
        get: () => {
          return this._vm[key]
        }
      })
    })

    this._vm = new Vue({
      data: {
        $$state: state
      },
      computed
    })
    const mutations = options.mutations
    const actions = options.actions
    this.mutations = {}
    this.actions = actions
    Object.keys(mutations).forEach(key => {
      const fn = mutations[key]
      this.mutations[key] = (payload) => fn(this.state, payload)
    })
    Object.keys(actions).forEach(key => {
      const fn = actions[key]
      this.actions[key] = (payload) => fn(this, payload)
    })
    const commit = (type, payload) => {
      this.mutations[type](payload)
    }
    const dispatch = (type, payload) => {
      this.actions[type](payload)
    }
    // this.commit = commit
    this.dispatch = dispatch
  }

  commit=(type, payload) => {
    this.mutations[type](payload)
  }

  get state () {
    return this._vm._data.$$state
  }
}
export const install = (_Vue) => {
  Vue = _Vue
  applyMixin(Vue)
}

模块划分*

namespaced: false

state会合并:

state:{

age:18,

a:{

age:28

},

b:{

age:58

}

}

mutations会把同名的组合成一个数组,然后commit的时候全部触发

手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端

模块安装*

手写vuex,vue.js,javascript,前端

实现Module类

手写vuex,vue.js,javascript,前端

installModule

手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端

import applyMixin from './mixin'
import ModuleCollection from './module/module-collection'
const installModule = (store, rootState, path, module) => {
  module.forEachMutation((mutation, key) => {
    store._mutations[key] = store._mutations[key] || []
    store._mutations[key].push((payload) => {
      mutation.call(store, module.state, payload)
    })
  })
  module.forEachAction((action, key) => {
    store._actions[key] = store._actions[key] || []
    store._actions[key].push((payload) => {
      action.call(store, store, payload)
    })
  })
  module.forEachGetter((getter, key) => {
    store._wrappedGetters[key] = () => {
      return getter.call(store, module.state)
    }
  })
  module.forEachChild((child, key) => {
    installModule(store, rootState, path.concat(key), child)
  })
}
let Vue
export class Store {
  constructor (options) {
    const state = options.state
    /**
     * 对数据进行格式化操作:递归形成了一棵树
     */
    this._module = new ModuleCollection(options)
    console.log('this._module===', this._module)
    this._mutations = {}
    this._actions = {}
    this._wrappedGetters = {}
    installModule(this, state, [], this._module.root)
    // const getters = options.getters
    // const computed = {}
    // this.getters = {}
    // Object.keys(getters).forEach(key => {
    //   const fn = getters[key]
    //   computed[key] = () => fn(this.state) // 注入state参数
    //   Object.defineProperty(this.getters, key, {
    //     get: () => {
    //       return this._vm[key]
    //     }
    //   })
    // })
    //
    // this._vm = new Vue({
    //   data: {
    //     $$state: state
    //   },
    //   computed
    // })
    // const mutations = options.mutations
    // const actions = options.actions
    // this.mutations = {}
    // this.actions = actions
    // Object.keys(mutations).forEach(key => {
    //   const fn = mutations[key]
    //   this.mutations[key] = (payload) => fn(this.state, payload)
    // })
    // Object.keys(actions).forEach(key => {
    //   const fn = actions[key]
    //   this.actions[key] = (payload) => fn(this, payload)
    // })
    // const commit = (type, payload) => {
    //   this.mutations[type](payload)
    // }
    // const dispatch = (type, payload) => {
    //   this.actions[type](payload)
    // }
    // // this.commit = commit
    // this.dispatch = dispatch
  }

  // commit=(type, payload) => {
  //   this.mutations[type](payload)
  // }

  get state () {
    return this._vm._data.$$state
  }
}
export const install = (_Vue) => {
  Vue = _Vue
  applyMixin(Vue)
}

import { forEachValue } from '@/vuex/utils'

export default class Module {
  constructor (options) {
    this._raw = options
    this._children = {}
    this.state = options.state
  }

  getChild (moduleName) {
    return this._children[moduleName]
  }

  addChild (moduleName, newModule) {
    this._children[moduleName] = newModule
  }

  forEachMutation (fn) {
    if (this._raw.mutations) {
      forEachValue(this._raw.mutations, fn)
    }
  }

  forEachAction (fn) {
    if (this._raw.actions) {
      forEachValue(this._raw.actions, fn)
    }
  }

  forEachGetter (fn) {
    if (this._raw.getters) {
      forEachValue(this._raw.getters, fn)
    }
  }

  forEachChild (fn) {
    forEachValue(this._children, fn)
  }
}

模块的状态*

手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端

命名空间的实现

手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端

注册的是时候加上namespaced

手写vuex,vue.js,javascript,前端

vuex插件的使用

手写vuex,vue.js,javascript,前端

手写vuex,vue.js,javascript,前端

辅助函数

手写vuex,vue.js,javascript,前端手写vuex,vue.js,javascript,前端文章来源地址https://www.toymoban.com/news/detail-619132.html

到了这里,关于手写vuex的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手写vuex

    vuex是作为插件使用,Vue.use(vuex) 最后注册给new Vue的是一个new Vuex.Store实例 根实例 组件 比如这里,App是vue实例的子组件即渲染组件 getters:注册参数state mutation: (state, payload) actions: ({ commit, dispatch }, payload) ?模板编译语法 install:接收注入的参数Vue,那么这个插件就是不需

    2024年02月15日
    浏览(34)
  • 10 使用Vue+axios+Vuex实现登录后前端数据本地化存储实战

    这已经是《 Vue + SpringBoot前后端分离项目实战 》专栏的前端部分第8篇博客了, 服务端部分 由天哥(天哥主页)负责,目前专栏目录如下: Vue + SpringBoot前后端分离项目实战 - 前端部分 1. 手把手带你做一套毕业设计-征程开启 2. 我应该把毕业设计做到什么程度才能过关? 3

    2024年02月16日
    浏览(38)
  • vue中vuex的五个属性和基本用法,另加js-cookie的使用

    VueX 是一个专门为 Vue.js 应用设计的状态管理构架,统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 state, getters, mutations, actions, modules。 1. state: vuex的基本数据,用来存储变量 2. geeter: 从基本数据(state)派生的数据,相当于state的计算属性 3.

    2024年02月14日
    浏览(41)
  • 前端常见面试题之js基础(手写深拷贝、原型和原型链、作用域和闭包)

    值类型包括 :字符串(string)、数字(number)、布尔值(boolean)、undefined。 引用类型包括 :对象(object)、数组(array)、函数(function)和null。 二者的区别 当你将一个值类型赋给另一个变量时,会复制该值的副本。而当你将一个引用类型赋给另一个变量时,只会复制对

    2024年01月22日
    浏览(47)
  • JavaScript - 判断当前时间是否在指定区间内,例如:9:00~12:00(检查当前时间是否处于规定的两个时间段范围内),适用于 vue.js / uniapp / 微信小程序等前端项目

    例如,您想知道当前时间是否处于 9:00 ~ 12:00 时间区间内,然后根据这个判断进而实现业务逻辑。 如下示例所示, 本文提供一个函数,您只需要传入 2 个时间区间,便可得出当前时间是否在该时间区间范围内: 您可以一键复制,直接粘贴到您的项目中。 您只需要传入开始时

    2024年02月16日
    浏览(60)
  • jQuery.js - 前端必备的Javascript库

    作者: WangMin 格言: 努力做好自己喜欢的每一件事 jQuery.js 是什么? jQuery是一个快速简洁、免费开源易用的JavaScript框架, 倡导写更少的代码,做更多的事情 。它封装JavaScript常用的功能代码,提供了一种简便的JavaScript设计模式,以及我们开发中常用到的操作DOM的API,优化HTML文

    2024年02月05日
    浏览(69)
  • web前端框架JS学习之JavaScript类型转换

    vascript有多种数据类型,如字符串、数字、布尔等,可以通过typeof语句来查看变量的数据类型。数据类型转换就是数据类型之间相互转换,比如把数字转成字符串、把布尔值转成字符串、把字符串转成数字等,这在工作也是经常碰到的。 本期我们就给大家说说web前端框架JS学

    2024年02月10日
    浏览(59)
  • 【前端灵魂脚本语言JavaScript⑤】——JS中数组的使用

    🐚 作者: 阿伟 💂 个人主页: Flyme awei 🐋 希望大家多多支持😘一起进步呀! 💬 文章对你有帮助👉关注✨点赞👍收藏📂 第一种: var 数组名 = new Array(); 创建一个空数组 第二种: var arr2 = new Array(10); 创建一个定长为10的数组 第三种 var arr3 = new Array(a,b,c); 创建时直接指定元素值

    2023年04月08日
    浏览(58)
  • 〖大前端 - 基础入门三大核心之JS篇㉓〗- JavaScript 的「数组」

    当前子专栏 基础入门三大核心篇 是免费开放阶段 。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费开放 , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:除了通过订阅\\\"白宝书系列专

    2024年02月04日
    浏览(67)
  • [前端系列第3弹]JS入门教程:从零开始学习JavaScript

    本文将带领大家,从零开始学习JavaScript,fighting~ 目录 一、JavaScript简介 二、变量和数据类型 三、注释和分号 四、算术运算符 五、表达式和语句 六、代码块和作用域 七、函数(最重要)          JavaScript(简称JS)是一种运行在浏览器中的脚本语言,它可以让网页变得

    2024年02月13日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包