Vue 3 & Composition API : template refs in v-for loop error : only get proxies

Vue 3 & Composition API : template refs in v-for loop error : only get proxies

我一直在使用 Vue3.js 和 Vue Cli 开发我的第一个项目,过去几个小时我一直被这段代码困住了。

基本上我想做的是根据在代码的 setup() 部分创建的对象数组创建一个按钮列表。所有对象还在数组本身中包含它们自己的引用,我最终将其绑定到模板上。然后我从每个 ref 中创建 const,以便我可以在 setup() 中使用它们但是当我 console.log(btnConvert.value) 我得到一个代理,我没有使用我的其他 ref不在 v-for 循环中。

    RefImpl {_rawValue: Proxy, _shallow: false, __v_isRef: true, _value: Proxy}

这是 console.log(btnConvert.value)

的扩展版本
Proxy {…}
  [[Handler]]: Object
    get: ƒ get({ _: instance }, key)
    has: ƒ has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key)
    ownKeys: (target) => {…}
    set: ƒ set({ _: instance }, key, value)
  [[Prototype]]: Object
  [[Target]]: Object
  [[IsRevoked]]: false

想尽了办法,还是看不懂官方的Vue doc。 谁能帮助我了解如何使用这些引用检索 DOM 元素? 非常感谢!

这是相关代码的一部分(为了便于讲课,我删除了 btn 所指的功能)。如果需要,我可以添加更多。

    <template>
      <div>
        <div ref="btnList" class="options">
          <vBtn
            v-for="btn in btnArray"
            :key="btn"
            :ref="btn.ref"
            class="btn"
            :class="`btn--${btn.class}`"
            @click="btn.action"
            v-html="btn.text"
          />
      </div>
    </template>
    <script>
    import { ref, onMounted } from 'vue'
    import vBtn from '@/components/Tool/vBtn.vue'

    export default {
      components : {
        vBtn
      },

      setup() {
        const btnConvert = ref(null)
        const btnCopy = ref(null)
        const btnCancel = ref(null)
        const btnUndo = ref(null)
        const btnErase = ref(null)
        
        const btnArray = [
          {
            class: 'convert',
            text: 'some text',
            action: convertText,
            ref: btnConvert
          },
          {
            class: 'undo',
            text: 'some text',
            action: undoConvert,
            ref: btnUndo
    
          },
          {
            class: 'cancel',
            text: 'some text',
            action: cancelChange,
            ref: btnCancel
    
          },
          {
            class: 'erase',
            text: 'some text',
            action: eraseText,
            ref: btnErase
    
          },
          {
            class: 'copy',
            text: 'some text',
            action: copyText,
            ref: btnCopy
          }
        ]
    
        onMounted() {
          console.log(btnConvert.value)
          // this is where I get the proxy
        }
      },
    }
    </script>

很抱歉,我无法复制您的结果

  1. 我不明白你怎么能从 console.log(btnConvert.value) 得到其他东西然后 null 当你根本不渲染第一个按钮时感谢 v-for="btn in btnArray.slice(1)" (这有效地创建没有源数组中第一个元素的新数组)

  2. 它很管用!见下面的例子

请注意:

Could anyone help me understand how I could retrieve the DOM elements with those refs?

因为ref放在了Vue组件(vBtn)上,所以永远不会是HTML元素。它将始终是一个组件实例...

const app = Vue.createApp({
  setup() {
    const buttons = ['convert', 'undo', 'cancel', 'erase', 'copy']
    const action = (param) => alert(param)
    const btnArray = buttons.map((item) => ({
        text: item,
        action: action,
        ref: Vue.ref(null)
    }))
    
    Vue.onMounted(() => {
      console.log(btnArray[0].ref.value)
      console.log(btnArray)
    })
    
    return {
      btnArray
    } 
  }
})

app.mount("#app")
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.11/vue.global.js" integrity="sha512-1gHWIGJfX0pBsPJHfyoAV4NiZ0wjjE1regXVSwglTejjna0/x/XG8tg+i3ZAsDtuci24LLxW8azhp1+VYE5daw==" crossorigin="anonymous"></script>
<div id="app">
  <button 
    v-for="(but, i) in btnArray" 
    :key="i" 
    @click="but.action(but.text)"
    :ref="but.ref"
   >  
    {{ but.text }}
   </button>
</div>