vuex的原理:
Vuex 全局維護着一個對象,使用到了單例設計模式。在這個全局對象中,所有屬性都是響應式的,任意屬性進行了改變,都會造成使用到該屬性的元件進行更新。并且隻能通過
commit
的方式改變狀态,實作了單向資料流模式。
state-> mutation-> action -> 更新渲染
vuex的優點:
最主要解決了元件之間共享同一狀态(資料變量)的問題。可以把元件的共享狀态提取出來,作為全局來管理。
(否則依靠on和dispatch,props 隻能進行父子元件間的資料傳遞) 父子/同級/跨級
Vuex應用場景?
如果不打算開發大型單頁應用,使用 Vuex 可能是繁瑣備援的。确實是如此——如果您的應用夠簡單,最好不要使用 Vuex。一個簡單的 global event bus 就足夠您所需了。但是,如果您需要建構是一個中大型單頁應用,很可能會考慮如何更好地在元件外部管理狀态,Vuex 将會成為自然而然的選擇。
Vuex核心
每一個Vuex應用的核心就是store(倉庫), store是儲存應用中大部分的狀态。
結構 建立一個store檔案夾,裡面建立 index.js ,types.js ,state.js ,getters.js , mutations.js , actions.js
store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state';
import mutations from './mutations';
import actions from './actions';
import getters from './getters';
Vue.use(Vuex);
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
store/types.js
//getters types
export const GET_THEMES = 'GET_THEMES';
//actions types
export const FETCH_THEMES = 'FETCH_THEMES';
//mutations types
export const MODIFY_THEMES = 'MODIFY_THEMES';
store/state.js
export default {
themes: []
}
store/getters.js
import * as types from './types';
export default {
[types.GET_THEMES]: state => {
return state.themes
}
}
store/mutations.js
import * as types from './types';
export default {
[types.MODIFY_THEMES](state, all) {
state.themes = all
}
}
store/actions.js
import axios from "axios";
import * as types from './types';
const baseURL = '/api/';
export default {
[types.FETCH_THEMES]({commit}) {
axios.get(baseURL + "themes").then(res => {
commit(types.MODIFY_THEMES, res.data.others)
//commit(types.MODIFY_THEMES, res.data.others)可進行多個改變
}).catch(err => console.log(err))
}
}
使用方法
(如何在元件中綁定事件)
① 擷取變量值
import { mapGetters } from "vuex";
computed: {
...mapGetters(["GET_THEMES", "GET_RECOMMENDLIST", "GET_ISLOADING"])
}
這樣就可以在元件中直接使用變量GET_THEMES(return state.themes)
② 觸發mutations,同步改變變量值
this.$store.commit("MODIFY_ISLOADING",newValue);
③ 觸發actions,異步改變變量值
this.$store.dispatch("FETCH_THEMES");
其他元件間通信方式:
① 父傳子:props
② 子傳父:通過 this.$emit 觸發事件, this.$on 監聽事件
③ 非父子:中央事件總線 ,然後通過 bus.$emit 觸發事件,bus.$on 監聽觸發的事件。
Vue.component('brother1',{
data(){
return {
mymessage:'hello brother1'
}
},
template:`
<div>
<p>this is brother1 compoent!</p>
<input type="text" v-model="mymessage" @input="passData(mymessage)">
</div>
`,
methods:{
passData(val){
//觸發全局事件globalEvent
bus.$emit('globalEvent',val)
}
}
})
Vue.component('brother2',{
template:`
<div>
<p>this is brother2 compoent!</p>
<p>brother1傳遞過來的資料:{{brothermessage}}</p>
</div>
`,
data(){
return {
mymessage:'hello brother2',
brothermessage:''
}
},
mounted(){
//綁定全局事件globalEvent
bus.$on('globalEvent',(val)=>{
this.brothermessage=val;
})
}
})
//中央事件總線
var bus=new Vue();
var app=new Vue({
el:'#app',
template:`
<div>
<brother1></brother1>
<brother2></brother2>
</div>
`
})
結束
如果文章對你有幫助,麻煩點贊哦!一起走碼農花路~