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?
- 安裝Vuex,再通過
import Vuex from 'vuex'
引入 - 先 var store = new Vuex.Store({...}),再把store作為參數的一個屬性值,new Vue({store})
- 通過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