Parse experiments - Vue setter on _data

node v10.24.1
version: 2.0.1
endpointsharetweet
const Parse = require("parse-self-host") const get = require('lodash/get') const set = require('lodash/set') const clone = require('lodash/clone') const Vue = require('vue@2.6.12') // instead of obj.set, use setPath, so that we can use Vue's internals to set the data reactively Parse.Object.prototype.setPath = function setPath (key, val) { const paths = key.split('.') if (paths.length === 1) { // use vue's internals to set reactivity on the _data object set inside a Parse.Object instance // strip away frozen-ness of the attribute, in case val is an object Vue.set(this._data, key, clone(val)) return this.set(key, val) } const rootKey = paths.shift() const root = get(this.attributes, rootKey) || {} set(root, paths, clone(val)) Vue.set(this._data, rootKey, root) // same, see as above - I set the root key in case the rootKey doesn't exist, and you're trying to set data nested within that - can cause problems with reactivity in Vue, this is safer return this.set(rootKey, root) } // create a new class from extended Parse.Object prototype class Meal extends Parse.Object { constructor () { super('Meal') Vue.set(this, '_data', {}) // reactive setter, sets our base data object } } const meal = new Meal () meal.setPath('label', 'Potatoes') // reactively set on _data.label meal.setPath('category', 'Dinner') // reactively set on _data.category const vue = new Vue({ data () { return { // bind the Parse.Object to the vue instance so the ui updates when the reactive data changes meal: meal // note: using meal.attributes in the UI is NOT reactive because its a frozen object // note: using {{ meal.get('label') }} in the UI template won't update because Vue doesn't know to re-call the #get function so no updates here either } }, // this is only here to test the assertion that the UI will update when the data changes, the two are equivalent watch: { // this watcher will fire anytime anything in the meal._data changes // and log the contents of the entire _data object 'meal._data': { deep: true, handler (val) { console.log('watch:_data', val) } }, // this watcher only watches for the label property // updates here are equivalent to changes to {{ meal._data.label }} in the ui template 'meal._data.label' (val, oldVal) { console.log('watch:_data.label', val, oldVal) } } }) // manually update by calling the setter (eg on select item from a select input) // meal.setPath('category', 'Breakfast') // auto real-time updates to the reactive object by binding to form input control meal._data.label = 'Toast'
Loading…

no comments

    sign in to comment