Emit input event on click кнопки, чтобы программно изменить v-модель ввода

Я пытаюсь сделать пользовательский input number с помощью кнопок + и -, чтобы увеличить или уменьшить текущее value полученное с помощью http request , если я набираю числа непосредственно на input это меняет значение, и когда я сохраняю содержимое с помощью form POST это работает, но если я выполню element.stepUp / Down, значение, похоже, изменится, но полученное значение через POST будет таким же, как и оригинал.

Я пытался trigger событие ввода с this.$emit('input', newValue) но это не работает, потому что я не могу указать цель, которая будет изменена. Я попытался запустить пользовательское событие this.$emit('spin-button', value) но вход не может прослушать выпущенное событие с помощью v-on:spin-button="myFunc()" .

v-model не может быть data variable потому что это динамическая форма, которая содержит более 100 inputs .

Мне нужно только отправить событие ввода, когда я нажимаю кнопки прокрутки после того, как я делаю stepUp / Down, чтобы изменить значение, но я не могу его достичь.

Есть ли способ передать событие другому элементу? Как правильно сделать это и изменить значение модели? Я пробовал с :value но результат тот же.

const app = new Vue({
  methods: {
    showVal(data){
      console.log(data)
    }
  },
  incrementDecrementNumber(action, event) {
			switch (action) {
				case "+": {
					event.target.parentElement.previousElementSibling.stepUp()
					break;
				}
				case "-": {
					event.target.parentElement.nextElementSibling.stepDown()
					break;
				}
			}
		},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">


<div class="input-group mb-3 mx-auto col-md-6 border-dark" v-if="question.type.code === 'NI'">
		<div class="input-group-prepend">
				<button class="btn btn-circle" @click="incrementDecrementNumber('-', $event)">-</button>
		</div>
		<input
			type="number"
			class="form-control text-center form-control-lg"
			@input="showVal($event)"
			name="`test_1_question_5"
			v-model.number="question.stored_data.answer"
		/>
														
		<div class="input-group-append">
			<button class="btn btn-circle" @click="incrementDecrementNumber('+', $event)">+</button>
		</div>
</div>

Всего 1 ответ


Вы можете создать свой собственный компонент, чтобы лучше контролировать происходящее. Это также позволит вам легко использовать его в других местах.

Ниже приведен минимальный пример того, как вы можете это сделать, но его можно расширить для большей гибкости.

Vue.component('spin-button', {
  template: '#spin-button',
  props: {
    'value': {
      required: true
    }
  },
  computed: {
    internalValue: {
      get() {
        return this.value;
      },
      set(value) {
        this.$emit('input', value)
      }
    }
  },
  methods: {
    incrementDecrementNumber(action) {
      switch (action) {
        case "+":
          this.$refs['input'].stepUp()
          break;
        case "-":
          this.$refs['input'].stepDown()
          break;
      }
      /* Need to manually $emit here since the above methods doesn't trigger our computed set method. */
      this.$emit('input', this.$refs['input'].value)
    }
  }
})

new Vue({
  el: "#app",
  data() {
    return {
      question: {
        stored_data: {
          answer: 5
        }
      }
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

<div id="app">
  <spin-button v-model="question.stored_data.answer" step="5" min="0" max="100">
  </spin-button>
  {{ question.stored_data.answer }}
</div>

<template id="spin-button">
  <div class="input-group">
    <div class="input-group-prepend">
      <button 
        class="btn" 
        @click="incrementDecrementNumber('-')"
      >
        -
      </button>
    </div>
    <input type="number" ref="input" class="form-control text-center" v-model="internalValue" v-bind="$attrs" />
    <div class="input-group-append">
      <button class="btn" @click="incrementDecrementNumber('+')">
        +
      </button>
    </div>
  </div>
</template>