[Vue] 08 - Vuex
解决不同组件间的数据共享,数据持久化。
https://www.bilibili.com/video/BV1zt411e7fp?p=29
过去是,父子组件通信:[Vue] 04 - Parameter Passing
兄弟组件间的数据共享。
local storage, session storage 在哪里?
核心概念
State
Getter
Mutation
Action
Module
state & mutations
一、定义一个 store.js
(1) 增加一个vuex的文件夹;再添加一个js文件:./vuex/store.js
(2) Install vuex。
npm install vuex --save
(3) 一切都是在为实例化 vuex.store 时,为其参数做准备。形式有点类似router。
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); /*1.state在vuex中用于存储数据*/ var state={ count:1 } /*2.mutations里面放的是方法,方法主要用于改变state里面的数据 */ var mutations={ incCount(){ ++state.count; } } //vuex 实例化 Vuex.store const store = new Vuex.Store({ state, mutations }) export default store;
二、读数据 store.js
Home.vue 从 store.js 读出数据。
Home.vue中,先注册下 store,在27行。然后在第4行使用。
<template> <!-- 所有的内容要被根节点包含起来 --> <div id="home"> 我是首页组件 -- {{this.$store.state.count}} <br> <button @click="incCount()">增加数量+</button> </div> </template> <script> //1. 引入store 建议store的名字不要变 import store from '../vuex/store.js'; //2.注册 export default{ data(){ return { msg:'我是一个home组件', value1: null, } }, store, methods:{ incCount() { //改变vuex store里面的数据 this.$store.commit('incCount'); /*触发 mutations 改变 state里面的数据*/ } } } </script>
三、写数据 store.js
Home.vue 直接对 store.js 改变数据。
通过 this.$store.commit('func') 触发了 store 中的 func。
达到的效果就是:两个组件都能同步改变同一个变量(state),并使用。
getter & action
一、使用 getter
改变state的时候,会自动触发 getters里面的方法。
貌似第二行的方法也能达到第一行的效果。
<!-- 我是首页组件 -- {{this.$store.state.count}} ----{{this.$store.getters.computedCount}} --> 我是首页组件 -- {{this.$store.state.count}} ----{{this.$store.state.count*2}}
在store.js中增加了:
/*3、优点类似计算属性 , 改变state里面的count数据的时候会触发 getters里面的方法 获取新的值 (基本用不到)*/
var getters= {
computedCount: (state) => {
return state.count*2
}
}
二、使用 action
特点:
(1) 不直接改变状态,只是提交mutations。
(2) 包含任意异步操作。
点击button --> 触发 incCount() --> 继续触发 dispatch制定的action中的方法 ‘incMutationsCount'。
<script> //1. 引入store 建议store的名字不要变 import store from '../vuex/store.js'; //2.注册 export default{ data(){ return { msg:'我是一个home组件', value1: null, } }, store, methods:{ incCount(){ //改变vuex store里面的数据 //this.$store.commit('incCount'); /*触发 mutations 改变 state里面的数据*/ this.$store.dispatch('incMutationsCount'); /*触发 actions里面的方法 */ } } } </script>
store.js 中定义了 action。但action不同与mutations,其中可以执行异步。
/* 1.state在vuex中用于存储数据*/ var state={ count:1, list:[] } /* 2.mutations里面放的是方法,方法主要用于改变state里面的数据 */ var mutations={ incCount(){ ++state.count; },
addList(state, data){ state.list = data; } } /* 3、优点类似计算属性 , 改变state里面的count数据的时候会触发 getters里面的方法 获取新的值 (基本用不到)
*/ var getters= { computedCount: (state) => { return state.count*2 } } /* 4、 基本没有用 Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作。 */ var actions= { incMutationsCount(context) { /* 因此你可以调用 context.commit 提交一个 mutation*/ context.commit('incCount'); /* 执行 mutations 里面的incCount方法 改变state里面的数据*/ } }
-
action和mutations的区别
可见,另一个组件中通过methods中的dispatch()触发 --> actions中的incMutationsCount --> commit('inCount') --> mutations: inCount()
关键在于,在store.js中多了一个actions,做了一个“过度”。
methods:{ incCount(){ //改变vuex store里面的数据 //this.$store.commit('incCount'); /*触发 mutations 改变 state里面的数据*/ this.$store.dispatch('incMutationsCount'); /*触发 actions里面的方法 */ } }
之前的mutations中的方法 incCount(),是通过 另一个组件中click直接commit去触发,如下所示。
methods:{ incCount() { //改变vuex store里面的数据 this.$store.commit('incCount'); /*触发 mutations 改变 state里面的数据*/ } }
store的数据持久化
—— 数据持久化,不同模块间的数据共享。
一、判断数据是否存在
list 保存了固化的数据。
},mounted(){ //判断 store里面有没有数据 var listData=this.$store.state.list; console.log(listData.length); if(listData.length > 0){ this.list=listData; }else{ this.requestData(); } }
若没有就请求数据。(1) 放在自己这里this.list;(2) 放在store中一份以共享。
methods:{ incCount(){ this.$store.commit('incCount'); }, requestData(){ //请求数据 var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1'; this.$http.get(api).then((response)=>{ console.log(response); //注意this指向 this.list=response.body.result; //数据放在store里面 this.$store.commit('addList',response.body.result); },function(err){ console.log(err); }) }
}
二、存放在store中
注意第一个默认要写的参数state。
/*2.mutations里面放的是方法,方法主要用于改变state里面的数据 */ var mutations={ incCount(){ ++state.count; }, addList(state, data){ state.list = data; } }
End.