Reputation: 31
I've been developing my first project with Vue3.js & Vue Cli and I've been stuck for the past couple of hours on this bit of code.
Basically what I'm trying to do is to have a list of buttons based on an array of objects created in the setup() part of the code. All objects also contain their own ref within the array itself, which I eventually bind on the template. I then make consts out of each ref so that I can use them within the setup() but when I console.log(btnConvert.value) I get a proxy, which I don't with my other refs that aren't within a v-for loop.
RefImpl {_rawValue: Proxy, _shallow: false, __v_isRef: true, _value: Proxy}
Here's the expanded version of the 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
I tried everything I could think of, but I couldn't understand the official Vue doc. Could anyone help me understand how I could retrieve the DOM elements with those refs? Thank you very much !
Here's the bit of relevant code (I removed the functions to which the btn refer for ease of lecture).I can add some more if necessary.
<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>
Upvotes: 3
Views: 9079
Reputation: 37883
I am sorry but I am not able to replicate your results
I do not understand how you can get anything else then null
from console.log(btnConvert.value)
when you are not rendering 1st button at all thanks to v-for="btn in btnArray.slice(1)"
(which effectively creates new array without the first element in source array)
It just works! See below example
Just a note:
Could anyone help me understand how I could retrieve the DOM elements with those refs?
Because ref
is placed on Vue component (vBtn
), it will never be an HTML element. It will be always a component instance...
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>
Upvotes: 5