store.commit('xxmutation')
修改數據mapState/mapGetters/mapMutations/mapActions
v-model
注意在computed那邊設置getter setter
<div>
<h1>{{title}}</h1>
<button @click="handleClick">將標題第一個字母大寫</button>
<div>
複製代碼
其實數據不復雜的狀況下,method就夠用的。數據複雜以後,就有點雲裏霧裏了。固然組件傳遞數據很麻煩的狀況下,vuex也是方便不少。css
vuex,其實就是管理數據的,全部數據的變化都必須經過方法add(1)
,不能直接xx.a=4
這種。而後就是專有名詞和具體用法須要記憶了。html
vuex的專業名詞:ios
new Vuex.Store({state:{},mutations:{}})
,store是倉庫,存着數據,存着改變數據的方法。data
,state:{title:'hi'}
computed
,但computed是經過this拿到data,而這裏是經過參數訪問store的state和getters,getters:{ doneTodosCount: (state,getters)=>{return getters.doneTodos.length} }
method
,仍是經過參數拿到state,參數直接放後面,mutations:{ add(state,n){ state.count + n } }
,調用的時候,store.commit('add',10)
,發現沒,傳方法名和參數就能夠了,不用傳state~commit(mutation)
,action的參數和上面都不同,其是store實例,能夠拿到store因此的東西,但通常commit居多,actions:({ add({commit}){commit('add')} })
,觸發的方式store.dispatch('add')
,這樣感覺不到異步的特殊性,換種方式actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
複製代碼
action這邊,其實特別重要,由於請求基本都是異步的,這邊寫下,結合請求使用actionvuex
state:{
listData:[]
},
mutations:{
setListData(state,data){
state.listData = data
}
},
// 另外的文件裏,export function getList(){ return axios.get('/list').then(res => res.data)}
actions: {
async setListData ({ commit }) {
commit('setListData', await getList())
},
async setOtherListData ({ dispatch, commit }) {
// 若是有串聯請求 先請求這個
await dispatch('setListData')
commit('setOtherListData', await getOtherList())
}
}
// 順便寫下 若是延時改變
actions: {
actionA ({ commit }) {
// 處理異步操做 當選promise
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
}
// 組件裏 1s以後變值
store.dispatch('actionA').then(() => { ... })
// 或者
store.dispatch('actionB')
複製代碼
const moduleA = { state: { ... }, mutations: { add(state,n){state.count+n} }, actions: { ... }, getters: { ... } }
const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } }
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
},
state:{}
})
store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態
複製代碼
首先store是掛載在vue實例上的,因此全部的組件都能訪問到store,new Vue({store})
。axios
/* xx.vue v1.0.0 */
computed: {
count () {
// count就是在store那邊
// Vuex 經過 store 選項,提供了一種機制將狀態從根組件「注入」到每個子組件中,這樣子組件經過this.$store就能夠訪問
return this.$store.state.count
},
isLogin () {
return this.$store.state.isLogin
}
}
/* 可是當屬性不少的時候,這樣寫太冗餘了 用數組簡化下 v2.0.0 */
let res = {}
['count', 'login'].map(prop => { res[prop] = () => this.$store.state[prop] })
// 用的時候
computed:{...res}
/* 索性能夠定義成一個方法 v3.0.0 */
function mapState(propArr){
let res = {}
propArr.map(prop => { res[prop] = () => this.$store.state[prop] })
return res
}
// 用的時候
computed:{...mapState(['count', 'login'])}
/* 固然咱們能想到的,vuex早就替咱們想到了,因此vuex本身提供了mapState v4.0.0 */
// 固然mapState還能夠對象形式,能夠去官網看看
import { mapState } from 'vuex'
computed:{...mapState(['count', 'login'])}
複製代碼
用法同state,不贅述。api
import { mapGetters } from 'vuex'
computed:{...mapGetters(['count', 'login'])}
複製代碼
其實知道state的用法,這邊就簡單多了,兩種形式,下面也寫個例子:數組
// mutation怎麼寫的 回憶下 add(state,n){state.count+n}
/* 1. 直接組件裏 this.$store.commit('add',1) */
/* 2. 組件裏 把mutation放進methods */
methods:{
add (n) {
this.$store.commit('add', n)
}
}
// 多個的話
import { mapMutations } from 'vuex'
methods:{
...mapMutations(['add'])
}
複製代碼
用法同mutations,不贅述。promise
/* 1. 直接組件裏 this.$store.dispatch('add',1) */
/* 2. 組件裏 把actions放進methods */
import { mapActions } from 'vuex'
methods:{...mapActions(['add'])}
複製代碼
v-model會直接改變數據,違背了vuex
,因此不能像以前那樣寫,換個寫法異步
// <input v-model="message">
// store.js
mutations: {
updateMessage (state, message) {
state.obj.message = message
}
}
// xx.vue
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
複製代碼
應用層級的狀態應該集中到單個 store 對象中。
提交 mutation 是更改狀態的惟一方法,而且這個過程是同步的。
異步邏輯都應該封裝到 action 裏面。