首頁 > 軟體

vuex中的state屬性解析

2022-04-12 13:00:31

state屬性介紹

state屬性是Vuex中用於存放元件之間共用的資料;也就是說,我們把一些元件之間共用的狀態主要存放在state屬性中;它採用的是單一狀態樹——用一個物件就包含了全部的應用層級狀態。這也意味著,每個應用將僅僅包含一個 store 範例。單一狀態樹讓我們能夠直接地定位任一特定的狀態片段,在偵錯的過程中也能輕易地取得整個當前應用狀態的快照。

state的使用

在HTML中我們可以直接省略 this 關鍵字 ,直接使用 $store.state.狀態名(變數名) 來存取 vuex 中的儲存的狀態;

① 抽離出去的state.js檔案

export default {
  loadingFlag: true,
  // 用於儲存已選類別標籤
  changedLableList: [
    { name: '頭條', class: 'iconfont icon-jinrishouru', url: 'topnews/index' },
    { name: '蘋果', class: 'iconfont icon-pingguoapple', url: "apple/index" },
    { name: 'NBA', class: 'iconfont icon-tiyu-lanqiu', url: "nba/index" },
    { name: '創業', class: 'iconfont  icon-chaxunchuangyebankaitongqingkuang', url: "startup/index" },
    { name: '足球', class: 'iconfont icon-swticonzuqiu', url: "football/index" },
    { name: '體育', class: 'iconfont icon-paobu', url: "tiyu/index" }
  ]
}

② 在index.js檔案中匯入state.js檔案並註冊

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import state from './state'
import actions from './actions'
import getters from './getters'
// 安裝外掛
Vue.use(Vuex)
// 建立物件
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})

③ 在元件中使用

<div class="flex-content">
          <div class="lable-items" v-for="(item, index) in $store.state.changedLableList" :key="index" @click="decrementTypeLable(index)">
            <div class="item">
              <div><i :class="item.class"></i></div>
              <span>{{ item.name }}</span>
            </div>
          </div>
        </div>

在js程式碼中,必須使用 this.$store.state.狀態名(變數名) 來存取vuex中儲存的狀態;

computed: {
    title() {
      return this.$route.meta.title
    },
    changedLableList() {
      return this.$store.state.changedLableList
    },
    alternativeLableList() {
      return this.$store.state.alternativeLableList
    }
  },

擴充套件

為什麼要在元件的computed計算屬性中使用不能放到data屬性中?

data 中的內容只會在 created 勾點函數觸發前初始化一次,類似於我們直接寫 const data = { foo: 123 }這樣,這時屬性的值是純粹的字面量,而不是所謂的【快取】(沒有 Cache Miss 哪來的快取?)。JS字面量賦值後顯然不會自動更新。

最簡單的例子:

let b = ‘xxx' // 相當於state中的資料
let a = b // 相當於data初始化時,將b的值賦值給了a
b = ‘xyz' // 這時對於原始型別,a 肯定還是 ‘xxx'

換句話說,data 中內容依賴變更時,data 屬性不會變更(它的設計目標就是儲存元件的區域性狀態資料而已)。而 computed則是通過【依賴追蹤】實現的,在 computed 求值時參照的 Vue 變數變化時,會觸發對 computed 的重新計算。所以我們可以使用computed 去參照 Vuex 狀態變數,從而使得依賴追蹤生效。或者,將 Vuex 狀態變數通過 mapState() 方法對映為 computed 也是一個很方便的選擇。

vuex的State

state 是Vuex中的基本資料,state 上存放的就是所謂的狀態。當沒有使用 state 的時候,直接在 data 中進行初始化,有了 state 之後,我們就把 data 上的資料轉移到 state 上去了。

單一狀態樹

Vuex 使用到的是單一狀態樹,即用一個物件就包含了全部的狀態資料。也就是說如果我們定義了一個 store 的範例,那麼這個 store 範例裡面只有一個 state。state作為構造器選項,定義了所有我們需要的基本狀態引數。

單一狀態樹讓我們能夠直接地定位任一特定的狀態片段,在偵錯的過程中也能輕易地取得整個當前應用狀態的快照。

在Vue元件中獲得 Vuex 狀態

從store範例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態。

範例:

例如我們在state中定義一個count屬性,給它賦一個值為10,store.js檔案內容如下所示:

import Vue from 'vue' // 引入vue
import Vuex from 'vuex' // 引入vuex
Vue.use(Vuex)  
const state = {
    count: 10
}
export default new Vuex.Store({
    state
})

然後建立一個 Counter元件,在元件中返回count,內容如下所示:

const Counter = {
  template: `<div> count的值為:{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count  //返回store範例的count狀態
    }
  }
}

每當 store.state.count 變化的時候,都會重新求取count屬性,並重新整理介面。

這種模式依賴於全域性的管理員 store,如果模組多了,那麼每個模組或者頁面只要用到了這個 state 裡面的資料,都得把 store 引入進來,這樣的操作確實有點難受。所以出現了下面這種解決辦法。

Vuex 通過store 選項,提供了一種機制將狀態從根元件 “注入” 到每一個子元件中:

new Vue({
  el: '#app',
  store,  // 根元件通過store選項將store範例注入所有地子元件
  // 子元件
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

Vue專案的index.html檔案內容如下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>俠課島</title>
  </head>
  <body>
    <h1>俠課島歡迎你</h1>
    <div id="app"></div>
  </body>
</html>

最終我們使用 npm run dev 執行專案,瀏覽器中的輸出結果如下圖所示,如果我們在state中改變count的值,頁面會自動重新整理:

mapState輔助函數

當一個元件需要獲取多個狀態時候,將這些狀態都宣告為計算屬性會有些重複和冗餘。為了解決這個問題,我們可以使用 mapState 輔助函數幫助我們生成計算屬性,讓你少按幾次鍵。

範例:

在使用mapState函數之前,需要先引入它:

import { mapState } from 'vuex'

引入後才可以開始使用,它兩種用法,可以接受一個物件或接受一個陣列。

物件用法如下:

import { mapState } from 'vuex'
export default {
  // 下面這兩種寫法都可以
  computed: mapState({
    // 元件內的每一個屬性函數都會獲得一個預設引數state,然後通過state直接獲取它的屬性
    count: state => state.count,
    // 'count' 直接對映到state物件中的count,相當於this.$store.state.count
    count: 'count' 
  })
}

陣列用法如下所示:

// 當對映的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給mapState傳一個字串陣列。
export default {
    computed: mapState([ // 陣列
      'count'
    ])
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。 


IT145.com E-mail:sddin#qq.com