console
class Redux {
constructor(reducer) {
this.state = {}
this.reducer = reducer
this.listeners = []
}
getState() {
return this.state
}
dispatch(action) {
this.state = this.reducer(this.state, action)
this.emit()
}
subscribe(listener) {
this.listeners.push(listener)
}
emit(type) {
this.listeners.forEach(listener => listener())
}
offSubscribe(listener) {
const index = this.listeners.indexOf(listener)
this.listeners.splice(index, 1)
}
onceSubscribe(listener) {
const listenerWrap = (...args) => {
listener(...args)
this.offSubscribe(listenerWrap)
}
this.subscribe(listenerWrap)
}
}
const reducer = (state, action = {}) => {
if (!state.value) {
state.value = 0
}
switch (action.type) {
case 'ADD':
state.value += action.payload
break
case 'REDUCE':
state.value -= action.payload
break
default:
}
return state
}
const store = new Redux(reducer)
const text = document.querySelector('#text')
text.value = store.getState().value || 0
const subscribeListener = () => {
text.value = store.getState().value
}
store.subscribe(subscribeListener)
console.log(store)
document.querySelector('#add').addEventListener('click', e => {
store.dispatch({
type: 'ADD',
payload: 1
})
})
document.querySelector('#reduce').addEventListener('click', e => {
store.dispatch({
type: 'REDUCE',
payload: 1
})
})
document.querySelector('#off').addEventListener('click', e => {
store.offSubscribe(subscribeListener)
})
<div>
<input type="text" id="text" readonly>
</div>
<br>
<div>
<button id="add">增加+</button>
<button id="reduce">减少-</button>
</div>
<br>
<div>
<button id="off">取消订阅</button>
</div>