狀態與變動
export default new Vuex.Store(
{ state: { count:0 },
mutations: { add(state) { state.count++ } }
})vue
派生狀態
export default new Vuex.Store(
{ getters: { todoCount(state) {
return state.todos.filter(todo=>!todo.completed).length } }
})
異步操做
export default new Vuex.Store({ actions: { someAction(context) { // do something context.state;
//訪問狀態 context.commit()
// 提交變動 context.dispatch();// 派發動做 } } })
簡化方法
export default { computed: { ...mapState(['isLogin']), ...mapGetters(['loginState']) },
methods: { ...mapActions(['login']) }
}vuex
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const cart = { state: { list: [] }, mutations: { addCart (state, good) { const ret = state.list.find(v => v.id === good.id) if (ret) { ret.count += 1 } else { state.list.push({good, count: 1, active: true}) } } } } export default new Vuex.Store({ state: { isLogin: false }, getters: { loginState (state) { return state.isLogin ? '歡迎回來as' : '遊客' } }, mutations: { login (state) { state.isLogin = true } }, actions: { // {commit}就是結構賦值 requestLogin (contxt, payload) { console.log(contxt) console.log(payload) // 異步操做,成功與否告訴外界 return new Promise(resolve => { setTimeout(() => { contxt.commit('login') resolve(true) }, 1000) }) } }, modules: { cart } })
YStore.jsapp
import Vue from 'vue' class YStore { constructor (options) { this.state = options.state this.mutations = options.mutations this.actions = options.actions // 借用Vue自己數據響應機制 this.vm = new Vue({ data: { state: this.state } }) } commit (type, payload) { const mutation = this.mutations[type] mutation(this.state, payload) } dispatch (type, payload) { const action = this.actions[type] const ctx = { commit: this.commit, state: this.state, dispatch: this.dispatch } return action(ctx, payload) } } export default new YStore({ state: {count: 1}, mutations: { add (state) { state.count++ } } })
組件中使用異步
<template> <div id="app"> {{getNum}} <button @click="onAdd">add</button> </div> </template> <script> import store from './YStore' export default { name: 'App', computed: { getNum () { return store.state.count } }, methods: { onAdd () { store.commit('add') } } } </script>
**Vuex也是一個插件
實現四個東西:state,mutations/actions/getters
建立Store
數據響應式**函數
let vue function install (_vue) { Vue = _vue // 這樣store執行的時候,就有了vue,不用import // 這也是爲啥vue.use必須在新建store以前 Vue.mixin({ beforeCreate () { // 這樣才能獲取到傳遞進來的store // 只有root元素纔有store,因此判斷一下 if (this.$options.store) { Vue.prototype.$store = this.$options.store } } }) } class Store { constructor (options = {}) { this.state = new Vue({ data: options.state }) this.mutations = options.mutations || {} this.actions = options.actions options.getters && this.handleGetters(options.getters) } // 注意這裏用箭頭函數形式,後面的action實現時會有做用 commit = (type, arg) => { this.mutations[type](this.state, arg) } dispatch = () => { this.actions[type]({commit: this.commit, state: this.state}, arg) } handleGetters (getters) { this.getters = {} // 定義this.getters // 遍歷getters選項,爲this.getters定義property // 屬性名就是選項中的key,只須要定義get函數保證其只讀性 Object.keys(getters).forEach(key => { Object.defineProperty(this.getters, key, { get: () => { // 注意依然是箭頭函數 return getters[key](this.state) } }) }) } } export default { Store, install }