web-dev-qa-db-ja.com

コンポーネント名別のVue.js $ children

特定の子に名前でアクセスしようとしています。現時点では、子供のいる場所のために、私はこれで子供を呼んでいます:

this.$root.$children[0]

その子が常に[0]しかし、次のような方法があれば素晴らしいと思います。

this.$root.$children['detail']

私は考え続けます$refsは私の問題に対する答えかもしれませんが、それが私を助ける方法を見つけることはできません。

何か案は?

22
Flakx

あなたが話しているこの子は、実際にアクセスしたいコンポーネントの子ですか?この場合、 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>

関連するAPIドキュメント: http://vuejs.org/api/#v-ref

32
Linus Borg

このプロパティを使用できます:

this.$root.$children[0].$options.name

例えば:

this.$root.$children.find(child => { return child.$options.name === "name"; });
24
drinor

すべてほぼ同じですが、Vue 2で使用する必要がある場合:<details ref="details-child"></details> v-refの代わりに。

その後、あなたがする必要があるのはthis.$refs.details-child;そして、そのプロパティのいずれかにアクセスできます。

3
Armin
this.$root.$children[0].constructor.name
1
user4229130

私は昨夜何人かの子供をターゲットにしようとしていた。入力時にel.focus()を呼び出そうとしました。私の問題は、ボタンクリックから起動されたインスタンスメソッドからそれを行おうとしており、入力がサードパーティライブラリにあり、それを別のコンポーネントにラップしていたことです。

私にとっての解決策は、ラッパーコンポーネントにrefを置くことでした。

たとえば、次のようなマークアップがある場合:

<my-dropdown ref="myDropdown"></my-dropdown>

my-dropdown内で、その子の1つに別のrefを置くことができます。

<template>
    <div>
        <my-library-wrapper ref="libWrapper"></my-library-wrapper>
    </div>
</template>

my-library-wrapper内では、refを含むnode_modulesからライブラリにインポートできます。ほとんどのライブラリは物事にrefを付けているので、それらを使用してターゲットにすることができます。

これで、次のようなコードを使用して、サンプルコンポーネントをターゲットに設定できます。

 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-named要素ではなく相対距離によって。

私の推奨事項は、ref="something"を何かに付けてconsole.log(this.$refs.something.$refs);を実行し、表示できるものを確認し、それを実行している間にconsole.log(this.$refs.something);を実行し、他の種類$attrs$children$elのようなものがあります。

0
agm1984

_$refs_は必ずしも必要ではありません。実際、コンポーネントを深くネストしている場合、実際には実行できない場合があります。検索中にこのQ&Aを何度か見つけましたが、この状況に頻繁に遭遇するため、最終的には独自のソリューションを実装することにしました。昔ながらのforループにbしないでください。それらはいくつかの理由で必要です。1つは、_x<descendants.length_をテストする(_len=descendants.length_などを事前に設定してテストするのではなく)それ)私はすべての反復で、2番目のforループでスタックにプッシュしています。

まず、使用法:

_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;
}
_
0
George Jempty