Vue 3 和 Composition API:v-for 循环中的模板引用错误:仅获取代理

Tom*_*WTG 3 vue.js vue-cli vuejs3 vue-composition-api

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

\n

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

\n
    RefImpl\xc2\xa0{_rawValue: Proxy, _shallow: false, __v_isRef: true, _value: Proxy}\n
Run Code Online (Sandbox Code Playgroud)\n

这是 console.log(btnConvert.value) 的扩展版本

\n
Proxy {\xe2\x80\xa6}\n  [[Handler]]: Object\n    get: \xc6\x92 get({ _: instance }, key)\n    has: \xc6\x92 has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key)\n    ownKeys: (target) => {\xe2\x80\xa6}\n    set: \xc6\x92 set({ _: instance }, key, value)\n  [[Prototype]]: Object\n  [[Target]]: Object\n  [[IsRevoked]]: false\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试了我能想到的一切,但我无法理解官方 Vue 文档。\n有人可以帮助我理解如何使用这些引用检索 DOM 元素吗?\n非常感谢!

\n

这是一些相关代码(为了便于讲座,我删除了 btn 引用的函数)。如果需要,我可以添加更多代码。

\n
    <template>\n      <div>\n        <div ref="btnList" class="options">\n          <vBtn\n            v-for="btn in btnArray"\n            :key="btn"\n            :ref="btn.ref"\n            class="btn"\n            :class="`btn--${btn.class}`"\n            @click="btn.action"\n            v-html="btn.text"\n          />\n      </div>\n    </template>\n
Run Code Online (Sandbox Code Playgroud)\n
    <script>\n    import { ref, onMounted } from \'vue\'\n    import vBtn from \'@/components/Tool/vBtn.vue\'\n\n    export default {\n      components : {\n        vBtn\n      },\n\n      setup() {\n        const btnConvert = ref(null)\n        const btnCopy = ref(null)\n        const btnCancel = ref(null)\n        const btnUndo = ref(null)\n        const btnErase = ref(null)\n        \n        const btnArray = [\n          {\n            class: \'convert\',\n            text: \'some text\',\n            action: convertText,\n            ref: btnConvert\n          },\n          {\n            class: \'undo\',\n            text: \'some text\',\n            action: undoConvert,\n            ref: btnUndo\n    \n          },\n          {\n            class: \'cancel\',\n            text: \'some text\',\n            action: cancelChange,\n            ref: btnCancel\n    \n          },\n          {\n            class: \'erase\',\n            text: \'some text\',\n            action: eraseText,\n            ref: btnErase\n    \n          },\n          {\n            class: \'copy\',\n            text: \'some text\',\n            action: copyText,\n            ref: btnCopy\n          }\n        ]\n    \n        onMounted() {\n          console.log(btnConvert.value)\n          // this is where I get the proxy\n        }\n      },\n    }\n    </script>\n
Run Code Online (Sandbox Code Playgroud)\n

Mic*_*evý 5

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

  1. 我不明白当您完全不渲染第一个按钮时null如何获得其他任何东西(这有效地创建了新数组,而没有源数组中的第一个元素)console.log(btnConvert.value)v-for="btn in btnArray.slice(1)"

  2. 它就是有效的!请参阅下面的示例

只是注意一下:

谁能帮助我理解如何使用这些引用检索 DOM 元素?

因为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")
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)