【Vue】集中式状态管理插件——Vuex


组件间非完全独立,在很多情况下需进行数据交互,当多个组件共享一个数据时,该数据的定义、改变,通常定义在他们的父组件中。由于存在多组件嵌套、兄弟间通信,操作相对繁琐。故对组件的共享状态抽取,全局单例,进行集中式管理。
Vuex:对 vue 应用中多个组件的共享状态进行集中式的管理(读/写)

流程

在这里插入图片描述
将Vue组件中的事件请求分发给actions对象中的事件回调函数,以commit提交的方式来触发mutations对象中state更新方法的调用,进而更新状态对象state,再以直接或计算属性(getters中定义)的方式映射回Vue视图

在这里插入图片描述
Actions对象中可包含异步代码(定时器, ajax)

应用

在这里插入图片描述

main.js:入口JS

import Vue from 'vue'
import APP from "./App"
import "./base.css"  //全局的样式
import store from "./store"  //自动匹配下面的index.js
// 创建vm
new Vue({
    
    
  el: '#app',
  components: {
    
    App}, // 映射组件标签
  template: '<App/>', // 指定需要渲染到页面的模板
  store // 所有的组件对象都多了一个属性: $store(值就是store对象)
})

创建vm方式2:

new Vue({
    
    
  el: "#app",
  render: h => h(APP), // =>函数的参数是 h(也是函数) 返回 h(APP)的结果
  store
});

index.js:vuex核心管理模块store对象

import Vue from "vue"
import Vuex from "vuex"

import actions from "./actions"
import mutations from "./mutations"
import state from "./state"
import getters from "./getters"

Vue.use(Vuex); //引入插件

export default new Vuex.Store({
    
      //export是对外暴露
  state,
  getters,
  actions,
  mutations
})

state.js:状态对象模块

export default {
    
    
  items:[]
}

App.vue中在mounted中分发本地保存数据请求事件

      mounted() {
    
    
        this.$store.dispatch("requestItems"); 
        //名称requestItems和参数决定actions对象中对应的事件回调
      }

actions.js:包含n个用于间接更新状态的方法的对象模块

import {
    
    ADD_ITEM,DEL_ITEM,SEL_ALL,DEL_COMPLETED,REQUEST_ITEMS} from "./mutation-types"
export default {
    
    
  requestItems({
    
    commit}) {
    
    
    commit(REQUEST_ITEMS);//该名称常量REQUEST_ITEMS定义是为保持与mutations方法名一致
  },
  delItem({
    
    commit},index) {
    
    
    commit(DEL_ITEM, {
    
    index});  //参数需要以对象形式进行传递  {参数}
  }
  。。。
}

mutations.js:包含n个用于直接更新状态的方法的对象模块

import {
    
    ADD_ITEM,DEL_ITEM,SEL_ALL,DEL_COMPLETED,REQUEST_ITEMS} from "./mutation-types"
import storageUtil from "../utils/storageUtil"
export default {
    
    
  [REQUEST_ITEMS](state) {
    
     // []的意义在于方法名REQUEST_ITEMS对应的变量request_items
    state.items = storageUtil.readItems();
  },
  [SEL_ALL](state, {
    
    value}) {
    
     //这里的value为true/false
    state.items.forEach(item => item.state=value)
  }
  。。。
}

mutation-types.js:包含n个mutation名称常量

export const REQUEST_ITEMS = "request_items"; //注意需要export
export const ADD_ITEM = "add_item";  
export const DEL_ITEM = "del_item";
。。。

getters.js:包含n个基于state的getter计算属性方法的对象模块

export default {
    
    
  completedSize(state) {
    
    
    const items = state.items;
    return items.reduce((preTotal,item)=>preTotal+(item.state?1:0),0)
  },
  isAllState(state,getters) {
    
     //可以传参state,getters等
      return getters.completedSize === state.items.length && state.items.length > 0;
  }
}

TodoFoot.vue

    <label>
      <input type="checkbox" v-model="isAllState"/> //配合get set双向绑定
    </label>
    <span>已选中{
    
    {
    
    completedSize}}/ 全部{
    
    {
    
    items.length}}</span>
    。。。
import {
    
    mapState,mapGetters,mapActions} from "vuex"
。。。
      computed: {
    
    
        ...mapState(["items"]),   //计算属性作为组件本身的属性,可以监视其变化
        ...mapGetters(["completedSize"]) //简化调用,completedSize就好,要不太复杂:this.$store.getters.completedSize
        // 
      },
      //methods:{ //"increment"即用increment调用对应actions中的increment方法
      //...mapActions(["increment","decrement","oddIncrement","synIncrement"])
      //},
      isAllState: {
    
    
          get() {
    
    
            return this.$store.getters.isAllState;
          },
          set(value) {
    
    
            // this.selAll(value);
            this.$store.dispatch("selAll", value);
          }
        }
      },
      watch:{
    
      //深度监视
        items:{
    
       //computed中的...mapState(["items"])引入该属性
          deep:true,
          handler: storageUtil.saveItems  //
        }
      }

storageUtil.js

/*
向local中存储数据的工具模块
1. 向外暴露一个函数(功能)  只有一个功能需要暴露
export function xxx() {

}
2. 向外暴露一个对象(包含多个功能)  有多个功能需要暴露
 */
const ITEMS_KEY = "Items_key";  //为维持存取键值一致
export default {
    
    
  saveItems(Items) {
    
    
    window.localStorage.setItem(ITEMS_KEY, JSON.stringify(Items));
  },
  readItems() {
    
    
    return JSON.parse(window.localStorage.getItem(ITEMS_KEY) || "[]");
  }
}

猜你喜欢

转载自blog.csdn.net/qq_40265247/article/details/108424979