Vue - использование шаблона $ emit, .sync с необязательным реквизитом - PullRequest
0 голосов
/ 31 декабря 2018

Если у меня есть необязательный реквизит, можно ли вывести (используя $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)
      }
    }
  }
}

Это работает, но есть ли лучший способ?

...