Vue 高級(jí)-Vuex

介紹

vuex是一種狀態(tài)管理模式传于,它保存著組件的公用的狀態(tài)碉克,并且以相應(yīng)的規(guī)則保證狀態(tài)變化。

vuex的核心就是一個(gè)store赁还,它相當(dāng)于是一個(gè)容器妖泄,里面包含有state,action,mutation,getter,modules。

  • state:用于數(shù)據(jù)的存儲(chǔ)艘策,是store中的唯一數(shù)據(jù)源

  • getters:如vue中的計(jì)算屬性一樣蹈胡,基于state數(shù)據(jù)的二次包裝,常用于數(shù)據(jù)的篩選和多個(gè)數(shù)據(jù)的相關(guān)性計(jì)算

  • mutation:類似函數(shù)朋蔫,改變state數(shù)據(jù)的唯一途徑罚渐,且不能用于處理異步事件

  • action:類似于mutation,用于提交mutation來改變狀態(tài)驯妄,而不直接變更狀態(tài)荷并,可以包含任意異步操作

  • modules:類似于命名空間,用于項(xiàng)目中將各個(gè)模塊的狀態(tài)分開定義和操作青扔,便于維護(hù)

特點(diǎn)

  • Vuex 的狀態(tài)存儲(chǔ)是響應(yīng)式的源织。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時(shí)候翩伪,若 store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新谈息。

  • 你不能直接改變 store 中的狀態(tài)缘屹。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個(gè)狀態(tài)的變化侠仇,從而讓我們能夠?qū)崿F(xiàn)一些工具幫助我們更好地了解我們的應(yīng)用囊颅。

  • vuex是單一狀態(tài)樹

vuex的流程

image.png

vuex的整體流程是:

  1. 在組件內(nèi)部,通過dispatch來分發(fā)action傅瞻。

  2. 再通過action來第調(diào)用mutation

  3. 進(jìn)而觸發(fā)mutation內(nèi)部的commit來修改state

  4. 最后state改變踢代,導(dǎo)致頁面重新render。

使用

vuex的使用場(chǎng)景

  • 大型應(yīng)用中嗅骄,用于全局共享的data,例如全局消息提醒平酿、控件權(quán)限控制等等碌冶。

  • vuex可配合sessionStorage做用戶基本信息的持久化存儲(chǔ)衅谷。

  • 多級(jí)組件的數(shù)據(jù)需要共享或多個(gè)頁面之間的數(shù)據(jù)存在因果關(guān)系時(shí)淘邻,可以使用vuex。

在state中定義了count屏积、userInfo医窿、students三個(gè)屬性,state里面的數(shù)據(jù)狀態(tài)可以在全局中被訪問,在任意組件中通過this.$store.state.attrName訪問炊林,在demo.vue的computed屬性里面姥卢,我們獲取了以上三個(gè)屬性

getter中可以自定義一些函數(shù)對(duì)state屬性里面的數(shù)據(jù)進(jìn)行過濾,并且在任意組件中可以通過this.$store.gettter.functionName的方式獲取

mutaions用來更新state里面的狀態(tài)渣聚,我們可以定義一些方法對(duì)數(shù)據(jù)進(jìn)行操作独榴,在里面的方法中至少有state和value兩個(gè)參數(shù),state就是上面所說的state對(duì)象(屬性)奕枝,value就是從組件傳遞來的值棺榔。可以看到隘道,在demo.vue中點(diǎn)擊加號(hào)按鈕或者減號(hào)按鈕症歇,通過this.$store.commit('getUserInfo',count的方式向vuex提交了一個(gè)事件,在store.js中mutaions里面的updateCount將提交過值接收并進(jìn)行處理谭梗,state里面的count狀態(tài)被更新忘晤,這是demo組件的computed屬性中的number被執(zhí)行,然后緊接著dom被更新默辨。

actions也是對(duì)state狀態(tài)進(jìn)行更新德频,但是是間接的苍息,一些異步的操作先交給actions里面的函數(shù)執(zhí)行缩幸,拿到結(jié)果后在交給mutaions中相應(yīng)的處理函數(shù)處理壹置,接下來的操作就跟上面講的一樣。 點(diǎn)擊獲取用戶信息按鈕表谊,通過this.$store.dispatch('getUserInfo',this)向vuex提交了一個(gè)事件钞护,store.js中actions的getUserInfo函數(shù)處理了這個(gè)事件,向本地一個(gè)user.json文件發(fā)了一個(gè)異步請(qǐng)求爆办,難道結(jié)果后將返回的用戶信息交給了mutaions的getUserInfo函數(shù)處理难咕,state的userInfo屬性被改變,userInfo的變化導(dǎo)致demo.vue中computed屬性的userInfo被執(zhí)行距辆,接著dom更新余佃,用戶信息被顯示。

代碼如下:

// store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
    state:{
        count:0,
        userInfo:{},
        students:[]
    },
    getters:{
      
    },
    mutations:{
        updateCount(state,count){
            state.count = count
        },
        getUserInfo(state,userInfo){
            state.userInfo = userInfo
        },
        getStudents(state,students){
            state.students = students
        }
    },
    actions:{
        updateCountAsync({commit,state},count){
            setTimeout(function() {
                console.log('count:'+count)
                commit('updateCount',count)
            }, 1000);
        },
        getUserInfo({commit,state},_this){
            let _vm = _this
            console.log(_vm)
            _vm.$http.get('http://localhost:8080/static/data/user.json').then(res=>{
                console.log(res)
                commit('getUserInfo',res.data)
            })
        },
        getStudents({commit,state},_this){
            let _vm = _this
            _vm.$http.get('/api/students').then(res=>{
                console.log(res)
                commit('getStudents',res.data.data.students)
            })
        }
    }
})
// demo.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
      
    <div class="number-box" style="margin:20px 0;">
      <button @click="plus">加 一</button>
      <input type="text" v-model="number" style="padding-left:20px;">
      <button @click="minus">減 一</button>
    </div>

    <button @click="getUserInfo">獲取用戶信息</button>
    <div class="user-info" v-if="userInfo">
      <span class="name" >{{userInfo.name}}</span>
      <span class="gender" >{{userInfo.gender}}</span>
      <span class="age">{{userInfo.age}}</span>
    </div>
    
    <button @click="getStudentList">獲取成績榜單</button>
    <div v-if="students.length>0">
      <h4 >成績榜單</h4>
      <ul>
        <li v-for="item in students" :key="item.id">
          <span>{{item.name}}</span>
          <span>{{item.score}}</span>
        </li>
      </ul>
    </div>
  </div>
</template>

<style>

</style>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  mounted() {
    
  },
  computed:{
    number(){
      return this.$store.state.count
    },
    userInfo(){
      return this.$store.state.userInfo
    },
    students(){
      return this.$store.state.students
    }
  },
  methods:{
    plus(){
      // this.number++
      let count = Number(this.number)+1
      console.log('plus:'+count)
      this.$store.dispatch('updateCountAsync',count)
    },
    minus(){
      // this.number--
      let count = Number(this.number)-1
      console.log('minus:'+count)
      this.$store.dispatch('updateCountAsync',count)
    },
    getUserInfo(){
      this.$store.dispatch('getUserInfo',this)
    },
    getStudentList(){
      this.$store.dispatch('getStudents',this)
    }
  }
}
</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;
}
.user-info{
  margin-top:20px;
  margin-bottom:20px;
}
.name{
  color:blue;margin-right:20px
}
.gender{
  color:red;margin-right:20px
}
.age{
  color:blue;margin-right:20px
}
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末跨算,一起剝皮案震驚了整個(gè)濱河市爆土,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诸蚕,老刑警劉巖步势,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異背犯,居然都是意外死亡坏瘩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門漠魏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倔矾,“玉大人,你說我怎么就攤上這事柱锹∑铺郑” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵奕纫,是天一觀的道長提陶。 經(jīng)常有香客問我,道長匹层,這世上最難降的妖魔是什么隙笆? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮升筏,結(jié)果婚禮上撑柔,老公的妹妹穿的比我還像新娘。我一直安慰自己您访,他們只是感情好铅忿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灵汪,像睡著了一般檀训。 火紅的嫁衣襯著肌膚如雪柑潦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天峻凫,我揣著相機(jī)與錄音渗鬼,去河邊找鬼。 笑死荧琼,一個(gè)胖子當(dāng)著我的面吹牛譬胎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播命锄,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼堰乔,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了脐恩?” 一聲冷哼從身側(cè)響起浩考,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎被盈,沒想到半個(gè)月后析孽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡只怎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年袜瞬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片身堡。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡邓尤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贴谎,到底是詐尸還是另有隱情汞扎,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布擅这,位于F島的核電站澈魄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仲翎。R本人自食惡果不足惜痹扇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望溯香。 院中可真熱鬧鲫构,春花似錦、人聲如沸玫坛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炕吸,卻和暖如春伐憾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背算途。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工塞耕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚀腿,地道東北人嘴瓤。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像莉钙,于是被迫代替她去往敵國和親廓脆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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