Vuex 数据状态

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。通俗说Vuex 可以处理共享数据,多个组件同一份数据的操作。

Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

  3. 数据的异步,本地存储,外部数据的操作,使用 (dispatch) action

 

定义vuex 调用文件 config.js

import vuex from "vuex"; // 导入
// 安装
Vue.use(vuex);
//创建
var store=new vuex.Store({
    state:{
        channels:{
            data:[],
            isLoading:false,
        },
        loginUser:[
            data:[],
            isLogin:false,
        ]
    }
});
export default store;

 如果多个数据,模块定义比较清晰

命名空间:默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

// channels.js 文件
export default{
    //通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
    namespaced:true,// 开启命名空间
    state:{
        data:[],
        isLoading:false,
    },
    mutations:{ // 唯一可以数据变化的地方,不可有副作用
        // state 原来的状态 payload 负荷
        setData(state,payload){
            state.data=payload;
        }
    },
    actions:{
        //可有副作用  外部数据,异步,本地存储
        fetchData(context){
       // 发送远程请求获取数据
            var getData=getNewList(); // import getNewList form ../server/new;
            //context 是当前命名空间, commit 触发 mutations 里的方法 , *.vue文件中js调用当前方法 this.$store.dispatch('channels/fetchData');
            context.commit("setData",getNewList)
        }
    }
};

//-------------------------------------------------------------------------------------
// config.js 文件,
import channels from 'channels'
var store=new vuex.Store({
    modules:{
        //a:channels 或者使用下面的方式,等同于 channels:channels
        channels
    }
});
export default store;

 

channels.vue  模板中获取共享数据

//模板中直接 读取仓库数据
{{$store.state.channels.data}}
//组件中使用仓库数据

// 单独直接调用,比较繁琐
export default{
    computed:{
        data(){
            return this.$store.state.channels.data
        }
    }
}
// 使用 mapState 辅助函数 处理 属性
import {mapState} from 'vuex';
//  直接调用
export default{
    computed:mapState("channels",["data","isLoading"]);
}
// 或者 传一个字符串数组
var computed:mapState("channels",["data","isLoading"]);
computed.abc=function(){
    result 123;
}
export default{
    computed,
}
// 或者 对象展开运算符,与局部计算属性混合使用
export default{
    computed:{
        ...mapState("channels",["data","isLoading"]),
        abc(){
            return 123;
        }
    },
    created(){
        // 调用更新仓库数据 命名空间,新的数据
        this.$store.commit('channels/setData',[1,2,3]);
        // 触发  仓库 actions
        this.$store.dispatch('channels/fetchData');
    }
}

 

“getter” 对 store 属性处理

getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    // Getter 接受当前 state 作为其第一个参数 
    doneTodos: state => {
     // 处理属性数据
      return state.todos.filter(todo => todo.done)
    },
    // Getter 也可以接受其他 getter 作为第二个参数
    doneTodosCount: (state, getters) => {
       return getters.doneTodos.length
    },
    // 通过方法访问
    getTodoById: (state) => (id) => {
        return state.todos.find(todo => todo.id === id)
    }
  }
});

// *.vue js 中访问属性,Getter 会暴露为 store.getters 对象
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
store.getters.doneTodosCount // -> 1
// 在任何组件中使用它
computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}
// 通过方法访问的调用,注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:

const moduleA = {
  // ...
  getters: {
    sumWithRootCount (state, getters, rootState) {
      return state.count + rootState.count
    }
  }
}

 

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性

// *.vue js 中使用
import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
     // 将一个 getter 属性另取一个名字,使用对象形式,把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
     doneCount: 'doneTodosCount'
      // ...
    ])
  }
}

 

posted @ 2020-08-03 11:32  柔和的天空  阅读(317)  评论(0编辑  收藏  举报