主頁 > 企業開發 > vuex知識筆記,及與localStorage和sessionStorage的區別

vuex知識筆記,及與localStorage和sessionStorage的區別

2020-10-02 08:05:48 企業開發

選單快捷導航

  1. Vuex是什么東東,有什么應用場景?localStorage和sessionStorage能否替代它?
  2. Vuex知識點State、Getter、Mutaion、Action
  3. Vuex模塊化(Module)

 1、Vuex概念和應用場景

  首先,Vuex是什么,官網介紹說Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式,我的理解就是Vuex就是類似于sessionStorage這樣管理資料(本地存和取)的一種技術方案,

  既然vuex類似于sessionStorage,那為何我們還要學習vuex,直接用sessionStorage和localStorage不就好了?這個問得好,我來描述一種場景:多個視圖(view)組件都要用到某一條資料(狀態),當這條資料發生變化的時候,依賴于該資料(狀態)的相關視圖(view)都要跟著即時更新,這種場景在作業中非常常見,我說一個自己碰到的例子,以前有一個react專案,其中有個功能是在pc頁面自定義小程式頁面,然后整個PC頁面有三個組件組成,在三個組件中還有其他的很多子組件,然后一開始的做法就是通過事件和組件間傳值來進行整個頁面資料同步更新,后面隨著組件越來越多,功能越來越復雜,麻煩和問題也就越來越多,然后每一個后面來接手的同事看代碼都要看好一陣,長痛不如短痛...

  對的,在作業中這種常見的多個組件依賴于同一條資料(狀態),需要即時回應更新的情況,vuex的價值就體現出來了,這種情況下,vuex相比其他實作手段,就要簡單干脆方便多了!先看一個小例子,看看vuex和localStorage、sessionStorage的區別,上圖:

  如圖,vuexPageA頁面中參考了三個組件,每個組件都分別從localStorage、sessionStorage、vuex中取了一個值,點擊按鈕加1的時候,vuex的值是及時更新了,其他需要重繪才能更新,總結一下:

  • localStorage存盤的值能夠永久的存盤在瀏覽器上,不管是重新打開新視窗還是重啟,同一個瀏覽器上的相同域名下,localStorage的值一直在,
  • sessionStorage存盤的值依賴于當前視窗(當前會話), 只要當前視窗不關閉,它存盤的資料就一直在,一旦關閉視窗或者打開新視窗,sessionStorage之前存盤的資料就會消失,
  • 相比localStorage和sessionStorage,vuex存盤的資料可以即時更新到,當前專案下的所有參考了該資料的組件,但是如果重繪頁面的話,vuex存盤的值會重置,而localStorage和sessionStorage存盤的值不會重置,

  相關代碼見:https://github.com/xiaotanit/tan_vue/blob/master/src/views/vuex/VuexPageA.vue

 

2、Vuex知識點State、Getter、Mutaion、Action

2.1 Vuex之State和mapState

  每一個Vuex應用的核心就是store(倉庫),“store"基本上就是一個容器,Vuex使用單一狀態樹,相當于用一個物件(store)就包含了全部的應用層級狀態,也就是說每個應用也只包含一個store實體,因此Vuex的使用從new一個Vuex.Store實體(store實體)開始,store實體中的State屬性就是用來存放Vue應用的所有的狀態,先來看要給最簡單的包含State屬性的store實體:

import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        count: 0,
    },
})

后面的mutations、getters、actions再慢慢往里面加入代碼,

  store實體創建,如何應用?Vue實體創建時,提供了一個store選項,可以讓Vuex通過store選項,將store實體物件從根組件”注入“到每一個子組件中:

import Vue from 'vue'
import App from './App.vue'
import router from './router.js'

//vuex 之 store實體物件
import store from './api/store/index' 

new Vue({
  router,  
  store, // 把 store 物件提供給 “store” 選項,這可以把 store 的實體注入所有的子組件
  render: h => h(App)
}).$mount('#app')

  store實體注入根組件后,應用中的每個組件中通過this.$store指的就是該store實體物件,那么現在如何在Vue組件中展示store中的state狀態(資料)呢?由于Vuex的狀態存盤是即時回應的,從store實體中讀取狀態最簡單的方法就是在Vue組件中”計算屬性“computed中回傳某個狀態,每當store.state中某個狀態變化的時候,都會重新求取計算屬性,并且觸發更新相關聯的DOM,

  mapState是一個輔助函式,當我們應用中一個組件需要獲取store中多個狀態的時候,使用mapState輔助函式可以幫助我們更加方便生成計算屬性,看看下面的應用測驗代碼:

import { mapState } from 'vuex';

    export default {
        data(){
            return {
                localCount: 88
            }
        },
        mounted(){
            console.log("...store物件:", this.$store);
        },
        computed:{
            localStorage_count(){
                return localStorage.getItem('localStorage_count')
            },
            //使用物件展開符"...",可以將物件目標物件混入到外部物件中
            ...mapState({
                sessionStorage_count(){
                    return sessionStorage.getItem('sessionStorage_count')
                },
                vuex_count: state => state.count, //箭頭函式可以使代碼更簡練
                vuex_count_alias: 'count', //傳字串引數'count'等同于 state => state.count
                // 為了能夠使用 `this` 獲取區域狀態,必須使用常規函式
                countPlusLocalState (state) {
                    return state.count + this.localCount
                }
            }),
        },
    }
View Code

 

2.2 Vuex之Getter和mapGetters

  有時我們需要從store中的state種派生出一些狀態,比如對store中的某一個狀態(資料)進行篩選過濾,然后特別是當有多個組件需要用到這種狀態(資料)時,“getter"就出場了!Vuex允許我們在store中定義”getter"(可以認為是store物件的計算屬性),就像計算屬性一樣,getter的回傳值會根據它的依賴被快取起來,且只有當它的依賴值發生了改變才會被重新計算,Getter接受state作為其第一個引數:

export default new Vuex.Store({
    state: {
        count: 0,
        todos: [
            { id: 1, text: '金戈鐵馬,氣吞萬里如虎', done: true },
            { id: 2, text: '老驥伏櫪,志在千里', done: false },
            { id: 3, text: '周公吐哺,天下歸心', done: true },
            { id: 4, text: '但使龍城飛將在,不教胡馬度陰山', done: false },
        ]
    },
    //Vuex允許我們再store中定義"getter"(可以認為是store的計算屬性),
    // 就像計算屬性一樣,getter的回傳值會根據它的依賴被快取起來,且只有當它的依賴值發生了改變才會被重新計算,
    getters: {
        doneTodos: state => {
            console.log('...state.getters.donwTodos...')
            return state.todos.filter(todo => todo.done)
        },
        //Getter也可以接受其他getter作為第二個引數
        //getter在通過屬性訪問時是作為Vue的回應式系統的一部分快取其中的
        doneTodosCount: (state, getters) => {
            console.log('...state.getters.doneTodosLength...', getters.doneTodos)
            return getters.doneTodos.length;
        },
        //通過方法訪問:通過讓getter回傳一個函式,來實作給getter傳參,
        //getter在通過方法訪問時,每次都會去進行呼叫,而不會快取結果,
        getTodoById: (state) => (id) => {
            console.log('...state.getters.getTodoById...: ', id);
            return state.todos.find(todo => todo.id === id);
        }
    },
    
})
View Code

   Getter應用:Getter會暴露為 store.getters 物件,然后在組件中,我們可以通過this.$store.getters來得到getter,getter里面的屬性,可以回傳屬性,也可以回傳方法,如果getter通過屬性訪問時是作為Vue的回應式系統的一部分快取,首次呼叫后再次呼叫時就會呼叫快取,只有該屬性的依賴值變化時,再次呼叫該屬性才會重新呼叫重新快取,如果getter通過方法訪問時,每次都會去進行呼叫,而不會快取結果,組件中應用測驗代碼:

methods:{
            //state.getters呼叫
            stateGettersProperty(){ //getters屬性呼叫, 屬性呼叫會被快取
                console.log(this.$store.getters.doneTodos);
                console.log(this.$store.getters.doneTodosCount);
            },
            stateGettersMethod(){ //方法呼叫,每次都會去進行呼叫,而不會快取結果,
                console.log(this.$store.getters.getTodoById(2).text);
                console.log(this.$store.getters.getTodoById(3).text);
            },
            addTodo(){ //增加資料
                let count = this.$store.state.todos.length;
                let obj = {
                    id: count + 1,
                    text: (count+1) + '***' + (count+1),
                    done: count % 2
                }
                this.$store.commit('addTodos', obj);
            },

        }
View Code

  mapGetters也是一個輔助函式,可以將store物件中的getter映射到區域計算屬性:

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用物件展開運算子將 getter 混入 computed 物件中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}
View Code

  如果你想將一個 getter 屬性另取一個名字,使用物件形式:

mapGetters({
  // 把 `this.doneCount` 映射為 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})
View Code

 

2.3 Vuex之Mutation和mapMutations

  上面說的mapState、getters、mapGetters都是對store物件中的狀態(state)進行應用,如果想更改Vuex的store物件中的狀態(state),必須要用mutation,Vuex中的mutation非常類似于事件:每個mutation都有一個字串的事件型別(type)和一個回呼函式(handler) ,這個回呼函式就是我們實際進行狀態更改的地方,并且它會接受state作為第一個引數:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 變更狀態
      state.count++
    }
  }
})
View Code

  mutation里面handler呼叫通過store.commit來呼叫,呼叫方式有“載荷(payload)"和“物件風格”兩種方式:

  • 載荷提交方式:
    // ...
    mutations: {
      increment (state, n) {
        state.count += n
      }
    }
    store.commit('increment', 10)
  • 物件風格提交方式:
    mutations: {
      increment (state, payload) {
        state.count += payload.amount
      }
    }
    store.commit({
      type: 'increment',
      amount: 10
    })

    一條重要的原則:mutation必須是同步函式,在組件中使用this.$store.commit('***')提交mutation,或者使用mapMutations輔助函式將組件中的methods映射為store.commit呼叫, 

 

2.4 Vuex之Action和mapActions

  Action類似于mutation,但是Action提交的是mutation,不能直接變更狀態;另外Action可以包含任意異步操作,在組件中使用this.$store.dispatch('***')呼叫action,或者使用mapActions輔助函式將組件中的methods映射為store.dispatch呼叫,

 

State、Getter、Mutation、Action的一些應用測驗代碼見:https://github.com/xiaotanit/tan_vue/blob/master/src/views/vuex/VuexPageB.vue

 

3、Vuex之模塊化(Module)

   由于使用單一狀態樹,應用的所有狀態(資料)會集中到一個比較大的物件,當應用變得非常復雜時,store物件就有可能變得相當臃腫,為了解決這種問題,Vuex允許我們將store分隔成模塊(module),每個模塊都有自己的state、mutation、action、getter、甚至是嵌套子模塊,

  默認情況下,模塊內容的action、mutation和getter是注冊在全域命名空間的,這樣使得多個模塊能夠對同一mutation或action作出回應,因此為了讓模塊具有更高的封裝度和復用性,我們可以在每個子模塊中添加namespaced: true屬性,這樣表示該模塊成為了帶命名空間的模塊,這樣后面再呼叫該模塊的getter、action和mutation時需要帶上該模塊名稱+呼叫的屬性或方法,下面寫一個示例代碼:

  新建三個js檔案moduleA.js、moduleB.js、moduleStore.js,其中moduleA和moduleB分別為子模塊,

moduleA.js:

const state = {
    countA: 99
}

const mutations = {
    increment(state){
        state.countA++
    },
    decrement(state){
        state.countA--
    }
}

const getters = {
    doubleCount(state){
        return state.countA * 2
    }
}

const actions = {
    add({ commit }){
        setTimeout(function(){
            commit('increment')
        }, 50)
    },
    minus({ commit }){
        setTimeout(()=>{
            commit('decrement')
        }, 500)
    }
}

export default {
    namespaced: true, //表示設定命名空間
    state,
    mutations,
    getters,
    actions
}
View Code

moduleB.js: 

const state = {
    countB: 11
}

const mutations = {
    increment(state){
        state.countB++;
    },
    decrement(state){
        state.countB--;
    }
}

//getters類似state里面屬性的計算屬性
const getters = {
    doubleCount(state){
        return state.countB * 2;
    }
}

const actions = {
    add({ commit }){
        commit('increment')
    },
    minus({ commit }){
        commit('decrement')
    }
}

export default {
    namespaced: true,
    state,
    getters,
    mutations,
    actions
}
View Code

moduleStore.js: 

/*
*  當專案大了后,為了責任清晰,目標明確,更易管理,將store拆成多個module形式
* */
import moduleCountA from './moduleA'
import moduleCountB from './moduleB'
import vuex from 'vuex'
import vue from 'vue'
vue.use(vuex)

export default new vuex.Store({
    modules: {
        moduleCountA,
        moduleCountB
    }
})

  再新建一個VuexPageC.vue頁面,測驗呼叫,js代碼如下:

import { mapGetters, mapActions, mapMutations } from 'vuex'

    export default {
        computed:{
            ...mapGetters({
                doubleCountA: 'moduleCountA/doubleCount',
                doubleConunB: 'moduleCountB/doubleCount'
            })
        },
        methods: {
            ...mapActions({
                //moduleA模塊的actions
                addCountA: 'moduleCountA/add',
                minusCountA: 'moduleCountA/minus',
                //moduleB模塊的actions
                addCountB: 'moduleCountB/add',
                minusCountB: 'moduleCountB/minus'
            }),
            ...mapMutations({
                //moduleA模塊的mutions
                incrementA: 'moduleCountA/increment',
                decrementA: 'moduleCountA/decrement',
                //moduleB模塊的mutions
                incrementB: 'moduleCountB/increment',
                decrementB: 'moduleCountB/decrement'
            }),
        }
    }

頁面效果如圖:

完整VuexPageC.vue頁面代碼見:https://github.com/xiaotanit/tan_vue/blob/master/src/views/vuex/VuexPageC.vue

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/147688.html

標籤:JavaScript

上一篇:JavaScript之DOM基礎

下一篇:JavaScript中,陣列和物件的遍歷方法總結

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more