Vue 高级-Vuex

介绍

vuex是一种状态管理模式,它保存着组件的公用的状态,并且以相应的规则保证状态变化。

vuex的核心就是一个store,它相当于是一个容器,里面包含有state,action,mutation,getter,modules。

  • state:用于数据的存储,是store中的唯一数据源

  • getters:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算

  • mutation:类似函数,改变state数据的唯一途径,且不能用于处理异步事件

  • action:类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作

  • modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护

特点

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

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

  • vuex是单一状态树

vuex的流程

image.png

vuex的整体流程是:

  1. 在组件内部,通过dispatch来分发action。

  2. 再通过action来第调用mutation

  3. 进而触发mutation内部的commit来修改state

  4. 最后state改变,导致页面重新render。

使用

vuex的使用场景

  • 大型应用中,用于全局共享的data,例如全局消息提醒、控件权限控制等等。

  • vuex可配合sessionStorage做用户基本信息的持久化存储。

  • 多级组件的数据需要共享或多个页面之间的数据存在因果关系时,可以使用vuex。

在state中定义了count、userInfo、students三个属性,state里面的数据状态可以在全局中被访问,在任意组件中通过this.$store.state.attrName访问,在demo.vue的computed属性里面,我们获取了以上三个属性

getter中可以自定义一些函数对state属性里面的数据进行过滤,并且在任意组件中可以通过this.$store.gettter.functionName的方式获取

mutaions用来更新state里面的状态,我们可以定义一些方法对数据进行操作,在里面的方法中至少有state和value两个参数,state就是上面所说的state对象(属性),value就是从组件传递来的值。可以看到,在demo.vue中点击加号按钮或者减号按钮,通过this.$store.commit('getUserInfo',count的方式向vuex提交了一个事件,在store.js中mutaions里面的updateCount将提交过值接收并进行处理,state里面的count状态被更新,这是demo组件的computed属性中的number被执行,然后紧接着dom被更新。

actions也是对state状态进行更新,但是是间接的,一些异步的操作先交给actions里面的函数执行,拿到结果后在交给mutaions中相应的处理函数处理,接下来的操作就跟上面讲的一样。 点击获取用户信息按钮,通过this.$store.dispatch('getUserInfo',this)向vuex提交了一个事件,store.js中actions的getUserInfo函数处理了这个事件,向本地一个user.json文件发了一个异步请求,难道结果后将返回的用户信息交给了mutaions的getUserInfo函数处理,state的userInfo属性被改变,userInfo的变化导致demo.vue中computed属性的userInfo被执行,接着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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容