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

Posted

技术标签:

【中文标题】Vue 3 & Composition API:v-for 循环中的模板引用错误:仅获取代理【英文标题】:Vue 3 & Composition API : template refs in v-for loop error : only get proxies 【发布时间】:2021-07-15 12:00:06 【问题描述】:

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

基本上,我要做的是根据代码的 setup() 部分中创建的对象数组创建一个按钮列表。所有对象在数组本身中也包含它们自己的 ref,我最终将其绑定在模板上。然后,我从每个 ref 中制作 const,以便我可以在 setup() 中使用它们,但是当我使用 console.log(btnConvert.value) 时,我得到了一个代理,而我没有使用不在 a 中的其他 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 文档。 谁能帮助我了解如何使用这些 ref 检索 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>

【问题讨论】:

当然你得到了 Proxy,你正在记录 ref 本身。改用console.log(btnConvert.value) @MichalLevý 我得到了代理作为输出,它的目标和处理程序被简单地命名为“对象” 我不明白。 “当我 console.log() btn.value 我得到一个代理” + console.log(btnConvert) // this is where I get the proxy.请再次阅读您的问题并修复它,以便更清楚...... @MichalLevý 好了,现在清楚了吗? 【参考方案1】:

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

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

    它只是工作!见下例

请注意:

谁能帮助我了解如何使用这些 ref 检索 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")
<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>

【讨论】:

非常感谢您的回答!我自己有点困惑,但你的回答让我回到了正确的轨道:)

以上是关于Vue 3 & Composition API:v-for 循环中的模板引用错误:仅获取代理的主要内容,如果未能解决你的问题,请参考以下文章

围绕Vue 3 Composition API构建一个应用程序,包含一些最佳实践!

Vue3 composition-api&setup 生命周期

Vue3 composition-api&setup 生命周期

vue3.0 Composition API 上手初体验 神奇的 setup 函数 生命周期函数

如何跨多个文件中的多个 Vue 实例正确使用 Vue 3 composition-api

vue2升级vue3:composition api中监听路由参数改变