Одним из способов было бы сделать ваши ссылки регулярными и сортируемыми, а затем найти текущую позицию в отсортированном списке ссылок, чтобы выяснить, какой из них является правильным предыдущим.
Например, создайте метод для вычисленияссылка из индексов, поэтому вам не нужно повторять код.В этом случае я сделал ref 'inputFieldXXXXYYYY', где XXXX - родительский индекс, а YYYY - дочерний индекс:
ref(parent, child) {
let me = 'inputField' + parent.toString().padStart(4, '0');
if (child !== undefined) me += child.toString().padStart(4, '0');
return me;
},
Затем в вашем шаблоне используйте ref (index) для родителя и ref (index, childIndex) для потомков:
<div id="main">
<div v-for="(task, index) in taskList">
<input :ref="ref(index)" type="text" v-model="task.taskName" @keydown.up="arrowPress(index)">
<div v-for="(child, childIndex) in task.children">
<input :ref="ref(index, childIndex)" type="text" v-model="task.taskName" @keydown.up="arrowPress(index, childIndex)">
</div>
</div>
</div>
Затем в функции arrowPress дети найдены в отсортированном списке в правильном месте, и вы можете уменьшить индекс, чтобы найти предыдущую ссылку:
arrowPress(parent, child) {
let refs = Object.keys(this.$refs).filter(key => key.indexOf('inputField') === 0).sort();
let i = refs.indexOf(this.ref(parent, child));
i = Math.max(i - 1, 0);
let prevRef = refs[i];
this.$nextTick(() => this.$refs[prevRef][0].focus());
}
Это работает для нажатий вверх.Вы можете видеть, как это будет распространяться на стрелки вниз.
Рабочая скрипка: https://jsfiddle.net/jmbldwn/a1sjk75r/24/
Для комментариев, здесь есть потенциально более простой способ, который включает в себя выравнивание структуры с последующим использованием одного v-для в шаблоне:
https://jsfiddle.net/jmbldwn/u0anzm35/7/