五、vuex

1惭载、VueX的介紹與作用解析

VueX:是一個專門為vue.js應用程序開發(fā)的狀態(tài)管理模式

1)旱函、它采用集中式存儲管理應用的所有組件的狀態(tài),并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化描滔。

2)棒妨、VueX也集成了Vue的官方調(diào)試工具 devtools extension,提供了諸如零配置的time-travel 調(diào)試含长、狀態(tài)快照導入導出等高級調(diào)試功能券腔。

狀態(tài)管理是什么?

狀態(tài)管理模式拘泞、集中式存儲管理這些名字有點高大上纷纫,讓人找摸不透。其實你可以簡單的將其看成把需要多個組件共享的變量全部存儲到一個對象里面陪腌;然后涛酗,將這個對象放在頂層的Vue實例中,讓其他組件可以使用偷厦;

應用場景:

用戶的登錄狀態(tài)商叹、用戶名稱、用戶頭像等

1.1只泼、vux 單界面到多界面狀態(tài)管理切換

安裝Vuex命令:

npm install vuex --save

示例代碼如下:

1)剖笙、配置vuex,一般會新建一個文件夾请唱,獨立管理vuex配置:新建文件夾 store/index.js

import Vue from 'vue';
import Vuex from 'vuex'
//安裝插件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state :{
    num:0
  },
  mutations:{
    //方法
    addition(state){
      state.num++;
    },
    subtract(state){
      state.num--;
    }
  },
  actions:{},
  getters:{},
  modules:{}
});
//導出
export default store;

2)弥咪、在main.js中進行掛載

import store  from "./store";
new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

3)、新建組件 Index.vue

<template>
  <div>
    <span> {{ this.$store.state.num }}</span><br>
     <button @click="Add">+</button>
     <button @click="Subtract">-</button>
  </div>
</template>

<script>
export default {
  name: "Index",
  methods:{
    Add(){
      this.$store.state.num++;
    },
    Subtract(){
      this.$store.state.num--;
    }
  }
}
</script>

<style scoped>

</style>

4)十绑、新建組件 Info.vue 聚至,代碼如下:

<template>
<div>
  <span>{{ this.$store.state.num }}</span><br>
</div>
</template>

<script>
export default {
  name: "Info"
}
</script>

<style scoped>

</style>

5)、在App.vue 中掛載兩個組件本橙,代碼如下:

<template>
  <div id="app">
    <Index/>
    <Info/>
  </div>
</template>

<script> 
import Index from './components/Index'
import Info from "./components/Info";
export default {
  name: 'App',
  components: {
    Index,
    Info
  }
}
</script>

<style> 
</style>

總結:

vuex 的安裝扳躬、配置以及使用狀態(tài)。

如果修改狀態(tài)值甚亭,以上的代碼是可以使用的贷币,但是官方是不建議這樣使用,因為這樣使用是無法監(jiān)聽是誰修改的這個狀態(tài)亏狰。

修改狀態(tài)值是在 mutations 進行修改狀態(tài)的值役纹,這樣就可以監(jiān)聽是誰修改的值,具體使用方法看實例代碼暇唾。

1.2促脉、Vuex-state 單一狀態(tài)樹的理解:

state:狀態(tài)值 單一狀態(tài)樹

單一狀態(tài)樹:單一數(shù)據(jù)源

mutations:修改狀態(tài)值

action:進行一些異步操作

getters:類似于組件中的計算屬性

getters的使用實例:

import Vue from 'vue';
import Vuex from 'vuex'
//安裝插件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state :{
    num:0
  },
  mutations:{
    //方法
    addition(state){
      state.num++;
    },
    subtract(state){
      state.num--;
    }
  },
  actions:{},
  //getters的使用
  getters:{
    multiply(state){
      return state.num*2;
    }
  },
  modules:{}
});
//導出
export default store;

vue調(diào)用方法:

{{this.$store.getters.multiply}}

modules :劃分模塊辰斋,根據(jù)不同的模塊進行一系列的操作

mutations的使用

更新狀態(tài)唯一的方式就是 提交 mutations 。

mutations 主要包括兩部分:

①瘸味、字符串類型事件

②宫仗、一個回調(diào)函數(shù),該毀掉函數(shù)的第一個參數(shù)是state

1)硫戈、示例代碼: store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
//安裝組件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state: {
    num: 0
  },
  mutations: {
    Add(state) {
      state.num++;
    },
    Cut(state) {
      state.num--;
    },
    AddFive(state,payload){
      console.log(payload)
      //第一種接收
      state.num = state.num + payload; 
      //第二種接收  第二個參數(shù)是一個對象
      state.num = state.num + payload.num1;
    } 
  }
});
//導出
export default store;

2)锰什、組件中調(diào)用,示例代碼:

//不傳參
this.$store.commit('mutations方法名稱');
//第一種傳參  
this.$store.commit('mutations方法名稱',參數(shù));
/第二種傳參
this.$store.commit({type:'mutations方法名稱',參數(shù) });

總結: mutations中函數(shù)傳參下硕,第一個參數(shù)state是固定的 丁逝,第二個參數(shù)是要傳遞的。

getters的使用:

getters的使用和組件中的計算屬性差不多梭姓,示例代碼如下:

import Vue from 'vue';
import Vuex from 'vuex';
//安裝組件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state: {
    num: 0
  },
  getters:{
    //不傳參 
    numAddNum(state){
      return state.num+state.num;  
    },
    //傳遞 參數(shù) 
    numAddNumParms(state,getters){
      return s =>{
         return getters.numAddNum + s;
      }
    }
  }
});
//導出
export default store;

在組件中調(diào)用霜幼,示例代碼如下:

<!--不傳參-->
<div>這是getters計算的值:{{this.$store.getters.numAddNum}}</div>
<!--傳遞參數(shù)-->
<div>這是getters傳參計算的值:{{this.$store.getters.numAddNumParms(2)}}</div>

Mutation 的響應規(guī)則

響應規(guī)則:

①、提前store中初始化屬性誉尖。

②罪既、當給state 中的對象添加新屬性時,使用下面的方式:

方式1:使用Vue.set(obj,'newProp',123)

方式2:用新對象給舊對象重新賦值

示例代碼如下: store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
//安裝組件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state: { 
    student:[
      {id:1,name:'xiaoming',sex:'男'},
      {id:2,name:'xiaogang',sex:'女'}
    ]
  },
  mutations: { 
    AddProperty(state) {
      console.log("添加對象屬性");
      Vue.set(state.student[0], 'adress', '12312');
    }
  } 
});
//導出
export default store;

組件中調(diào)用铡恕,示例代碼如下:

<div>這是student對象值:{{this.$store.state.student}}</div>
<button @click="AddProperty">添加student對象屬性</button>
<script>
export default {
   name:'Index',
   methods:{ 
     AddProperty(){
        this.$store.commit('AddProperty');
     }
   }
}
</script>

mutation的類型常量

由于項目越來越大琢感,mutation中的方法越來越多,為了更好的管理這些方法探熔,可以將這些方法名單獨抽出文件來進行管理驹针。

①、 示例代碼如下:新建 mutation-types/index.js

export  const  ADDPROPERTY = 'AddProperty'

②诀艰、在store/index.js文件中導入文件柬甥,示例代碼:

import Vue from 'vue';
import Vuex from 'vuex';
import * as types from '../mutation_types'
//安裝組件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state: {
    num: 0,
    student:[
      {id:1,name:'xiaoming',sex:'男'},
      {id:2,name:'xiaogang',sex:'女'}
    ]
  },
  mutations: { 
    [types.ADDPROPERTY](state) {
      console.log("添加對象屬性");
      Vue.set(state.student[0], 'adress', '12312');
    }
  }
});
//導出
export default store;

③、在組件中調(diào)用其垄,示例代碼如下:

  <div>這是student對象值:{{this.$store.state.student}}</div>
  <button @click="AddProperty">添加student對象屬性</button>
 <script>
import * as types from '../mutation_types'
export default {
   name:'Index',
   methods:{ 
     AddProperty(){
        this.$store.commit(types.ADDPROPERTY);
     }
   }
}
</script>

Vuex-Action 的基本使用

Action主要應用于異步苛蒲,同步方法在Mutation中進行定義。

基本使用:在store/index.js 示例代碼:

import Vue from 'vue';
import Vuex from 'vuex';
import * as types from '../mutation_types'
//安裝組件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state: {
    num: 0,
    student:[
      {id:1,name:'xiaoming',sex:'男'},
      {id:2,name:'xiaogang',sex:'女'}
    ]
  },
  mutations: { 
    [types.ADDPROPERTY](state) {
      console.log("添加對象屬性");
      Vue.set(state.student[0], 'adress', '12312');
    }
  }, 
  actions:{//用于一步操作
    aUpdata(context){
      setTimeout(() => {
        console.log('執(zhí)行異步操作');
        //異步操作在Actions中進行绿满,但是修改值必須經(jīng)過mutation
        context.commit(types.ADDPROPERTY);
      }, 2000);
    }
  }
});
//導出
export default store;

在組建中調(diào)用臂外,示例代碼:

<div>這是student對象值:{{this.$store.state.student}}</div>
<button @click="AddPropertyAsync">異步操作添加student對象屬性</button>
<script>
import * as types from '../mutation_types'
export default {
   name:'Index',
   methods:{  
     AddPropertyAsync(){
        this.$store.dispatch('aUpdata');
     }
   }
}
</script>

總結:

異步操作必須在Actions中進行操作,但是修改的值必須經(jīng)過Mutation喇颁。

Actions 與 Promise 結合使用寄月,示例代碼:

import Vue from 'vue';
import Vuex from 'vuex';
import * as types from '../mutation_types'
//安裝組件
Vue.use(Vuex);
//創(chuàng)建對象
const store = new Vuex.Store({
  state: {
    num: 0,
    student:[
      {id:1,name:'xiaoming',sex:'男'},
      {id:2,name:'xiaogang',sex:'女'}
    ]
  },
  mutations: { 
    [types.ADDPROPERTY](state) {
      console.log("添加對象屬性");
      Vue.set(state.student[0], 'adress', '12312');
    }
  }, 
  actions:{  
    aUpdata(context){
      return new Promise((resolve, reject) => {
        console.log('執(zhí)行異步操作');
        context.commit(types.ADDPROPERTY);
        resolve('Ok');
      });
    }
  }
});
//導出
export default store;

組件中調(diào)用,示例代碼如下:

<div>這是student對象值:{{this.$store.state.student}}</div>
<button @click="AddPropertyAsync">異步操作添加student對象屬性</button>
<script>
import * as types from '../mutation_types'
export default {
   name:'Index',
   methods:{ 
     AddProperty(){
        this.$store.commit(types.ADDPROPERTY);
     }, 
      AddPropertyAsync(){
        this.$store.dispatch('aUpdata').then((res)=>{
            console.log('執(zhí)行成功');
            console.log(res);
        });
     }
   }
}
</script>

modules的基本使用:

Vue使用單一狀態(tài)樹,那么也意味著有很多狀態(tài)都得需要交給Vuex來管理无牵,當應用變的很復雜時漾肮,那么store對象會變得很臃腫,為了解決這個問題茎毁,vuex允許我們將store分割成很多模塊克懊,每個模塊都有自己的 state actions getters mutations忱辅。

示例代碼如下: store/index.js

import Vue from 'vue';
import Vuex from 'vuex';

//安裝 
Vue.use(Vuex);

const TestModule = {
  state: {
    num: 0,
    payload:0,
    name:'小剛'
  },
  mutations: {
    add(state) {
      state.num++;
    },
    subtraction(state) {
      state.num--;
    },
    parms(state,payload){
      state.payload = payload;
    }
  },
  getters:{
    fullname(state){
     return  state.name = '李'+state.name;
    },
    fullname1(state,getters){
      return  getters.fullname+2222;
     },
     fullname2(state,getters,rootState){
      return  getters.fullname1+rootState.rootname;
     }
  },
  actions:{
     updateNameAsync(context){
        setTimeout(()=>{
          context.commit('parms',"再見");
          context.commit('updaterootName');
          context.rootGetters.test ('開發(fā)');
          console.log(context);
        },1000);
     }
  }
};

//創(chuàng)建對象并導出對象
export default new Vuex.Store({
  state:{
    rootname:'fuck'
  },
  mutations:{
    updaterootName(state)
    {
      state.rootname = "you";
    }
  },
  modules: {
    TestModule
  },
  getters:{
    test(state,getters)
    {
     return (s)=>{
        return state.rootname = s;
     }
    }
  }
});

組件中調(diào)用谭溉,示例代碼如下:

<template>
  <div class="hello">
    <h2>TestModule 的 state狀態(tài)值:{{this.$store.state.TestModule.num}}</h2>
    <h2>TestModule 的 mutations 參數(shù)傳值:{{this.$store.state.TestModule.payload}}</h2>
    <h2>TestModule 的 getters無參值:{{this.$store.getters.fullname}}</h2>
    <h2>TestModule 的 使用getters參數(shù)獲取fullname函數(shù)在拼接值:{{this.$store.getters.fullname1}}</h2>
    <h2>TestModule 的 使用rootgetters參數(shù)獲取根getter中的函數(shù)在拼接值:{{this.$store.getters.fullname2}}</h2>
    <div>
      <button @click="add">+</button>
      <button @click="subtraction">-</button>
       <button @click="parms">Mutations 傳值</button>
        <button @click="updateAsync">異步修改</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods:{
    add(){
      this.$store.commit('add');
    },
    subtraction(){
      this.$store.commit('subtraction')
    },
    parms(){
      console.log(this.$store.commit('parms',4)); 
    },
    updateAsync(){
      this.$store.dispatch('updateNameAsync');
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

總結:

getters中可以調(diào)用根中state對象 關鍵字:rootstate

actions中的context參數(shù)也可以調(diào)用根中的rootGetters墙懂、rootstate、mutations扮念,詳細看以上代碼损搬。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市柜与,隨后出現(xiàn)的幾起案子巧勤,更是在濱河造成了極大的恐慌,老刑警劉巖弄匕,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颅悉,死亡現(xiàn)場離奇詭異,居然都是意外死亡迁匠,警方通過查閱死者的電腦和手機剩瓶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來城丧,“玉大人延曙,你說我怎么就攤上這事⊥龊澹” “怎么了枝缔?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長磺平。 經(jīng)常有香客問我魂仍,道長,這世上最難降的妖魔是什么拣挪? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任擦酌,我火速辦了婚禮,結果婚禮上菠劝,老公的妹妹穿的比我還像新娘赊舶。我一直安慰自己,他們只是感情好赶诊,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布笼平。 她就那樣靜靜地躺著,像睡著了一般舔痪。 火紅的嫁衣襯著肌膚如雪寓调。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天锄码,我揣著相機與錄音夺英,去河邊找鬼晌涕。 笑死,一個胖子當著我的面吹牛痛悯,可吹牛的內(nèi)容都是我干的余黎。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼载萌,長吁一口氣:“原來是場噩夢啊……” “哼惧财!你這毒婦竟也來了?” 一聲冷哼從身側響起扭仁,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤垮衷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后斋枢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帘靡,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡知给,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年瓤帚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涩赢。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡戈次,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出筒扒,到底是詐尸還是另有隱情怯邪,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布花墩,位于F島的核電站悬秉,受9級特大地震影響,放射性物質發(fā)生泄漏冰蘑。R本人自食惡果不足惜和泌,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祠肥。 院中可真熱鬧武氓,春花似錦、人聲如沸仇箱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剂桥。三九已至忠烛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間权逗,已是汗流浹背美尸。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工垒拢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人火惊。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓求类,卻偏偏與公主長得像,于是被迫代替她去往敵國和親屹耐。 傳聞我的和親對象是個殘疾皇子尸疆,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Vuex 是什么? ** 官方解釋:Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式**惶岭。它采用集中...
    Rz______閱讀 2,308評論 1 10
  • 一寿弱、Vuex是什么 Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應用的所有...
    尋找夢的豬豬閱讀 274評論 0 0
  • Vuex[https://vuex.vuejs.org/zh/] 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理...
    lio_zero閱讀 476評論 1 6
  • 學習目的 了解和熟練使用 VueX按灶,能夠在實際項目中運用症革。 VueX介紹 Vuex 是一個專為 Vue.js ...
    _1633_閱讀 2,799評論 0 7
  • 目錄 Vue組件間通信方式回顧組件內(nèi)的狀態(tài)管理流程組件間通信方式父組件給子組件傳值 (最簡單的一種方式)子組件給父...
    頑皮的雪狐七七閱讀 722評論 0 3