vuex實現數據持久化


vuex-狀態管理工具

對於vuex來說,它只是一個狀態管理工具,當有些變量不止在組件間用時,可能很多頁面都會復用。我們使用vuex進行管理。

state:設置初始值狀態。

getters:store倉庫的計算屬性,主要作用是派生出一些新的狀態。比如將state狀態的數據進行一次映射或者篩選。

mutations:對state數據進行賦值操作,並進行相應操作;利用store.commit()觸發該操作,

actions處理異步操作,可以使用commit方法,使用store.dispatch()觸發。

實現數據的持久化--跟localStorage結合使用

設置state的狀態:

const state = {
    status: '0'
};

設置getters:

    getStatus(state) {
        let t = localStorage.getItem('isLogined')
        if (t == null || t== undefined) {
            t = state.isLogined;
        }
        state.isLogined=t;
        return state.isLogined;
    }    

設置mutations:

SET_STATE(state, val) {
        state.status = val;
        try {
            localStorage.setItem('isLogined',val);
        } catch (e) {
            console.log(e);
        }
    }

使用-----在頁面的計算屬性 根據getter獲取狀態

 

computed:{
      isLogined(){
        return this.$store.getters['getStatus'];
    }   
}        

 操作----修改狀態即在方法中調用commit:

methods:{
  handleStatus(){
     this.$store.commit('SET_STATUS','1');        
  }
}

(小知識點:如果是在公共函數內調用,請引入store的index的js文件,調用store.getters和store.commit)

storage的存儲方式:

localStorage的存儲是按照字符串存儲的(以上例子為存儲字符串格式)。如果存儲為對象格式,會出現返回值是{Object object}的情況,那么,存儲時要將數據轉成string格式,請使用如下方式:

   localStorage.setItem('obj',JSON.stringfy(object));

storage的讀取和使用:

   JSON.parse(localStorage.getItem('obj'));

注意點:

getter的值是要根據依賴值進行變化的, 即如果return的返回值不是state的數據,則監聽不到數據變化。

假如只是return localStorage.getItem('status')的話, 則數據不會更新。必須進行state的賦值和return操作。

如果不需要對數據二次改造的話,也可以寫到state的初始值: status: localStorage.getItem('isLogined') || '0'。這樣的話取數據只能用this.$store.state.status來獲取了。

---同理,computed的計算屬性也應該和data的數據依賴。

 

插播一點: 可使用node require引入文件的方式  遍歷模板,避免模板過多,每次引入文件。

 

const modulesFiles = require.context('./modules', false, /\.js$/);
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'  $1是正則里邊的捕獲,(.*)內的內容;
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
  const value = modulesFiles(modulePath);
  modules[moduleName] = value.default;
  return modules;
}, {});

const store = new Vuex.Store({
  modules,
});

 

  

---------------------------------------------------------------想看原理的請繼續往下划👇,如何使用👆------------------------------------------------------------------------------------------------------------

實現原理

1、vuex本質是一個對象,有兩個屬性:install方法和Store類。

2、install方法的作用是將store這個實例掛載到所有組件。

3、Store這個類有commit,dispatch方法,store類將用戶傳入的數據包裝成data,作為new Vue的參數,從而實現state的響應式。

  • 剖析vuex本質

 

Vue項目中是怎么引入Vuex?

 

  1. 安裝Vuex,再通過import Vuex from 'vuex'引入
  2. 先 var store = new Vuex.Store({...}),再把store作為參數的一個屬性值,new Vue({store})
  3. 通過Vue.use(Vuex) 使得每個組件都可以擁有store實例

使用Vue.use(), 而 Vue.use的使用原則是執行對象的install方法。 如果參數是對象,則執行對象的install方法,如果是函數,則將函數當成install執行。

class store{

}

function install (){

}

export default {store, install}

1、插件的類型,可以是install方法,也可以是一個包含install方法的對象。

2、插件只能被安裝一次,保證插件列表中不能有重復的插件。

實現:

Vue.use = function(plugin){
 const installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
 if(installedPlugins.indexOf(plugin)>-1){
  return this;
 }
 <!-- 其他參數 -->
 const args = toArray(arguments,1);
 args.unshift(this);
 if(typeof plugin.install === 'function'){
  plugin.install.apply(plugin,args);
 }else if(typeof plugin === 'function'){
  plugin.apply(null,plugin,args);
 }
 installedPlugins.push(plugin);
 return this;
}

注意點: 首先要判斷插件是不是已經注冊過,如果注冊過,則直接終止方法。保證相同插件不會被重復加載。

通過Vue.use(Vuex) 使得每個組件都可以擁有store實例:

function install() {
  Vue.mixin({
    beforeCreate() {
      if (this.$options && this.$options.store) { //根組件,傳入vue的參數,可通過$options.store訪問。
        this.$store = this.$options.store;
      } else { //不是根組件 
        this.$store = this.$parent && this.$parent.store;
      }
    },
  });
}

mixin的作用是將mixin的內容混合到Vue的初始化options中。為什么是beforeCreate 中執行? 因為created中,$options已經初始化好了。

現在實現類store

let Vue
//myVuex.js
class Store {
    constructor(options) {
        this.vm = new Vue({
            data: {
                state: options.state
            }
        })

        let getters = options.getter || {}
        this.getters = {}
        Object.keys(getters).forEach(getterName => {
            Object.defineProperty(this.getters, getterName, {
                get: () => {
                    return getters[getterName](this.state)
                }
            })
        })

        let mutations = options.mutations || {}
        this.mutations = {}
        Object.keys(mutations).forEach(mutationName => {
            this.mutations[mutationName] = (arg) => {
                mutations[mutationName](this.state, arg)
            }
        })

        let actions = options.actions
        this.actions = {}
        Object.keys(actions).forEach(actionName => {
            this.actions[actionName] = (arg) => {
                actions[actionName](this, arg)
            }
        })

    }
    //dispatch,commit是方法;其余getter,state是屬性!!!
    dispatch(method, arg) {
        this.actions[method](arg)
    }
    commit = (method, arg) => {
        console.log(method);
        console.log(this.mutations);
        this.mutations[method](arg)
    }
    get state() {
        return this.vm.state
    }
}
let install = function (vue) {
    ×××省略
}

let Vuex = {
    Store,
    install
}

export default Vuex

 

生命周期執行順序:

data和el什么時候有數據:

 

 

參考文章:

https://zhuanlan.zhihu.com/p/166087818

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM