Sync in Vue 2.x with Mixin
by asemahle
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
<div id="app">
<p>
Value in parent: {{title}}
</p>
<custom-component :value_sync="title" v-on:value-change="title = arguments[0]"></custom-component>
<button v-on:click="title = 'Changed From Parent!'">CHANGE FROM PARENT</button>
</div>
<template id="custom-component">
<div>
<p>
Value in child: {{value}}
</p>
<button v-on:click="value = 'Changed From Child!'">CHANGE FROM CHILD</button>
</div>
</template>
JavaScript
var SyncMixin = {
created: function () {
for (let propName of this.$options._propKeys) {
// only sync props ending with '_sync'
if (!propName.endsWith('_sync')) continue;
dataName = propName.slice(0, propName.length - 5);
//only sync props if there's matching data
if (!(dataName in this.$data)) continue;
//initially set data equal to prop
this.$data[dataName] = this[propName];
// reset data to prop when prop changes
this.$watch(propName, (newVal, oldVal) => {
this.$data[dataName] = this[propName];
});
// emit changed event when data changes
this.$watch(dataName, (newVal, oldVal) => {
this.$emit(dataName + '-change', newVal);
});
}
},
}
Vue.component('custom-component', {
template: '#custom-component',
mixins: [SyncMixin],
props: ['value_sync'],
data: function() {
return {
value: null,
}
}
});
var app = new Vue({
el: '#app',
data: {
title: 'Original Value',
}
});