#typescript #vue.js #vuejs2 #quasar-framework #vue-composition-api
#typescript #vue.js #vuejs2 #quasar-фреймворк #vue-composition-api
Вопрос:
Я использую Quasar (quasar.dev) с Vue2 Composition API и пытаюсь получить доступ к элементам DOM с динамически генерируемыми свойствами ‘v-bind: ref’, следуя этой странице документов Vue3:
https://v3.vuejs.org/guide/composition-api-template-refs.html#usage-inside-v-for
Это упрощенное представление проблемы в codesandbox: https://codesandbox.io/s/suspicious-pine-90qgd?file=/src/components/MyOuterComponent.ts
Шаблон моего компонента (MyOuterComponent.vue):
<template>
<div>
<my-component
v-for="(item, i) in list"
v-bind:ref="
(el) => {
if (el) divs[i] = el
}
"
v-bind:key="i"
>
{{ item }}
</my-component>
</div>
</template>
<script src='./MyOuterComponent.ts' />
и мой скрипт для этого компонента:
import MyComponent from './MyComponent.vue'
import TMyComponent from './MyComponent'
import {
defineComponent,
onMounted,
ref,
reactive,
onBeforeUpdate
} from '@vue/composition-api'
export default defineComponent({
name: 'MyOuterComponent',
components: { MyComponent },
props: {},
setup(props, context) {
const list = reactive([1, 2, 3, 4, 5])
const divs = ref<InstanceType<typeof TMyComponent>[]>([])
// make sure to reset the refs before each update
onBeforeUpdate(() => {
divs.value = []
})
onMounted(() => {
context.root.$nextTick(() => {
console.log('THE COMPONENTs', divs, context.root.$refs)
divs.value.forEach((div) => {
console.log('My Div Ref: ', div)
})
})
})
return {
list,
divs
}
}
})
Как видно из документов, я ожидаю divs
, что они будут заполнены ссылками на шаблоны для моих динамически генерируемых компонентов, что и должна делать эта строка в моем шаблоне:
v-bind:ref="(el) => { if (el) divs[i] = el }"
divs
остается пустым даже при регистрации после nextTick. Я ожидаю увидеть там 5 элементов, ссылающихся на элементы DOM.
Если я изменю шаблон на:
<template>
<div>
<my-component
v-for="(item, i) in list"
v-bind:ref="item"
v-bind:key="i"
>
{{ item }}
</my-component>
</div>
</template>
<script src='./MyOuterComponent.ts' />
Я вижу ссылки в context.refs
, но мне сказали, что это свойство будет удалено в Vue3;- (
Может кто-нибудь, пожалуйста, скажите мне, где я ошибаюсь? Спасибо.
Ответ №1:
Похоже, что vue-composition-api (vue2) не поддерживает синтаксис :ref . Взгляните на https://github.com/vuejs/composition-api#limitations
Предупреждение должно быть очень полезным.
Комментарии:
1. Большое спасибо, жаль, что я не знал об этом раньше, прежде чем тратить часы, пытаясь заставить его работать; (
Ответ №2:
Сначала вам нужно импортировать ссылки:
import { ref } from "@vue/composition-api"
Простой способ — добавить ссылку в список. Вы можете ссылаться на требуемый ref
, используя индекс списка.
<template>
<div>
<my-component
ref="mycomponentRef"
v-for="(item, index) in list"
v-bind:key="index"
>
{{ item }}
</my-component>
</div>
</template>
<script>
export defineComponent({
setup() {
// this is an array, [ref0, ref1, ...]
const mycomponentRef = ref()
return { mycomponentRef }
}
})
</script>
Ответ №3:
Хотя на данный момент они не поддерживаются, вы все равно можете использовать старые $ refs в качестве обходного пути. Этого нет в Vue3, но вы будете использовать, пока оно не будет реализовано.
<div v-for='i of 10' :key='i' ref='myRefs' />
setup(props, {refs}){
// Workaround until Vue2 Composition API supports dynamic template refs.
onMounted(()=>{
myRefs = refs.myRefs // array of 10 refs
})
}
Комментарии:
1. {refs} не существует в объекте контекста настройки (Vue 2.7). Контекст содержит только следующие ключи: attrs, emit, expose, слушатели, слоты
2.
import { getCurrentInstance } from "vue"; // 2.7 getCurrentInstance().proxy.$refs;