深入Vue底层,手写一个vuex

简介: 笔记

1. Vuex是什么?什么场景下使用?


Vuex是vue的一个插件,叫做状态管理模式,全局共享某一些状态

通俗来讲,当各组件需要共享某一组状态的时候,会用到Vuex,兄弟组件及跨级组件传值也可以派上用场(如果数据量不大,或者组件状态不需要共享也可以用中央信息插件event-bus)


2. Vuex的基本使用


vue-cli 4.0 以上,在搭建脚手架的时候选择此项就可以

项目搭建完成,便会在src文件夹下看到一个store,这就是自动生成的仓库

以下是vuex的一些基本操作,供参考:

import Vue from 'vue'
import Vuex from 'vuex'  
Vue.use(Vuex)
export default new Vuex.Store({   
  state: {  
    name: 'Vuex',
    age: 18
  },
  // 可以看做vuex的计算属性
  getters: {
    addName(state) {
      return `${state.name}牛逼`
    }
  },
  // 提交数据更改
  mutations: {    
    syncAdd(state, payload){
      state.age += payload
    },
    syncReduce(state, payload){
      state.age -= payload
    }
  },
  // 处理异步,此处为异步提交数据
  actions: {  
    asyncReduce({commit}, payload) { 
      setTimeout( () => {
        commit('syncReduce', payload)
      }, 1000)
    }
  },
  // 管理多个模块,当vuex比较大的时候会用到
  modules: {
  }
})
  • vue组件中的调用
<template>
  <div id="app">
    <h2>{{$store.state.name}}</h2>
    <div>{{$store.getters.addName}}</div>
    <div>年龄: {{$store.state.age}}</div>
    <div><button @click="add()">加10</button></div>
    <div><button @click="reduce()">减10-异步</button></div>
  </div>
</template>
<script>
export default {
  mounted () {
    // 这里可以访问到 vuex中的整个store
    console.log(this.$store)
  },
  methods: {
    // 同步加10
    add(){
      this.$store.commit('syncAdd', 10)
    },
    // 异步减2
    reduce() {
      // 会去找对应的action
      this.$store.dispatch('asyncReduce', 2)
    }
  }
}
</script>


3. 手写一个vuex


  • 从以上的应用,便可以反推出Vuex的基本源码
let Vue;
class Store {
    constructor(options = {}) {
        // 实现响应式 核心(刚刚直接拿过用户的数组放上去,是没有响应式的)
        this.s = new Vue({
            data() {
                return { state: options.state }
            }
        })
        // 将用户传入的getters放到store实例之上
        let getters = options.getters
        this.getters = {} 
        // 通过循环,拿出键值,绑定访问器属性get 劫持对象的所有属性
        Object.keys(getters).forEach((getterName) => {
            Object.defineProperty(this.getters,
            getterName, {
                get: () => {
                    // 执行此函数
                    return getters[getterName](this.state) 
                }
            })
        })
        // 获取所有同步更新的操作方法
        let mutations = options.mutations 
        // 放到实例上去
        this.mutations = {}
        // 订阅,下面commit是发布
        Object.keys(mutations).forEach( (mutationName)=> {
            // 当前实例上,通过名找方法
            this.mutations[mutationName] = (payload) =>{
                // 内部的第一参数是状态
                mutations[mutationName](this.state, payload)
            }
        })
        let actions = options.actions
        this.actions = {}
        forEachFn(actions, (actionName, fn) => {
            this.actions[actionName] = (payload) => {
                // fn 是这个玩意 asyncReduce
                fn(this, payload)
            }
        })
    }
    // 提交更改,在当前store找到对应函数执行,通过名字找  发布
    commit = (mutationName, payload) => {
        this.mutations[mutationName](payload)
    }
    // action 分发的方法
    dispatch = (actionName, payload) => {
        this.actions[actionName](payload)
    }
    // 为了方便取值
    get state() {
        return this.s.state
    }
}
const install = (_Vue) => {
    Vue = _Vue 
    Vue.mixin({
        beforeCreate() {
            console.log('beforeCreate')
            if (this.$options && this.$options.store) {       // 根实例
                // 根实例增加$store属性
                this.$store = this.$options.store
            } else {
                this.$store = this.$parent && this.$parent.$store
            }
        }
    })
}
export default {
    install, 
    Store
}
  • 总体思路就是在Vue实例上挂上一个store实例,使用Vue提供的install方法注入,之后将用户传入的都绑定上去即可
目录
相关文章
|
25天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
27天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
1天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
28天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
32 1
vue学习第一章
|
28天前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
26 1
vue学习第三章
|
28天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
35 1
vue学习第四章
|
25天前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
22 1
|
25天前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
27 1
|
25天前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
25天前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能