Vue.js Vue-使用$emit、.sync模式和不需要的道具

Vue.js Vue-使用$emit、.sync模式和不需要的道具,vue.js,vuejs2,vue-component,Vue.js,Vuejs2,Vue Component,如果我有一个非必需的道具,是否可以在子组件中发射(使用$emit('update:',value))它,并在父组件没有:.sync=”“ 示例子组件: Vue.component('child-component', { props: { bar: { type: String, default: () => 'foo' } }, methods: { doSomethingWithBar () { this.$em

如果我有一个非必需的道具,是否可以在子组件中发射(使用
$emit('update:',value)
)它,并在父组件没有
:.sync=”“

示例子组件:

Vue.component('child-component', {
  props: {
    bar: {
      type: String,
      default: () => 'foo'
    }
  },

  methods: {
    doSomethingWithBar () {
      this.$emit('update:bar', 'bar')
    }
  },

  template: '<button @click="doSomethingWithBar">{{ bar }}</button>'
})

这很有效,但有更好的方法吗?

你为什么要这样做?您的道具
bar
看起来像一个内部数据项我的实际代码是一个环绕HTML音频API的音频组件。我希望组件中显示一个
currentTime
的道具,使用
'timeupdate'
事件进行更新,并且我希望组件的用户能够通过道具设置
currentTime
,所以您希望当前时间的真相来源在两个地方?是通过
timeupdate
事件设置,还是由用户通过道具设置?还是希望道具仅作为初始默认值?为什么不将当前时间显示拖出到它自己的组件中,并且只让父级管理时间?然后,父级可以直接或从事件中更新时间。你的问题似乎简化得太多了,以至于所有的上下文都丢失了,这看起来像是一个XY问题。如果家长必须管理时间,那么这将完全破坏组件的使用,因为家长可能有数百个这样的组件。当父级设置
currentTime
时,它应该覆盖
audio.currentTime
-有点像用户通过单击来寻找某个特定时间。@chipit24我添加了一些上下文,也许它会解释得更好
<child-component /> <!-- notice no :bar.sync -->
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)
      }
    }
  }
})
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)
      }
    }
  }
}