44.Vue實現(xiàn)查找任意層級子元素和祖先元素

在vue中查找子元素和父元素提供了this.$parent、this.$children睡陪,但是如果需要查找任意層級子元素和祖先元素并沒有直接的API,需要封裝方法:

案例

index.vue

<template>
    <div>
        <!-- jq closest效果 -->
        jq closest效果 <br>
        <com2 @comParentItem="com2Fun">
            <!-- 父元素com1 -->
            <com1>
                <com2></com2>
            </com1>
        </com2>
        <br>
        <br>
        <com1>
            <!-- 父元素com1 -->
            <com2>
                <com1></com1>
            </com2>
        </com1>
    </div>
</template>
<script>
    import com1 from './com1'
    import com2 from './com2'
    export default {
        //
        components: {
            com1,
            com2
        },
        data(){
            return { }
        },
        methods: {
            /*
               com2Fun的方法
            */
            com2Fun(item){
                console.log('觸發(fā)父元素事件------ ');
                console.log(item);
            }
        }
    }
</script>
<style>
    .item {
        border: 1px solid red;
        height: 30px;
        line-height: 30px;
    }
</style>

com1.vue

<!-- 組件一
    實現(xiàn)找到任意子元素
 -->
<template>
    <div>
        <slot>
            <com3 @click.native="showChild">
                <com3>
                    <com4 @comChilItem="comChilItemFun">
                        <com3 class="item" >
                            子元素列表1
                        </com3>
                        <com3  class="item">
                            子元素列表2
                        </com3>
                        <com3  class="item">
                            子元素列表3
                        </com3>
                    </com4>
                </com3>
            </com3>
        </slot>
    </div>
</template>
<script>
    import com3 from './com3'
    import com4 from './com4'
    export default {
        components: {
            com3,
            com4
        },
        data(){
            return {}
        },
        methods: {
            /*
                找到指定的子元素
            */
            broadcast(componentName, eventName, params, that){
            //
                broadcast.call(this, componentName, eventName, params, that);
                function broadcast(componentName, eventName, params, that) {
                    //遍歷所有子組件
                    this.$children.forEach(child => {
                            var name = child.$options._componentTag.toLowerCase();
                            //尋找符合指定名稱的子組件
                            // if (name === componentName) {
                            if (componentName.includes(name)) {
                                //在符合的自組件上觸發(fā)的事件型奥,但是不會再繼續(xù)尋找符合名稱的組件的子集误窖,原因涮阔?
                                child.$emit.apply(child, [eventName].concat(params));
                            } else {
                                //不符合繼續(xù)尋找他的子集(即孫子組件)
                                broadcast.apply(child, [componentName, eventName, params].concat([that]));
                            }
                    });
                }   
            },
            showChild(){
                //
                this.broadcast('com4', 'comChilItem', {children: '2'});
            },
            comChilItemFun(item){
                console.log('子組件被觸發(fā)--------');
                console.log(item);
            }
        }
    }
</script>
   
<style>
</style>

com2.vue

<!-- 組件二 
    實現(xiàn)找到任意祖先元素
 -->
<template>
    <com1>
        <slot>
            <com4>
                <com1>
                    <com1 @click.native="showParent">
                        <com1 class="item" >
                            列表1
                        </com1>
                        <com1  class="item">
                            列表2
                        </com1>
                        <com1  class="item">
                            列表3
                        </com1>
                    </com1>
                </com1>
             </com4>
        </slot>
    </com1>

</template>
<script>
    import com1 from './com1.vue'
    import com4 from './com4.vue'
    export default {
        components: {
            com1,
            com4
        },
        data(){
            return {}
        },
        methods: {
            /*
                找到指定的父元素猜绣,仿jq的closest
            */
            dispatch(componentName, eventName, params){
                var parent = this.$parent || this.$root;
                var name = parent.$options._componentTag.toLowerCase();
                //尋找父級,如果父級不是符合的組件名敬特,則循環(huán)向上查找
                // while (parent && (!name || name !== componentName)) {
                while (parent && (!name || !componentName.includes(name))) {
                    parent = parent.$parent;
                    if (parent) {
                    name = parent.$options._componentTag;
                    }
                }
                //找到符合組件名稱的父級后掰邢,觸發(fā)其事件。整體流程類似jQuery的closest方法
                if (parent) {
                    parent.$emit.apply(parent, [eventName].concat(params));
                }
            },
            
            showParent(){
               // 找到指定的祖先元素
               this.dispatch('com2', 'comParentItem', {parent: '1'});
            }
        }
    }
</script>
<style>
</style>

com3.vue

<!-- 組件一 -->
<template>
    <div>
        <slot>
            
        </slot>
    </div>
</template>
<script>
    export default {
        data(){
            return {}
        },
        methods: {

        }
    }
</script>
   
<style>
</style>

com4.vue

<!-- 組件一 -->
<template>
    <div>
        <slot>
            
        </slot>
    </div>
</template>
<script>
    export default {
        data(){
            return {}
        },
        methods: {

        }
    }
</script>
   
<style>
</style>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伟阔,一起剝皮案震驚了整個濱河市辣之,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌皱炉,老刑警劉巖怀估,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異合搅,居然都是意外死亡多搀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門灾部,熙熙樓的掌柜王于貴愁眉苦臉地迎上來康铭,“玉大人,你說我怎么就攤上這事赌髓〈犹伲” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵锁蠕,是天一觀的道長夷野。 經(jīng)常有香客問我,道長荣倾,這世上最難降的妖魔是什么扫责? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮逃呼,結(jié)果婚禮上鳖孤,老公的妹妹穿的比我還像新娘者娱。我一直安慰自己,他們只是感情好苏揣,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布黄鳍。 她就那樣靜靜地躺著,像睡著了一般平匈。 火紅的嫁衣襯著肌膚如雪框沟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天增炭,我揣著相機與錄音忍燥,去河邊找鬼。 笑死隙姿,一個胖子當著我的面吹牛梅垄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播输玷,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼队丝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了欲鹏?” 一聲冷哼從身側(cè)響起机久,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赔嚎,沒想到半個月后膘盖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡尤误,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年侠畔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袄膏。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡践图,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沉馆,到底是詐尸還是另有隱情码党,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布斥黑,位于F島的核電站揖盘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锌奴。R本人自食惡果不足惜兽狭,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧箕慧,春花似錦服球、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伐庭,卻和暖如春粉渠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背圾另。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工霸株, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人集乔。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓去件,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饺著。 傳聞我的和親對象是個殘疾皇子箫攀,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容