AlpineJs:无法读取未定义的属性(读取 'focus')

AlpineJs : Cannot read properties of undefined (reading 'focus')

我在 codepen 中将此代码用于 OTP 输入字段

此代码在 alpine@v2.3.5 中运行良好,但升级到 v3 后显示此错误

无法读取未定义的属性(读取 'focus')

<div
  x-data="pinHandler()"
  x-init="$nextTick(() => { $refs[0].focus() })"
  class="flex items-start justify-center min-h-screen w-full bg-white p-16 pt-64">
  <div class="relative p-10 pb-8 bg-indigo-500 mx-auto max-w-md rounded-lg shadow-2xl z-50">
    <label
      for="enter-pin"
      class="block text-3xl mb-2 text-white font-extrabold text-center">Enter PIN</label>
    <form
      id="enter-pin"
      class="flex flex-row flex-wrap justify-center space-x-4"
      @submit.prevent="handleSubmit()"
      @paste.prevent="handlePaste($event)">
      <template x-for="(input, index) in Array.from({ length: length })" :key="index">
          <input
            @input.prevent="handleInput($event.target)"
            @keydown.backspace="$event.target.value || focusPreviousRef($event.target.getAttribute('x-ref'))"
            autocomplete="off"
            :aria-label="`Pin ${index + 1}`"
            data-lpignore="true"
            :x-ref="index"
            class="w-12 mb-4 rounded border border-gray-200 p-3 text-center appearance-none"
            type="text"
            maxlength="1">
      </template>
    </form>
  </div>

  <p class="absolute bottom-0" x-text="`value: ${value}`"></p>
</div>

根据 Alpine.js 升级指南,$refs 对动态创建元素的支持已弃用。

Alpine.js Upgrade guide from V2

因此,要运行上面的代码,您应该像下面这样静态地创建输入元素。 (以下代码适用于 laravel blade 模板)

<form id="enter-pin" class="flex flex-row flex-wrap justify-center space-x-4" x-on:submit.prevent="handleSubmit()" x-on:paste.prevent="handlePaste($event)">
@for($i = 1; $i <= 6; $i++)
    <input x-on:input.prevent="handleInput($event.target)" x-on:keydown.backspace="$event.target.value || focusPreviousRef($event.target.getAttribute('x-ref'))" autocomplete="off" data-lpignore="true" x-ref="{{ $i }}" class="w-12 mb-4 rounded border border-gray-200 p-3 text-center appearance-none" type="text" maxlength="1">
@endfor

绑定id怎么样?

$root.querySelector(#pin-${上一个}) document.getElementById(pin-${上一个})

           <input
              @input.prevent="handleInput($event.target)"
              @keydown.backspace="$event.target.value || focusPreviousRef(index)"
              autocomplete="off"
              :aria-label="`Pin ${index + 1}`"
              data-lpignore="true"
              {{-- :x-ref="index" --}}
              :id="`pin-${index}`"
              class="w-12 mb-4 rounded border border-gray-200 p-3 text-center appearance-none"
              type="text"
              maxlength="1">

----

    focusPreviousRef(index) {
      const previous = parseInt(index, 10) - 1
      previous_element=this.$root.querySelector(`#pin-${previous}`);

      previous_element.focus()
      previous_element.select()
    },