Vuex的初探與實戰

来源:https://www.cnblogs.com/peerless1029/archive/2018/11/26/10018318.html
-Advertisement-
Play Games

1.背景 最近在做一個單頁面的管理後臺項目,為了提高開發效率,使用了Vue框架來開發。為了使各個部分的功能,獨立結構更加清晰,於是就拆分了很多組件,但是組件與組件之間數據共用成了一個問題,父子組件實現起來相對簡單,prop,$emit,$on就能搞定。除此之外,有很多兄弟組件和跨多級組件,實現起來過 ...


1.背景 

  最近在做一個單頁面的管理後臺項目,為了提高開發效率,使用了Vue框架來開發。為了使各個部分的功能,獨立結構更加清晰,於是就拆分了很多組件,但是組件與組件之間數據共用成了一個問題,父子組件實現起來相對簡單,prop,$emit,$on就能搞定。除此之外,有很多兄弟組件和跨多級組件,實現起來過程繁瑣,在多人協同開發上,不利於統一管理,於是,開始了Vue的生態之一的Vux實踐之旅。

2.概述

每一個 Vuex 應用的核心就是 store(倉庫)。“store”基本上就是一個容器,它包含著你的應用中大部分的狀態 (state)。

Vuex 和單純的全局對象有以下兩點不同:

1.Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新;2.你不能直接改變 store 中的狀態。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地瞭解我們的應用

3.安裝使用

3.1.使用Vue-cli開發安裝vue包

cnpm install vuex --save

3.2.在src目錄下創建store文件夾並創建index.js如下(src/store/index.js)

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
  state: {

  },
  getters: {

  },
  mutations: {

  },
  actions: {

  }
});

 然後在src文件下的main.js中使用

import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false

new Vue({ el: '#app', store, components: { App }, template: '<App/>' })

4.用法簡介

4.1.state

state是保存共用數據的,現在改store/index.js如下:

**
state: {
    count:0
  },
**

在components目錄下創建Index.vue如:

<template>
  <div class="index">
    {{count}}
  </div>
</template>

<script>
  export default {
    name: "index",
    computed:{
      count(){
        return this.$store.state.count;
      }
    }
  }
</script>

 結果如下:

我們可以通過組件的計算屬性來保存state裡面的值,那麼問題來了,如果store太多的話,我們組件裡面的計算屬性豈不是成了這個樣子:

**
computed:{
  count(){
     return this.$store.state.count;
  },
   stateA(){
      return this.$store.state.stateA;
   },
   stateB(){
      return this.$store.state.stateB;
   }
}
**

這樣獲取共用狀態的數據也沒有什麼問題不過看起來還是有大量的重覆冗餘代碼,我們可以使用 mapState 輔助函數幫助我們生成計算屬性,讓你少按幾次鍵:

當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給 mapState 傳一個字元串數組。

**
import {mapState} from 'vuex'
  export default {
    name: "index",
    computed:{
      ...mapState(['count']),
    }
  }
**

 小結:使用 Vuex 並不意味著你需要將所有的狀態放入 Vuex。雖然將所有的狀態放到 Vuex 會使狀態變化更顯式和易調試,但也會使代碼變得冗長和不直觀。如果有些狀態嚴格屬於單個組件,最好還是作為組件的局部狀態。

 4.2.getter

有的時候我們需要對共用狀態裡面的某一個屬性做一些處理後再使用,我們可以把數據獲取後再在組件的計算屬性中處理,舉個例子如下:

// store/index.js
state: {
    count:0,
    numbers:[0,1,2,3,4,5,6,7,8]
  },
// Index組件
<template>
  <div class="index">
    {{count}}
    <br>
    {{numbers.join()}}
  </div>
</template>
<script>
  import {mapState} from 'vuex'
  export default {
    name: "index",
    computed:{
      ...mapState(['count']),
      numbers(){
        return this.$store.state.numbers.filter((item)=>{
          return item>3;
        })
      }
    }
  }
</script>

結果如下:

 那麼問題來了,如果多個組件都要做同樣的處理,我們就需要把一份代碼複製到多個地方,顯然是不大合理的,於是有了getter,可以理解為組件裡面的計算屬性。示例如下:

/ store/index.js
getters: {
    filterNumbers(state){
      return state.numbers.filter((item)=>{
        return item>3;
      })
    }
  },
// Index組件
<template>
  <div class="index">
    {{count}}
    <br>
    {{filterNumbers.join()}}
  </div>
</template>

<script>
  import {mapState} from 'vuex'
  export default {
    name: "index",
    computed:{
      ...mapState(['count']),
      filterNumbers(){
        return this.$store.getters.filterNumbers;
      }
    }
  }
</script>

結果完全一樣,我們可以根據this.$store.getters.屬性名來獲取getters,也可以通過mapGetters 輔助函數將 store 中的 getter 映射到局部計算屬性: 

具體實現方式如下:

<template>
  <div class="index">
    {{count}}
    <br>
    {{filterNumbers.join()}}
    <br>
    {{antherNumbers.join()}}
  </div>
</template>

<script>
  import {mapState,mapGetters} from 'vuex'
  export default {
    name: "index",
    computed:{
      ...mapState(['count']),6
      ...mapGetters(['filterNumbers']),
      ...mapGetters({
        antherNumbers:'filterNumbers'
      })
    }
  }
</script>

 如果用同一名字直接把數組作為參數,如果想改一個名字,可以傳入一個對象作為參數,結果如下:

 4.3.mutation

在組件內,來自store的數據只能讀取,不能手動改變,改變store中數據唯一的途徑就是顯示的提交mutations。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字元串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,並且它會接受 state 作為第一個參數。改變代碼如下:

// store/index.js
mutations: {
add(state){
state.count++;
}
},

// Index組件
**
    <button @click="add">+</button>
**
    methods:{
      add(){
        this.$store.commit('add');
        console.log(this.count);
      }
**

連續點擊5次增加按鈕,發現count的值也改變了。當然,我們也可以傳參進去

// store/index.js
mutations: {
  add(state,n){
    state.count+=n;
  }
},

// Index組件
**
    <button @click="add">+</button>
**
    methods:{
      add(){
        this.$store.commit('add'10);
        console.log(this.count);
      }
**

觸發方法語句為:this.$store.commit(方法名);也可以使用輔助函數mapMutations代替:

**
methods:{
   ...mapMutations(['add']),
}
**

4.4.action

前面我們講過,mutation有必須同步執行這個限制,我們在業務需求中有時候需要在獲取ajax請求數據之後再操作或定時器操作數據,這些都屬於非同步請求,要用actions來實現。具體實現如下:

// store/index.js
**
mutations: {
    changeCount(state){
      state.count=3000;
    },
  },
  actions: {
    changeCount3000s(context){
      setTimeout(()=>{
        context.commit('changeCount')
      },3000)

// Index組件
**
<button @click="changeCount3000s">點擊按鈕3s後count的值改變</button>
**
methods:{
  ...mapMutations(['add']),
    changeCount3000s(){
       this.$store.dispatch('changeCount3000s');
    }
  }
**

我們在點擊按鈕3s後count的值改變為3000,我們可以通過this.$store.dispatch(方法名)來觸發事件,也可以通過輔助函數mapActions來觸發。

**
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
 **
    methods:{
      ...mapMutations(['add']),
      ...mapActions(['changeCount3000s'])
    }
**

 

  學會以上幾個屬性的使用基本就可以滿足平時業務中的需求了,但使用Vuex會有一定的門檻和複雜性,它的主要使用場景是大型單頁面應用,如果你的項目不是很複雜,用一個bus也可以實現數據的共用,但是它在數據管理,維護,還只是一個簡單的組件,而Vuex可以更優雅高效地完成狀態管理,所以,是否使用Vuex取決於你的團隊和技術儲備。


參考資料:

《Vue.js實踐》  Vuex


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 查詢Linux系統負載情況,一般需要瞭解三個方面的信息: 1、Linux系統配置。如Linux版本號、CPU、記憶體、網路、磁碟等; 2、收集系統負載信息的手段。常用的工具包有sysstat和procps等。 3、查詢結果分析。通過工具包獲取系統負載信息,要具體分析系統是否負載、某項指標參數是否超標、 ...
  • SqlServer 操作 JSON Intro Sql Server 從 2016 開始支持了一些 json 操作,最近的項目里也是好多地方直接用欄位直接存成了 json ,需要瞭解一下怎麼在 Sql Server 中操作 JSON. JSON支持適用於 SqlServer 2016 及以上版本 和 ...
  • 轉自:http://www.maomao365.com/?p=7847摘要: 為了更好的記錄資料庫中存儲過程腳本的變化情況,下文采用資料庫觸發器來自動記載每次“存儲過程”的變化(新增或修改),如下所示: 實驗環境:sql server 2008 R2 <hr />處理方法:1 .master資料庫下 ...
  • 原創作品,歡迎轉載,轉載請在文章顯眼位置註明出處:https://www.cnblogs.com/sunshine5683/p/10016569.html 開始之前先註意:在linux中切換到sqlplus,進行命令操作時候,退格鍵有可能不能用,出現^H的情況,這時候將退格鍵和Ctrl鍵一起使用,問 ...
  • @[toc] Hadoop所用安裝包和配置文件等我找到最方便使用的方式再上傳到博客,如果有需要也歡迎找我分享。 這篇博客是建立在我另一篇博客的基礎上,建議先瀏覽博文 "大數據入門第一篇:maven項目的搭建" 在windows下, 1.導包Hadoop包 我用的是破解版的文件,不需要安裝,直接解壓到 ...
  • 比如學hadoop,從哪兒開始學首先要根據你的基本情況而定,如果你就一小白,沒有任何開發基礎,也沒有學過任何開發語言,那就必須先從基礎java開始學起(大數據支持很多開發語言,但企業用的最多的還是JAVA),接下來學習數據結構、關係型資料庫、linux系統操作,夯實基礎之後,再進入大數據的學習,例如 ...
  • 問題現象:hadoop 3.1.0源碼文件ClientNamenodeProtocolProtos大小4M+,IDEA打開時載入失敗,ClientNamenodeProtocolPB報錯找不到類。 問題原因:IDEA預設載入文件大小不超過2500KB,配置項為idea.max.intellisens ...
  • 在調用glide介面時,因為最新版本為4.8.0 調用代碼如下: repositories { mavenCentral() google() } dependencies { implementation 'com.github.bumptech.glide:glide:4.8.0' annota ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...