Vue.js $дети по имени компонента
Я пытаюсь получить доступ к конкретному ребенку по имени. На данный момент, из-за того, где находится ребенок, я звоню ребенку так:
this.$root.$children[0]
Это нормально, пока этот ребенок всегда [0]
но было бы здорово, если бы был способ сделать что-то вроде:
this.$root.$children['detail']
Я продолжаю думать, что $refs
может быть ответом на мою проблему, но я никогда не смогу найти способ, которым это поможет мне.
Есть идеи?
Ответы
Ответ 1
Этот ребенок, о котором вы говорите, действительно является дочерним компонентом компонента, к которому вы хотите получить доступ? В этом случае v-ref
действительно является ответом:
// in the code of the parent component, access the referenced child component like this:
this.$refs.detailsChild
<!-- Template of the parent component, assuming your child Component is called Details -->
<details v-ref:details-child></details>
Ответ 2
Вы можете использовать это свойство:
this.$root.$children[0].$options.name
Например:
this.$root.$children.find(child => { return child.$options.name === "name"; });
Ответ 3
Все почти так же, но в Vue 2 вам нужно использовать: <details ref="details-child"></details>
вместо v-ref.
Тогда все, что вам нужно сделать, это использовать this.$refs.details-child;
и вы можете получить доступ к любому из его свойств.
Ответ 4
this.$root.$children[0].constructor.name
Ответ 5
Вам не обязательно нужно $refs
, на самом деле иногда это невозможно, если у вас есть глубоко вложенные компоненты. Я нашел этот Q & A несколько раз при поиске, но, наконец, решительно реализовал свое собственное решение, так как довольно часто сталкиваюсь с этой ситуацией. Не отказывайтесь от старой школы для петель, они необходимы по нескольким причинам, во-первых, я тестирую x<descendants.length
(вместо того, чтобы устанавливать что-то вроде len=descendants.length
спереди и проверять на это) на каждом итерации, когда я нажимаю на стек во втором цикле.
Во-первых, использование:
let unPersonalizable = matchingDescendants(this, /a.checkimprintfiinformation$/, {first: true});
Реализация:
function matchingDescendants(vm, matcher, options) {
let descendants = vm.$children;
let descendant;
let returnFirst = (options || {}).first;
let matches = [];
for (let x=0; x<descendants.length; x++) {
descendant = descendants[x];
if (matcher.test(descendant.$vnode.tag)) {
if (returnFirst) {
return descendant;
}
else {
matches.push(descendant);
}
}
for (let y=0, len = descendant.$children.length; y<len; y++) {
descendants.push(descendant.$children[y]);
}
}
return matches.length === 0 ? false : matches;
}
Ответ 6
Я пытался нацелиться на некоторых детей прошлой ночью. Я пытался вызвать el.focus()
на входе. Моя проблема заключалась в том, что я пытался сделать это из экземпляра метода, который вызывался нажатием кнопки, а входные данные находились в сторонней библиотеке, и я помещал это в другой компонент.
Решением для меня было поставить ref
на мой компонент оболочки.
Например, если у вас есть разметка, как это:
<my-dropdown ref="myDropdown"></my-dropdown>
Внутри my-dropdown
вы можете поставить еще одного ref
на одного из его детей:
<template>
<div>
<my-library-wrapper ref="libWrapper"></my-library-wrapper>
</div>
</template>
Внутри my-library-wrapper
вы можете импортировать библиотеку из node_modules
которой есть ссылки. Большинство библиотек ставят ссылки на вещи, чтобы вы могли использовать их для нацеливания.
Теперь вы можете начать нацеливать наши компоненты примера здесь с кодом, подобным этому:
console.log(this.$refs.myDropdown);
console.log(this.$refs.myDropdown.$refs);
console.log(this.$refs.myDropdown.$refs.libWrapper);
this.$refs.myDropdown.$refs.libWrapper.$refs.someThing.focus();
this.$refs.myDropdown.$refs.libWrapper.$refs.someThing.click();
На первый взгляд, это может показаться странным, но выгода от этого по сравнению с подобными вещами: this.$refs.myDropdown.$children[0].$children[1].focus();
в том, что refs
гораздо менее хрупкие. Если вы или кто-то еще добавите <divs>
в разметку позже, код, использующий refs
, не сломается, потому что Vue находит эти элементы с именами ref по имени, а не по относительному расстоянию.
Я рекомендую поместить ref="something"
в что-то и сделать console.log(this.$refs.something.$refs);
и посмотрите, что вы видите, и пока вы это делаете, выполните console.log(this.$refs.something);
и посмотрите, какие другие вещи доступны в there--, такие как $attrs
$children
и $el
.