Vuex 在state中存取數據 modules分模塊 (2018/11/28)

1、store是一個狀態管理工具 (vueX中只有惟一 一個store)
用途 :存數據 取數據 改數據
 
把須要共享的數據放在store裏 不須要共享的數據仍是放在組件裏
 
從state中取出數據渲染到view層------>view層再經過action改變數據------>action在將數據存入state  (vuex的處理流程是一個單向的數據流  必須先發動動做纔可以改數據)
 
Vuex就是提供一個倉庫,Store倉庫裏面放了不少對象。其中state就是數據源存放地,對應於與通常Vue對象裏面的data(後面講到的actions和mutations對應於methods)。
在使用Vuex的時候一般會建立Store實例new Vuex.store({state,getters,mutations,actions})有不少子模塊的時候還會使用到modules。
總結,Store類就是存儲數據和管理數據方法的倉庫,實現方式是將數據和方法已對象形式傳入其實例中。要注意一個應用或是項目中只能存在一個Store實例!!
      Vuex 的思想是 當咱們在頁面上點擊一個按鈕,它會觸發(dispatch)一個action, action 隨後會執行(commit)一個mutation, mutation 當即會改變state,  state 改變之後,咱們的頁面會state 獲取數據,頁面發生了變化。 Store 對象,包含了咱們談到的全部內容,action, state, mutation,因此是核心了。
       store 對象注入到根實例後,在全部的子組件中,就能夠用this.$store 來指向store 對象,獲取state。在子組件中,computed 屬性是根據它的依賴自動更新的。因此只要store中的state發生變化,它就會自動變化。
      經過computed屬性能夠獲取到狀態值,可是組件中每個屬性(如:count)都是函數,若是有10個,那麼就要寫10個函數,且重複寫10遍return this.$store.state,不是很方便。vue 提供了 mapState 函數,它把state 直接映射到咱們的組件中。
store就是一個實例其中存放了不少對象,每一個對象又有不一樣的職責,有的存放數據,有的調用方法
 
創建新項目的步驟:
一、新建一個vue項目
二、把數據存到state裏  在文件路徑下 cnpm i  vuex  --save
三、啓動項目  npm run dev
四、在src文件夾中新建一個文件夾  store---->index.js----->main.js引入store----->App.vue 取數據渲染到頁面上
index.js  (向store中存數據)
 
import  Vue from 'vue'   //引入兩個插件
import Vuex from 'vuex'
Vue.use(Vuex)
var store = new Vuex.Store({   //向store中存入數據
      state:{
            n:1000,
            age:12,
            lessions:["java","html"], //數組
            haha:{   //對象
                  yi:'mm'
            }
      }
})
export  default store  //將數據暴露出去
 
main.js
 
import Vue from 'vue'
import App from './App'
import router from './router'
import store from '@/store/index'   //引入index
Vue.config.productionTip = false
 
new Vue({
  el: '#app',
  router,
  store,  //註冊
  components: {
      App
  },
  template: '<App/>'
})
 
App.vue  (從state中取數據)
 
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
    {{n}}   {{age}}  {{lessions}}  {{haha}}   <!--渲染數據-->
  </div>
</template>
<script>
export default {
  name: 'App',
  computed:{    //取數據
      n(){
            return this.$store.state.n
      },
      age(){
            return this.$store.state.age
      },
      lessions(){
            return this.$store.state.lessions[0]
      },
      haha(){
            return this.$store.state.haha["yi"]
      }
  }
}
</script>
 
2、getters計算屬性
         Vuex 容許咱們在 store 中定義「getter」(能夠認爲是 store 的計算屬性)。就像計算屬性同樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算。
             Getter 接受 state 做爲其第一個參數, 也能夠接受其餘 getter 做爲第二個參數

經過屬性訪問

               Getter 會暴露爲 store.getters 對象,你能夠以屬性的形式訪問這些值
                注意:getter 在經過屬性訪問時是做爲 Vue 的響應式系統的一部分緩存其中的。(會產生緩存)
store.getters.doneTodos 
 

經過方法訪問 

                 也能夠經過讓 getter 返回一個函數,來實現給 getter 傳參。在你對 store 裏的數組進行查詢時很是有用。
                   注意,getter 在經過方法訪問時,每次都會去進行調用,而不會緩存結果。(不會產生緩存)
store.getters.getTodoById(2)
 
3、mutations 同步的方法更改數據
              更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。 惟一修改狀態的事件的回調函數
               mutation中放的是處理數據邏輯的方法,它可以使數據和視圖分離,起到更改數據(狀態)的做用。
(1)mutation 同步更改數據
        每個mutation都有一個字符串類型的事件類型(type)和回調函數(handler),先註冊事件type,當觸發響應類型的時候調用handler();
(2)payload   提交載荷
         簡單的理解就是往handler(state)中傳參handler(state,payload);通常是個對象。
          state      是存放數據的地方
          payload      至關於一個參數
(3)commit   調用mutation中的type
         能夠在組件中使用 this.$store.commit.("type名") 提交 通過mutation操做後作出改動的數據
         commit是同步函數,並且只能是同步執行
 
 
4、actions 異步的方法更改數據
         Action 提交的是 mutation,而不是直接變動狀態。而且能夠包含任何的異步操做。actions將mutations裏面只能同步處裏數據的方法變成了能夠異步處理數據的方法。
           Action 函數接受一個與 store 實例具備相同方法和屬性的 context 對象,所以你能夠調用context.commit來提交一個mutation(由於mutation中的type是經過 $store.commit方法被提交的,action中的mutation能夠經過context.commit被提交 )
          在組件中使用this.$store.dispatch("xxx") 分發 action
 
總結一下就是 同步提交mutation用 this.$store.commit("mutation中的type名")
                     異步提交mutation用 context.commit("mutation中的type名",參數)
                     異步分發action用 this.$store.dispatch("action中的type名")
store/index.js
 
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
var store = new Vuex.Store({
     state://存數據
           n:10000,
           age:12,
           lesson:['aaaa','bbbbbb']
     },
     mutations:{ //同步的方法更改數據
     changeAge1(state,payload){   //type:changeAge1,handler的第一個參數是state;
           state.age=state.age+1  // 變動狀態
     },
     changeNum1(state,payload){   //  提交載荷 payload  簡單的理解就是往handler(state)中傳參handler(state,payload);通常是個對象。
           state.n+=payload   //這個payload至關於一個參數
     },
     addlesson(state,payload){
           state.lesson=state.lesson.concat(payload) //在已有課程以後拼接新的課程 payload接收到了從actions中的getlesson中甩出來的數據
     }
     },
     actions:  //異步的方法定義和調用數據
           getlesson(context){ //context是自帶的上下文對象
                axios.get("http://localhost:3000/lessons").then((res)=>{   //從data.json中獲取數據
                     context.commit("addlesson",res.data.map((item)=>item.lesson))   // 第一個參數用於調用mutation中的方法  第二個參數至關因而payload 是將從json中獲取到的值甩出去
                     
                })
           }
     }
})
export default store
 
App.vue
 
<template>
  <div id="app">
    <router-view/>
   {{age}}  <button @click='changeAge'>年齡</button>
     <button @click='changeNum(1)'>+</button>{{n}}<button  @click='changeNum(-1)'>-</button>
     <p v-for='item in lesson'>{{item}}</p>
     <button @click='getlesson'>添加數據</button>
   <!--渲染數據-->
  </div>
</template>
<script>
export default {
  name: 'App',
  computed:{  //取數據
     n(){
           return this.$store.state.n
     },
     age(){
           return this.$store.state.age
     },
     lesson(){
           return this.$store.state.lesson
     }
  },
  methods:{  //調用方法改變數據
     changeAge(){
           this.$store.commit("changeAge1")
  },
  changeNum(n){
     this.$store.commit("changeNum1",n)
  },
getlesson(){
     this.$store.dispatch("getlesson")
            }
        }
    }
</script>
 
5、modules分模塊
        因爲使用單一狀態樹,應用的全部狀態會集中到一個比較大的對象。當應用變得很是複雜時,store 對象就有可能變得至關臃腫。
            爲了解決以上問題,Vuex 容許咱們將 store 分割成模塊(module)。每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行一樣方式的分割:
操做步驟:
             在src文件目錄下新建一個store文件夾----->在store中新建一個index.js----->在store目錄下新建一個demo文件夾 ------>在demo中新建state.js 、mutation.js、action.js、getter.js文件----->在demo/index文件中引入以上幾個js文件,並將其暴露出去------>store/index 引入demo文件夾而且建立store實例 引入modules----->App.vue中調用方法----->main.js引入store中的index.js  註冊store
                
state.js
export default{  //不須要寫state:{}
          n:1000,
          age:12,
          lesson:['math','english']
}
 
mutations.js
export default{
     
          changeAge(state,payload){
              state.age=state.age+1
          },
          changeNum(state,payload){
              state.n+=payload
          },
          addlesson(state,payload){
              state.lesson=state.lesson.concat(payload)
          }
     
}
 
actions.js
import axios from 'axios'
export default{
     
          getlesson(context){
               axios.get("http://localhost:3000/lessons").then((res)=>{
context.commit('addlesson',res.data.map((item)=>item.lesson))
              })
          }
     
}
 
demo/index.js
import state from './state'
import mutations from './mutations'
import actions from './actions'
export default{
     state,
     mutations,
     actions
}
 
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import demo from './demo'
Vue.use(Vuex)
var store = new Vuex.Store({  //建立store實例
     
     modules:{  //引入模塊
          demo
     }
     
})
export default store
 
App.vue
<template>
  <div id="app">
     <button @click='changeNum(1)'>+</button>{{n}}<button  @click='changeNum(-1)'>+</button>
     <button @click='changeAge'>改變年齡</button>{{age}}
    <p v-for='item in lesson'>{{item}}</p>
  <button @click='getlesson'>添加課程</button>
  </div>
</template>
<script>
export default {
  name: 'App',
  computed:{
     n(){
          return this.$store.state.demo.n  //注意路徑
     },
     age(){
          return this.$store.state.demo.age
     },
     lesson(){
          return this.$store.state.demo.lesson
     }
  },
  methods:{
     changeAge(){
          this.$store.commit('changeAge')
     },
     changeNum(inc){
          this.$store.commit('changeNum',inc)
     },
     getlesson(){
          this.$store.dispatch('getlesson')
     }
  }
}
</script>
 
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from '@/store/index'
Vue.config.productionTip = false
 
new Vue({
  el: '#app',
  router,  //把router和store放在實例上
  store,
  components: { App },
  template: '<App/>'
})
6、四個輔助函數
 
mapstate      //將state中的數據映射到組件中去
mapmutations
mapactions
mapgetters
<template>
    <div>
        {{Counter.arr[idx]}}<button @click="inc(idx)">+</button>
    </div>
</template>
 
import {mapState,mapMutations} from ‘vuex’   //引入
 
computed:{
props:["idx"],
...mapState(["counter","arr"])   //這表示counter中的arr
    },
mathods:{
    ...mapMutations(["inc"])
    }
相關文章
相關標籤/搜索