【问题标题】:Vue 3 & Composition API : template refs in v-for loop error : only get proxiesVue 3 & Composition API:v-for 循环中的模板引用错误:仅获取代理
【发布时间】: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ý 好了,现在清楚了吗?

标签: vue.js vuejs3 vue-cli vue-composition-api


【解决方案1】:

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

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

  2. 它只是工作!见下例

请注意:

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

【讨论】:

  • 非常感谢您的回答!我自己有点困惑,但你的回答让我回到了正确的轨道:)
猜你喜欢
  • 1970-01-01
  • 2017-08-13
  • 2019-11-13
  • 2022-01-17
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
相关资源
最近更新 更多