If I have a non-required prop is it possible to emit (using $emit('update:<prop name>', value) ) it in the child component and have it update to the emitted value without the parent component having :<prop name>.sync="<data name>"
example child component:
Vue.component('child-component', {
props: {
bar: {
type: String,
default: () => 'foo'
}
},
methods: {
doSomethingWithBar () {
this.$emit('update:bar', 'bar')
}
},
template: '<button @click="doSomethingWithBar">{{ bar }}</button>'
})
example parent:
<child-component /> <!-- notice no :bar.sync -->
Example on codepen: https://codepen.io/anon/pen/jXaGJg
My current solution is:
Vue.component('child-component', {
props: {
bar: {
type: String,
default: () => 'foo'
}
},
data () {
return {
innerBar: null
}
},
mounted () {
this.innerBar = this.bar
},
methods: {
doSomethingWithBar () {
this.innerBar = 'bar'
}
},
template: '<button @click="doSomethingWithBar">{{ bar }}</button>',
watch: {
bar () {
this.innerBar = this.bar
},
innerBar () {
if (this.innerBar !== this.bar) {
this.$emit('update:bar', this.innerBar)
}
}
}
})
But this requires a lot of unnecessary code and I am quite sure there is a better idea.
UPDATE: (Actual context)
I am designing an audio component that wraps controls and playing Audio.
Example for audio.loop (I would have to do something similar to currentTime, paused, volume, etc.):
export default {
props: {
loop: {
type: Boolean,
default: () => false
},
audio: {
required: true,
type: HTMLAudioElement
},
},
data () {
return {
innerLoop: null
}
},
methods: {
toggleLoop () {
if (this.innerLoop) {
this.innerLoop = false
} else {
this.innerLoop = true
}
}
},
watch: {
loop () {
this.innerLoop = this.loop
},
innerLoop () {
this.audio.loop = this.innerLoop
if (this.innerLoop !== this.loop) {
this.$emit('update:loop', this.innerLoop)
}
}
}
}
This works but is there a better way?