Vue Sync Mixin
Create two-way bindings as easily as props.
HTML
<div id="vue">
<user :firstname.sync="user.firstname" :lastname.sync="user.lastname"></user>
<user v-bind.sync="user"></user>
<wrapper :user.sync="user"></wrapper>
{{ user }}<br>
<toggler :state.sync="state"></toggler>{{ state }}
</div>
JavaScript
Vue.mixin({
beforeCreate(){
const sync = this.$options.sync
if(sync){
if(!this.$options.computed){
this.$options.computed = {}
}
const attrs = Object.keys(this.$attrs)
sync.forEach(key => {
if(!attrs.includes(key)){
Vue.util.warn(`Missing required sync-prop: "${key}"`, this)
}
this.$options.computed[key] = {
get(){
return this.$attrs[key]
},
set(val){
this.$emit('update:' + key, val)
}
}
})
}
}
})
Vue.component('user',{
sync:['firstname','lastname'], //this is the special option added by the mixin
template:`
<div>
<input v-model="firstname">
<input v-model="lastname">
</div>`
})
Vue.component('wrapper',{
sync:['user'],
template:`<user v-bind.sync="user"></user>`
})
Vue.component('toggler',{
sync:['state'],
template:`<button @click="state = !state">{{state ? 'X' : 'O'}}</button>`
})
new Vue({
el:'#vue',
data:{
user:{
firstname:'Simon',
lastname:'Herteby'
},
state:true
}
})