У меня есть вопрос о создании компонентов VueJS, которые можно использовать с v-model
, которые используют базовые value
prop и $emit('input', newVal)
.
props: {
value: Array
},
methods: {
moveIdToIndex (id, newIndex) {
const newArrayHead = this.value
.slice(0, newIndex)
.filter(_id => _id !== id)
const newArrayTail = this.value
.slice(newIndex)
.filter(_id => _id !== id)
const newArray = [...newArrayHead, id, ...newArrayTail]
return this.updateArray(newArray)
},
updateArray (newArray) {
this.$emit('input', newArray)
}
}
В приведенном выше примере кода, если я сделаю две модификациив быстрой последовательности они оба будут выполняться в «старом массиве» (неизмененном value
prop).
moveIdToIndex('a', 4)
moveIdToIndex('b', 2)
Другими словами, мне нужно дождаться, пока value
будетобновляется через $emit('input')
, чтобы второй вызов moveIdToIndex
использовал этот уже измененный массив.
Неправильное решение 1
Один обходной путь меняет updateArray
на:
updateArray (newArray) {
return new Promise((resolve, reject) => {
this.$emit('input', newArray)
this.$nextTick(resolve)
})
}
и выполнить так:
await moveIdToIndex('a', 4)
moveIdToIndex('b', 2)
Но я не хочу этого делать, потому что мне нужно выполнить это действие с массивом идентификаторов и переместить их все в разные места нав то же время.И await
IN значительно снизит производительность.
Плохое решение 2
Гораздо лучшее решение, которое я нашел, это просто сделать это:
updateArray (newArray) {
this.value = newArray
this.$emit('input', newArray)
}
Тогда я нене нужно ждать завершения $emit
.
Тем не менее, в этом случае VueJS выдает консольную ошибку:
Избегайте непосредственного изменения опоры, так как значение будетбыть перезаписано всякий раз, когда родительский компонент перерисовывается.Вместо этого используйте данные или вычисляемое свойство, основанное на значении реквизита.Подставка изменена: «значение»
У кого-нибудь есть лучшее решение?