Vue.js 如何为嵌套的v-for创建唯一的ref?

Vue.js 如何为嵌套的v-for创建唯一的ref?,vue.js,v-for,Vue.js,V For,我有一个嵌套的对象数组,如下所示: taskList: [{ taskName: "Number One" },{ taskName: "Number Two", children: [{ taskName: "Child One" },{ taskName: "Child due" }] },{ taskName: "Number Three" }]}

我有一个嵌套的对象数组,如下所示:

    taskList: [{
      taskName: "Number One"
    },{
      taskName: "Number Two",
      children: [{
        taskName: "Child One"
      },{
        taskName: "Child due"
      }]
    },{
      taskName: "Number Three"
      }]}
  <div v-for="(task, index) in taskList">
      <input :ref="'inputField' + index" type="text" v-model="task.taskName" @keydown.up="arrowPress(index, -1)">
      <div v-for="(childOne, childOneIndex) in task.children">
            <input ref="inputField" type="text" v-model="task.taskName" @keydown.up="arrowPress(childOneIndex, -1)">
      arrowPress(index, value) {
      this.$nextTick(() => this.$refs['inputField'+ (value + index)][0].focus());
      }
我使用嵌套的v-for循环遍历此列表,并为每个元素创建一个输入,如下所示:

    taskList: [{
      taskName: "Number One"
    },{
      taskName: "Number Two",
      children: [{
        taskName: "Child One"
      },{
        taskName: "Child due"
      }]
    },{
      taskName: "Number Three"
      }]}
  <div v-for="(task, index) in taskList">
      <input :ref="'inputField' + index" type="text" v-model="task.taskName" @keydown.up="arrowPress(index, -1)">
      <div v-for="(childOne, childOneIndex) in task.children">
            <input ref="inputField" type="text" v-model="task.taskName" @keydown.up="arrowPress(childOneIndex, -1)">
      arrowPress(index, value) {
      this.$nextTick(() => this.$refs['inputField'+ (value + index)][0].focus());
      }
这对家长来说效果很好

但我也希望能够在孩子们之间移动。也就是说,当我把焦点放在“3号”上时,我想先转到“儿童2号”,然后再转到“儿童1号”,然后再转到“2号”,等等

我可以找到一些解决方案,但还没有找到如何让其中任何一个发挥作用的方法:

  • :ref=“'inputField'+index”
    更改为
    ref=“inputField”
    。但是我怎么知道inputField调用什么来更改它+-1呢?例如,如何在我的方法中从inputField2转到inputField1
  • 添加一个在每次添加输入时都执行++的常规计数器,并使用
    :ref=“'inputField'+counter”
    。然而,每当我试图通过在v-for div之后添加
    {{counter++}}
    来实现这一点时,我就会得到一个infite循环
  • 还有其他想法吗

  • 提前谢谢

    一种方法是使引用规则化和可排序,然后在已排序的引用列表中找到当前位置,以确定哪一个是正确的前一个引用

    例如,创建一个从索引计算ref的方法,这样就不需要重复代码。在本例中,我将ref设置为“inputFieldXXXXYYYY”,其中XXXX是父索引,yyy是子索引:

        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>
    
    这适用于向上箭头按压。您可以看到它将如何延伸到向下箭头

    工作小提琴:

    根据评论,这里有一种可能更简单的方法,包括展平结构,然后在模板中使用单个v-for:


    您是从儿童中的道具中调用
    箭头按钮
    ,还是处理该功能?原因是如果您使用来自父级的道具,您可以调用子函数或使用事件侦听器当前它位于同一组件中,但将来可能会移动到子组件。感谢您的回复!当你尝试小提琴的时候,焦点移动的很好,除了孩子一号。从那以后,它跳过了父母(第二位),而转到了第一位。哎呀,我的糟糕。0 !== 未定义。固定的!谢谢你在这方面的帮助!它现在确实在两方面都起作用。我仍然想知道是否有一个“更简单”的解决方案。当然,有可能。一种方法可能是首先将数据结构扁平化为一个简单的数组,其中索引将是单调的和确定性的。不确定这是否简单。添加了一个摆弄扁平化方法。它失去了父子关系,因此它可能有一个缺点,这取决于你的应用程序正在做什么。