深入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方法注入,之后将用户传入的都绑定上去即可
目录
相关文章
|
8天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
8天前
|
缓存 JavaScript 搜索推荐
Vue SSR(服务端渲染)预渲染的工作原理
【10月更文挑战第23天】Vue SSR 预渲染通过一系列复杂的步骤和机制,实现了在服务器端生成静态 HTML 页面的目标。它为提升 Vue 应用的性能、SEO 效果以及用户体验提供了有力的支持。随着技术的不断发展,Vue SSR 预渲染技术也将不断完善和创新,以适应不断变化的互联网环境和用户需求。
27 9
|
7天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。
|
6天前
|
JavaScript
如何在 Vue 中使用具名插槽
【10月更文挑战第25天】通过使用具名插槽,你可以更好地组织和定制组件的模板结构,使组件更具灵活性和可复用性。同时,具名插槽也有助于提高代码的可读性和可维护性。
13 2
|
6天前
|
JavaScript
Vue 中的插槽
【10月更文挑战第25天】插槽的使用可以大大提高组件的复用性和灵活性,使你能够根据具体需求在组件中插入不同的内容,同时保持组件的结构和样式的一致性。
11 2
|
6天前
|
前端开发 JavaScript 容器
在 vite+vue 中使用@originjs/vite-plugin-federation 模块联邦
【10月更文挑战第25天】模块联邦是一种强大的技术,它允许将不同的微前端模块组合在一起,形成一个统一的应用。在 vite+vue 项目中,使用@originjs/vite-plugin-federation 模块联邦可以实现高效的模块共享和组合。通过本文的介绍,相信你已经了解了如何在 vite+vue 项目中使用@originjs/vite-plugin-federation 模块联邦,包括安装、配置和使用等方面。在实际开发中,你可以根据自己的需求和项目的特点,灵活地使用模块联邦,提高项目的可维护性和扩展性。
|
7天前
|
JavaScript 前端开发 UED
vue 提高 tree shaking 的效果
【10月更文挑战第23天】提高 Vue 中 Tree shaking 的效果需要综合考虑多个因素,包括模块的导出和引用方式、打包工具配置、代码结构等。通过不断地优化和调整,可以最大限度地发挥 Tree shaking 的优势,为 Vue 项目带来更好的性能和用户体验。
|
7天前
|
缓存 JavaScript UED
Vue 中异步加载模块的方式
【10月更文挑战第23天】这些异步加载模块的方式各有特点和适用场景,可以根据项目的需求和架构选择合适的方法来实现模块的异步加载,以提高应用的性能和用户体验
|
7天前
|
JavaScript 测试技术 UED
解决 Vue 项目中 Tree shaking 无法去除某些模块
【10月更文挑战第23天】解决 Vue 项目中 Tree shaking 无法去除某些模块的问题需要综合考虑多种因素,通过仔细分析、排查和优化,逐步提高 Tree shaking 的效果,为项目带来更好的性能和用户体验。同时,持续关注和学习相关技术的发展,不断探索新的解决方案,以适应不断变化的项目需求。
|
8天前
|
JavaScript 搜索推荐 前端开发
Vue SSR 预渲染的广泛应用场景及其优势
【10月更文挑战第23天】Vue SSR 预渲染技术在众多领域都有着广泛的应用价值,可以显著提升网站的性能、用户体验和搜索引擎优化效果。随着技术的不断发展和完善,其应用场景还将不断拓展和深化
22 2