如果我有一个不需要的道具,可以在子组件中发射(使用$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)
}
}
}
}
这可行,但是有更好的方法吗?