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

时间:2018-12-31 10:47:21

标签: vue.js vuejs2 vue-component

如果我有一个不需要的道具,可以在子组件中发射(使用$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)
      }
    }
  }
}

这可行,但是有更好的方法吗?

0 个答案:

没有答案