Vue Vuex

Vuex 集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以可预测的方式发生变化

核心概念

  • state: 状态中心
  • mutations: 更改状态
  • actions: 异步更改状态
  • getters: 获取状态
  • modules: 将state分成多个modules,便于管理
  1. 状态 - state

state保存应用状态

export default new Vuex.Store({ state: { counter:0 },})
  1. 状态变更 - mutations

mutations用于修改状态,store.js

export default new Vuex.Store({
    mutations:
    {
      add(state) {
        state.counter++
      }
    }
  })
  1. 派生状态 - getters

从state派生出新状态,类似计算属性

export default new Vuex.Store({
    getters:
    {
      doubleCounter(state) { // 计算剩余数量 return state.counter * 2;
      }
    }
  })
  1. 动作 - actions

加业务逻辑,类似于controller

export default new Vuex.Store({
    actions:
    {
      add({
        commit
      }) {
        setTimeout(() = >{}
      }
    })

测试代码:

<p @click="$store.commit('add')">counter: {{$store.state.counter}}</p>
<p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p>
<p>double:{{$store.getters.doubleCounter}}</p>

vuex原理解析

  • 实现一个插件:声明Store类,挂载$store
  • Store具体实现:
    • 创建响应式的state,保存mutationsactionsgetters
    • 实现commit根据用户传入type执行对应mutation
    • 实现dispatch根据用户传入type执行对应action,同时传递上下文
    • 实现getters,按照getters定义对state做派生
// 目标1:实现Store类,管理state(响应式的),commit方法和dispatch方法
// 目标2:封装一个插件,使用更容易使用
let Vue;

class Store {
  constructor(options) {
    // 定义响应式的state
    // this.$store.state.xx
    // 借鸡生蛋
    this._vm = new Vue({
      data: {
        $$state: options.state
      }
    })
    
    this._mutations = options.mutations
    this._actions = options.actions

    // 绑定this指向
    this.commit = this.commit.bind(this)
    this.dispatch = this.dispatch.bind(this)
  }

  // 只读
  get state() {
    return this._vm._data.$$state
  }

  set state(val) {
    console.error('不能直接赋值呀,请换别的方式!!天王盖地虎!!');
    
  }
  
  // 实现commit方法,可以修改state
  commit(type, payload) {
    // 拿出mutations中的处理函数执行它
    const entry = this._mutations[type]
    if (!entry) {
      console.error('未知mutaion类型');
      return
    }

    entry(this.state, payload)
  }

  dispatch(type, payload) {
    const entry = this._actions[type]

    if (!entry) {
      console.error('未知action类型');
      return
    }

    // 上下文可以传递当前store实例进去即可
    entry(this, payload)
  }
}

function install(_Vue){
  Vue = _Vue

  // 混入store实例
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

// { Store, install }相当于Vuex
// 它必须实现install方法
export default { Store, install }
### VueVuex 的集成与使用方法 #### 集成过程概述 为了实现 VueVuex 的集成,通常需要完成以下几个主要步骤: 1. **创建 `store` 文件夹并初始化核心文件** 在项目的根目录下创建一个名为 `store` 的文件夹,并在其内部建立 `index.js` 文件作为 Vuex Store 的入口点。此文件用于定义全局状态管理逻辑。 2. **配置 Vuex Store 并挂载到 Vue 实例上** 将 Vuex Store 导入到 `main.js` 中,并通过 Vue 构造器将其注入整个应用上下文中。 3. **编写具体的 State、Mutations、Actions 及 Getters 定义** 这些部分分别负责存储数据、修改数据、处理异步操作以及计算派生状态。 4. **在组件中调用 Vuex 功能** 组件可以通过特定语法访问或更新 Vuex 中的状态。 --- #### 示例代码展示 以下是基于上述流程的一个完整示例: ##### 1. 创建 `store/index.js` ```javascript import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const state = { count: 0, }; const mutations = { increment(state) { state.count++; }, }; const actions = { incrementAsync({ commit }) { setTimeout(() => { commit('increment'); }, 1000); }, }; const getters = { doubleCount: (state) => state.count * 2, }; export default new Vuex.Store({ state, mutations, actions, getters, }); ``` 此处展示了如何设置基础的 `state`, `mutations`, `actions`, 和 `getters`[^2]。 ##### 2. 修改 `main.js` 来引入 Store ```javascript import Vue from 'vue'; import App from './App.vue'; import store from './store'; // 引入刚刚创建好的 store new Vue({ render: (h) => h(App), store, // 注册 store 到 vue 应用实例中 }).$mount('#app'); ``` 这一步确保了 Vuex Store 被成功注册到了 Vue 应用程序之中[^1]。 ##### 3. 在组件中使用 Vuex 下面是一个简单的组件例子,演示如何读取和更改 Vuex 状态: ```html <template> <div> <p>当前计数:{{ count }}</p> <button @click="increment">增加</button> <button @click="asyncIncrement">延迟增加</button> </div> </template> <script> import { mapState, mapGetters, mapActions } from 'vuex'; export default { computed: { ...mapState(['count']), ...mapGetters(['doubleCount']), }, methods: { ...mapActions(['increment', 'incrementAsync']), asyncIncrement() { this.incrementAsync(); }, }, }; </script> ``` 这里利用了辅助函数 `mapState`, `mapGetters`, 和 `mapActions` 提高开发效率[^4]。 --- #### 关于 Actions 参数中的 Context 对象 当我们在定义 Action 方法时,第一个参数总是被命名为 context 或类似的名称。这个对象包含了多个属性和方法,其中就包括 dispatch 方法。它允许我们触发其他 action,从而支持复杂的业务场景下的链式调用。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码哥・Martin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值