Vuex
Core
observer
js
export const createObserver = () => {
const map = new Map();
return {
notify: createNotify(map),
observe: createObserve(map)
};
};
const createNotify = (map) => (key, value) => {
const fns = map.get(key);
fns.forEach(fn => fn(value))
};
const createObserve = (map) => (key, fn) => {
map.has(key) || map.set(key, new Set());
const observers = map.get(key);
observers.add(fn);
};
vuex
js
import {createObserver} from './observer.js';
export const createStore = ({state, mutation, actions}) => {
const observer = createObserver();
const innerState = ref(state);
const commit = (mutationName, payload) => {
const oldValue = innerState.value;
const newValue = mutation[mutationName](oldValue, payload);
innerState.value = newValue;
detectMutation(oldValue, newValue);
};
const detectMutation = (oldValue, newValue) => {
Object
.keys(oldValue)
.forEach((key) => {
if (oldValue[key] !== newValue[key]) {
observer.notify(key, newValue[key])
}
});
};
const context = {
commit,
get state () {
return innerState.value;
},
};
const dispatch = (actionName, payload) => {
actions[actionName](context, payload);
};
return {
dispatch,
observe: observer.observe,
}
};
const ref = (value) => ({value});
Consumer
store module
js
import {createStore} from './core/vuex.js';
export const store = createStore({
state: {
presentation: null,
name: '',
age: '',
},
mutation: {
mutatePresentation: (state, presentation) => {
return {...state, presentation}
},
mutateName: (state, name) => {
return {...state, name}
},
mutateAge: (state, age) => {
return {...state, age}
}
},
actions: {
updatePresentation: (context, payload) => {
context.commit('mutatePresentation', payload);
},
updatePersonInfo: (context, {name, age}) => {
console.log(context.state);
context.commit('mutateName', name);
context.commit('mutateAge', age);
}
}
});
index
js
import {store} from './store.js'
store.observe('presentation', (presentation) => {
console.log(presentation);
});
store.observe('name', (name) => {
console.log(`My Name is ${name}`);
});
store.observe('age', (age) => {
console.log(`I'm ${age}`);
});
store.dispatch('updatePersonInfo', {
name: 'Peter',
age: 10,
});
store.dispatch('updatePresentation', '<div></div>');