Vuex-各模塊的應用

一 初識Vuex

Vuex是vue官方推出的一款插件,採用“集中式存儲“管理所有組件的狀態(其實就是使數據共享)

1. vuex安裝

npm install vuex

1. State單一狀態樹

單一狀態樹是指Vuex將所有的狀態(數據)都放在一個store中,便於管理和維護,而不是把不同的數據放在不同的store中,容易讓人混淆

二 vuex 模塊

  1. /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  //存放一些數據(狀態)
  state: {
    //在state中定義的數據是響應式的,數據改變頁面會馬上改變
    counter: 1000,
    stu: [
      {id:11,age:30},
      {id:17,age:50},
      {id:14,age:20}
    ],
    info: {
      name: 'kobe',
      age: 50
    }
  },
  //存放改變數據的方法,官方推薦改變數據時用mutations中的方法來實現,而不是直接修改數據
  //同步操作
  mutations: {
    increment(state){
      state.counter++
    },
    decrement(state){
      state.counter--
    },
    //參數被稱作mutations的載荷,多參數可以傳一個對象
    incrementCount(state,payload){
      //普通的提交
      //state.counter += payload
      //特殊的提交
      state.counter += payload.count
    },
    addStudent(state,stu){
      state.stu.push(stu)
    },
    updateInfo(state){
      //state.info.name = 'woshishui' //數據在state中,響應式改變
      //state.info['address'] = 'china' //數據不在state中,不會響應式改變
      //Vue.set(state.info, 'address', 'china')//用的set 響應式改變
      //delete state.info.age //非響應式
      Vue.delete(state.info, 'age') //響應式
    }

  },
  //異步操作 修改數據還是得調用mutations中的方法
  actions: {
  /*  aUpdateInfo(context,payload){
      setTimeout(()=>{
        context.commit('updateInfo')
        console.log(payload)
      },1000)
    }*/
    aUpdateInfo(context,payload) {
      return new Promise((resolve,reject) => {
        setTimeout(() => {
          context.commit('updateInfo')
          console.log(payload)
          resolve('111')
        },1000)
      })
    }
  },
    //數據篩選和數據變換
    getters: {
      doubleCn(state){
        return state.counter * state.counter;
      },
      stuFilter(state){
        return state.stu.filter(s=> s.age>=30)
      },
      //第一個參數一定是state 第二個參數一定是getters
      len(state,get){
        return get.stuFilter.length;
      },
      //傳參寫法
      studentFilter(state){
        /*return function(age){
          return state.stu.filter(s=>s.age>=age)
        }*/
      //箭頭函數寫法
      return age => {return state.stu.filter(s => s.age >= age)}
    }
  },
  //模塊,用於把一些數據分離出來,使結構更清晰,
  //編譯時會將modules中的內容加載到state中
  modules: {
    a: {
      state: {
        name: 'zan'
      },
      mutations: {
        updateName(state, payload){
          state.name = payload
        }
      },
      //modules中的action只能對modules中的mutations進行調用
      actions:{},
      getters:{
        fullName(state){
          return state.name + '1111'
        },
        fullName2(state, getters){
          return getters.fullName + '222'
        },
        //獲得跟內的數據
        fullName3(state, getters, rootState){
          return getters.fullName2 + rootState.counter
        }
      }
    }
  }
})
export default store
  1. src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

  1. src/App.vue
<template>
  <div>
    <h1>全局變量{{$store.state.counter}}</h1>
    <button @click="incre">+</button>
    <button @click="decre">-</button>
    <h1>getters double {{$store.getters.doubleCn}}</h1>
    <h1>getters filter {{$store.getters.stuFilter}}</h1>
    <h1>getters length  {{$store.getters.len}}</h1>
    <h1>getters params {{$store.getters.studentFilter(50)}}</h1>
    <button @click="addCount(10)">addCount</button>
    <button @click="addStudent()">添加數據</button>
    <button @click="updateInfo">{{$store.state.info}}</button>
    <h1>=============modules=================</h1>
    <h2>{{$store.state.a.name}}</h2>
    <button @click="updateName">修改名字</button>
    <!--modules中getters調用和平常的一樣-->
    <h2>{{$store.getters.fullName}}</h2>
    <h2>{{$store.getters.fullName2}}</h2>
    <h2>{{$store.getters.fullName3}}</h2>
  </div>
</template>
<!---->
<script>
export default {
  name: 'App',
  //封裝mutations中的方法
  methods: {
    incre(){
      this.$store.commit('increment')
    },
    decre(){
      this.$store.commit('decrement')
    },
    addCount(count){
      //1. 普通的提交封裝,傳回去的是普通數據類型
      //this.$store.commit('incrementCount',count)

      //2. 特殊的提交封裝,傳回去的是對象
      this.$store.commit({
        type: 'incrementCount',
        count
      })
    },
    addStudent(){
      const stu={id:4454,age:100}
      this.$store.commit('addStudent',stu)
    },
    updateInfo(){
      //同步操作
      //this.$store.commit('updateInfo')
      //異步操作
      this.$store.dispatch('aUpdateInfo', 'payload')
          .then(res => {
            console.log('裏面完成了提交');
            console.log(res);
          })
    },
    updateName(){
      this.$store.commit('updateName','newName')
    }
  }
}
</script>
<style>
</style>

三 vuex 模塊分佈式寫法

  1. /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'

Vue.use(Vuex)


const state ={
  count:100,
  students:[
    {id:100,name:'kobe',age:30},
    {id:200,name:'james',age:32},
    {id:300,name:'curry',age:31},
  ],
  info:{
    name:'kobe',
    age:19
  }
}
const store = new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules:{
    a:moduleA
  },
})

export default store
  1. /src/store/mutations.js
export default {
  increment(state){
    state.count++
  },
  decrement(state){
    state.count--
  },
  //普通提交的封裝 傳入的是具體數字
  /* incrementCount(state,count){
     state.count += count
   },*/
  //特殊提交的封裝 傳入的是對象
  incrementCount(state,payload){
    state.count +=payload.count
  },
  addStudent(state, data){
    state.students.push(data)
  },
  updateInfo(state){
    //state.info.name = 'james' 修改已有的數據是響應式的
    //state.info['address'] = 'LA' 添加未有的數據不是響應式的
    //Vue.set(state.info,'address','LA')  //響應式
    //delete state.info.age 非響應式
    Vue.delete(state.info, 'age') //響應式
    //或者用響應式方法 push pop shift unshift splice 等
  }
}
  1. /src/store/getters.js
export default{
  powerCount(state){
    return state.count * state.count
  },
  more20stu(state){
    return state.students.filter(s => s.age >20)
  },
  len(state,getters){//可以有第二個參數拿其他getters
    return getters.more20stu.length
  },
  moreAge(state){//getters裏的方法只能有兩個參數,不接收第三個參數
    return age => {return state.students.filter(s => s.age >age)}
  },
  fullName1(state){
    return state.a.name + 'root中的name'
  },
}
  1. /src/store/actions.js
export default {
  aUpdateInfo(context, payload){
    return new Promise((resolve,reject)=>{
      setTimeout(()=>{
        context.commit('updateInfo')
        console.log(payload);
        resolve('裏面異步操作')
      },1000)
    })
  }
}
  1. /src/store/modules/moduleA.js
export default {
  state:{
    name:'wo'
  },
  mutations:{
    updateName(state,payload){
      state.name = payload
    }
  },
  getters:{
    fullName(state,getters){
      return getters.fullName1 + '模塊裏的name'
    },//可以調用root中的getters
    fullName3(state,getters,rootState){
      //模塊中的getters方法可以有第三個參數
      return getters.fullName + rootState.count
    }
  },
  actions:{
    //模塊actions中context指向本模塊 其中封裝有getters rootGetters
    //rootState state
    aUpdateName(context) {
      setTimeout(()=>{
        context.commit('updateName','wangwu')
      },1000)
    }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章