Created
August 2, 2018 11:56
-
-
Save mikeapr4/ed34e071d7ed563a3747cfbaf67ba4c6 to your computer and use it in GitHub Desktop.
Reactive-compatible Moment.js Instances
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import moment from 'moment'; | |
import 'moment-timezone'; | |
// Make all fields on `object` hidden (not enumerable) | |
// except any in the whitelist. | |
const hideFields = (object, whitelist) => Object.keys(object) | |
.forEach((field) => { | |
if (!whitelist.includes(field)) { | |
const val = object[field]; | |
Object.defineProperty(object, field, { | |
value: val, | |
configurable: true, | |
writable: true, | |
enumerable: false, | |
}); | |
} | |
}); | |
/** | |
* Modify Moment locales and timezones so that only the identifier field | |
* is enumerable, this way the other data will be hidden from reactivity. | |
* | |
* Individual Moment instances can be reactive and if they have Locale or TZ | |
* changed, it will trigger reactivity, but changes to the Locale or TZ | |
* shared objects won't cause problems. | |
*/ | |
moment.locales().forEach((code) => { | |
const locale = moment.localeData(code); | |
hideFields(locale, ['_abbr']); | |
}); | |
moment.tz.names().forEach((tz) => { | |
const zone = moment.tz.zone(tz); | |
hideFields(zone, ['name']); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Store } from 'vuex'; | |
const store = new Store({ | |
... | |
}); | |
const rehydrateMoments = (obj) => { | |
const queue = [obj]; | |
while (queue.length) { | |
const item = queue.shift(); | |
if (typeof item === 'object' && item !== null) { | |
if (Array.isArray(item)) { | |
queue.push(...item); | |
} else if (item._isAMomentObject) { // Found a Moment instance | |
Object.setPrototypeOf(item, moment.prototype); | |
// Reassign the TZ and Locale shared objects (only the identifier fields are in the snapshot) | |
// This also ensures the moment instance has references to Objects which themselves have | |
// the correct prototype (rather than plain Object deserialized versions) | |
item.tz(item.tz()); | |
item.locale(item.locale()); | |
} else { | |
queue.push(...Object.values(item)); | |
} | |
} | |
} | |
}; | |
const oldReplace = store.replaceState; | |
store.replaceState = function replaceState(state) { | |
rehydrateMoments(state); | |
return oldReplace.call(this, state); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
related article - https://medium.com/dailyjs/dates-in-vuex-primitives-or-complex-objects-6e6b29ebb880