状态与变更
export default new Vuex.Store(
{ state: { count:0 },
mutations: { add(state) { state.count++ } }
})
派生状态
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']) }
}
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
}
})
vuex在vue中源码实现
YStore.js
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
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。