Если у меня есть необязательный реквизит, можно ли вывести (используя $emit('update:<prop name>', value)
) его в дочернем компоненте и обновить его до испущенного значения без родительского компонента, имеющего пример :<prop name>.sync="<data name>"
дочерний компонент:
Vue.component('child-component', {
props: {
bar: {
type: String,
default: () => 'foo'
}
},
methods: {
doSomethingWithBar () {
this.$emit('update:bar', 'bar')
}
},
template: '<button @click="doSomethingWithBar">{{ bar }}</button>'
})
пример родителя:
<child-component /> <!-- notice no :bar.sync -->
Пример на codepen: https://codepen.io/anon/pen/jXaGJg
Мое текущее решение:
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)
}
}
}
})
Но это требует большого количества ненужного кода, и я уверен, что есть лучшая идея.
ОБНОВЛЕНИЕ: (Фактический контекст)
Я проектирую аудиокомпонент, который оборачивает элементы управления и воспроизводит аудио.
Пример для audio.loop
(мне нужно было бы сделать что-то похожее на currentTime, пауза, громкость и т. Д.):
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)
}
}
}
}
Это работает, но есть ли лучший способ?