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.