成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從零開始實(shí)現(xiàn)一個(gè)Vue級(jí)聯(lián)組件

binaryTree / 2652人閱讀

摘要:從零開始實(shí)現(xiàn)一個(gè)級(jí)聯(lián)組件本文實(shí)現(xiàn)級(jí)聯(lián)組件需要用到自定義指令和組件通信相關(guān)知識(shí),最好先閱讀以下兩篇文章自定義指令組件基礎(chǔ)與通信一組件簡介本文實(shí)現(xiàn)的是一個(gè)省市縣多級(jí)聯(lián)動(dòng)組件,當(dāng)組件渲染完成后默認(rèn)會(huì)加載出所有的省名稱,當(dāng)用戶點(diǎn)擊某個(gè)省的名稱后,右

從零開始實(shí)現(xiàn)一個(gè)Vue級(jí)聯(lián)組件

本文實(shí)現(xiàn)級(jí)聯(lián)組件需要用到自定義指令組件通信相關(guān)知識(shí),最好先閱讀以下兩篇文章:

Vue自定義指令

Vue組件基礎(chǔ)與通信

一、組件簡介

本文實(shí)現(xiàn)的是一個(gè)省、市、縣...多級(jí)聯(lián)動(dòng)組件,當(dāng)組件渲染完成后默認(rèn)會(huì)加載出所有的省名稱,當(dāng)用戶點(diǎn)擊某個(gè)省的名稱后,右邊會(huì)自動(dòng)添加一列顯示該省下對(duì)應(yīng)的市名稱列表,當(dāng)用戶點(diǎn)擊某個(gè)市后,右邊又會(huì)自動(dòng)添加一列顯示該市下對(duì)應(yīng)的縣名稱列表,同時(shí)支持級(jí)聯(lián)列表的打開和關(guān)閉。

二、組件實(shí)現(xiàn)設(shè)計(jì)思路

① 組件所需要的數(shù)據(jù),數(shù)據(jù)結(jié)構(gòu)非常簡單,對(duì)象里面只有兩個(gè)屬性,一個(gè)是label(標(biāo)簽名),如果當(dāng)前標(biāo)簽下還有子標(biāo)簽,則會(huì)多一個(gè)children屬性,children屬性值為一個(gè)數(shù)組每個(gè)數(shù)組元素為其下的一個(gè)子標(biāo)簽。

// data.json, 為避免數(shù)據(jù)占用太多篇幅,這里只列舉了一條數(shù)據(jù)

[
    {
        "label": "江西",
        "children": [
            {
                "label": "贛州",
                "children": [
                    {
                        "label": "全南縣"
                    },
                    {
                        "label": "龍南縣"
                    }
                ]
            }
        ]
    }
]

② 我們的級(jí)聯(lián)組件分為上下兩部分組件,上部分顯示用戶選擇的路徑,下部分顯示用戶選擇列表,同時(shí)支持點(diǎn)擊級(jí)聯(lián)組件的上部分可以實(shí)現(xiàn)下半部分的打開和關(guān)閉,點(diǎn)擊組件外面關(guān)閉組件的下半部分,這里需要用到v-click-outside指令,這里自定義指令的代碼就不再重復(fù),請(qǐng)參考Vue自定義指令
// Cascader.vue 新建一個(gè)Cascader.vue組件



注意到組件中有一個(gè)selectedItems數(shù)據(jù),這是一個(gè)數(shù)組,默認(rèn)值為空數(shù)組,因?yàn)楫?dāng)級(jí)聯(lián)組件渲染完成后,默認(rèn)用戶是沒有點(diǎn)擊選擇其中任何一項(xiàng)的,只有當(dāng)用戶點(diǎn)擊了某一項(xiàng)后,才會(huì)將點(diǎn)擊的這一項(xiàng)添加到selectedItems數(shù)組中,其就是記錄用戶的選擇項(xiàng)。這里需要理解清楚選擇項(xiàng)的概念:
比如我們的級(jí)聯(lián)組件有三列,省、市、縣三列,結(jié)合上面的數(shù)據(jù)結(jié)構(gòu),整個(gè)省是一個(gè)大對(duì)象,即省對(duì)象,省對(duì)象中有children屬性,里面包括多個(gè)子對(duì)象,即市對(duì)象,市對(duì)象中又包括children屬性,里面包括多個(gè)子對(duì)象,即縣對(duì)象,縣對(duì)象中不再有children了,具體表示就是:
省對(duì)象:
{ "label": "江西", children: [省略...]}
市對(duì)象:
{ "label": "贛州", children: [省略...]}
縣對(duì)象:
{ "label": "全南縣"}
當(dāng)用戶點(diǎn)擊第一列,那么就將整個(gè)省對(duì)象添加到selectedItems數(shù)組中的第一項(xiàng)位置,當(dāng)用戶接著點(diǎn)擊了第二列,如省對(duì)象中的label為"贛州"的市對(duì)象,則將整個(gè)市對(duì)象添加到selectedItems數(shù)組中的第二項(xiàng)位置,當(dāng)用戶又點(diǎn)擊了第三列,如"贛州"市對(duì)象下的label為"全南縣"的縣對(duì)象,則將整個(gè)縣對(duì)象添加到selectedItems數(shù)組中的第三項(xiàng)位置,這樣selectedItems數(shù)組中就保存了用戶選擇的三列數(shù)據(jù)了,然后將三列數(shù)據(jù)中的label取出通過"/"連接起來,即用戶的選擇路徑"江西/贛州/全南縣"。

③ 接下來就是考慮組件拿到數(shù)據(jù)后,如何渲染的問題了?
這里需要用到組件內(nèi)遞歸組件,我們可以左右兩列抽象成一個(gè)多帶帶的組件CascaderItem.vue,但是右邊這一列會(huì)不會(huì)顯示,得看用戶有沒有選擇左邊的項(xiàng),如果點(diǎn)擊了左邊的項(xiàng)則顯示右邊的列,如果沒有點(diǎn)擊左邊的項(xiàng)則不顯示右邊的列。

還是以省、市、縣三列為例,中間的市這一列,既是省的右列,也是縣的左列,我們已經(jīng)將左右兩列抽象了一個(gè)多帶帶的CascaderItem組件,關(guān)鍵是理解省這一列的右邊部分到底是什么?,從表面上看,省這一列的右邊就是一個(gè)市列,但是如果右邊僅僅是市這一列的話,那么當(dāng)用戶點(diǎn)擊市這一列中的某項(xiàng)的時(shí)候,就無法顯示市右邊的縣列了,所以省這一列的右邊其實(shí)又是一個(gè)CascaderItem組件,只有這樣點(diǎn)擊市列中的某一項(xiàng)的時(shí)候,其右邊的縣列才會(huì)顯示出來。所以我們需要在CascaderItem組件內(nèi)遞歸自己,而組件內(nèi)遞歸自己,那么必須給組件添加name屬性,即給組件取一個(gè)名字,如:

// CascaderItem.vue



CascaderItem組件組件的渲染數(shù)據(jù)來自于頂層父組件Cascader中的selectedItems數(shù)據(jù),因?yàn)橛脩酎c(diǎn)擊了左側(cè)列中的項(xiàng)后,會(huì)將點(diǎn)擊的item項(xiàng)添加到selectedItems中,selectedItems中數(shù)據(jù)變化之后才會(huì)顯示右側(cè)的列。
CascaderItem組件需要接收一個(gè)level屬性,用來記錄當(dāng)前CascaderItem組件所屬層級(jí),即第幾列,為了方便,我們從0開始表示第一列,即第一層所以Cascader.vue中l(wèi)evel傳入0,后面沒加一層level會(huì)加1,如:

// 補(bǔ)全上面的Cascader.vue,渲染出下半部分

CascaderItem組件的左邊部分都監(jiān)聽了一個(gè)click事件,當(dāng)用戶點(diǎn)擊左邊的列選項(xiàng)后,需要將當(dāng)前所在level和item對(duì)象數(shù)據(jù)傳遞到Cascader父組件中的selectedItems數(shù)組中,以便獲取用戶的選擇路徑,因?yàn)?strong>單向數(shù)據(jù)流,子組件不能直接修改父組件傳遞過來的數(shù)據(jù),所以需要去父組件中修改數(shù)據(jù),這里以事件的方式通知頂層父組件自己更新數(shù)據(jù)

// CascaderItem.vue給CascaderItem組件添加一個(gè)select()方法

export default {
    methods: {
        select(item) { // 處理CascaderItem組件內(nèi)左側(cè)列點(diǎn)擊事件,item為當(dāng)前點(diǎn)擊的對(duì)象
            // 向上一級(jí)發(fā)射一個(gè)change事件,通知上層進(jìn)行修改,并將當(dāng)前點(diǎn)擊的層級(jí)level和item傳遞過去
            this.$emit("change", {level: this.level, item: item});
        }
    }
}
由于CascaderItem是遞歸調(diào)用的,所以現(xiàn)在的組件調(diào)用關(guān)系為: Cascader --> CascaderItem --> CascaderItem --> CascaderItem --> ......
頂層父組件為Cascader,所以CascaderItem也可能是CascaderItem的父組件,CascaderItem組件自身也需要監(jiān)聽change事件,主要就是負(fù)責(zé)將數(shù)據(jù)改變信號(hào)傳遞到Cascader頂層父組件上,如:

// CascaderItem.vue給CascaderItem組件添加一個(gè)change事件處理方法

export default {
    methods: {
        change(newValue) { // 向頂層傳遞數(shù)據(jù)改變信息
            this.$emit("change", newValue);
        }
    }
}
頂層父組件Cascader接收到數(shù)據(jù)改變信號(hào)后,就需要改變selectedItems數(shù)據(jù)了,即將用戶的選擇項(xiàng)添加到對(duì)應(yīng)的位置,如:

// Cascader.vue 添加change事件處理函數(shù)

export default {
    methods: {
        change(newValue) {
            this.selectedItems.splice(newValue.level, 1, newValue.item); // 替換當(dāng)前點(diǎn)擊位置信息
            this.selectedItems.splice(newValue.level + 1); // 刪除當(dāng)前點(diǎn)擊位置之后的數(shù)據(jù)
        }
    }
}
Cascader組件除了替換掉指定level中的數(shù)據(jù)外,還需要將當(dāng)前l(fā)evel之后的數(shù)據(jù)刪除掉,否則當(dāng)前l(fā)evel之后的數(shù)據(jù)還在,導(dǎo)致右側(cè)路徑仍然保留而顯示不一致。

至此,一個(gè)簡單的級(jí)聯(lián)組件就實(shí)現(xiàn)了,可以在App.vue中直接使用,如:
// App.vue


三、總結(jié)
整個(gè)Cascader組件設(shè)計(jì)思路就是: 在頂層父組件Cascader中添加一個(gè)selectedItems數(shù)組,用于保存用戶點(diǎn)擊的level層級(jí)(列序號(hào))和對(duì)應(yīng)的item對(duì)象,同時(shí)用于生成用戶的選擇路徑,當(dāng)用戶點(diǎn)擊了CascaderItem組件的左側(cè)列中某項(xiàng)后,通過層層傳遞事件的方式通知頂層父組件Cascader對(duì)其數(shù)據(jù)進(jìn)行更新,頂層父組件Cascader更新數(shù)據(jù)后,CascaderItem組件從selectedItems中取出對(duì)應(yīng)level的item對(duì)象,然后獲取item的children并遍歷顯示右側(cè)列

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/110003.html

相關(guān)文章

  • 第十集: 從零開始實(shí)現(xiàn)一套pc端vue的ui組件庫( 計(jì)數(shù)器組件 )

    摘要:第十集從零開始實(shí)現(xiàn)計(jì)數(shù)器組件本集定位聽到計(jì)數(shù)器這個(gè)名字很多人是不是一瞬間沒有什么印象畢竟這個(gè)組件用的比較少就是那種左邊一個(gè)右邊一個(gè)控制某些數(shù)量的時(shí)候才會(huì)用到比如我之前做的商城小程序只有下單頁面的規(guī)格彈出框里面才有他的身影如果是涉及到處理商 第十集: 從零開始實(shí)現(xiàn)( 計(jì)數(shù)器組件 ) 本集定位: 聽到計(jì)數(shù)器這個(gè)名字很多人是不是一瞬間沒有什么印象, 畢竟這個(gè)組件用的比較少,就是那種左邊...

    Sanchi 評(píng)論0 收藏0
  • 第十集: 從零開始實(shí)現(xiàn)一套pc端vue的ui組件庫( 計(jì)數(shù)器組件 )

    摘要:第十集從零開始實(shí)現(xiàn)計(jì)數(shù)器組件本集定位聽到計(jì)數(shù)器這個(gè)名字很多人是不是一瞬間沒有什么印象畢竟這個(gè)組件用的比較少就是那種左邊一個(gè)右邊一個(gè)控制某些數(shù)量的時(shí)候才會(huì)用到比如我之前做的商城小程序只有下單頁面的規(guī)格彈出框里面才有他的身影如果是涉及到處理商 第十集: 從零開始實(shí)現(xiàn)( 計(jì)數(shù)器組件 ) 本集定位: 聽到計(jì)數(shù)器這個(gè)名字很多人是不是一瞬間沒有什么印象, 畢竟這個(gè)組件用的比較少,就是那種左邊...

    Kerr1Gan 評(píng)論0 收藏0
  • 第二集: 從零開始實(shí)現(xiàn)一套pc端vue的ui組件庫(icon組件)

    摘要:第二集從零開始實(shí)現(xiàn)組件本集定位這套組件我本來是先從做的但是我發(fā)現(xiàn)每個(gè)組件都要用到這個(gè)組件如果沒有他很多組件沒法擴(kuò)展而且本身不依賴其他組件所以還是先把它作為本篇文章的重點(diǎn)吧組件讀過源碼的同學(xué)都知道他們選擇的是字體圖標(biāo)的方式來做組件的而我的這 第二集: 從零開始實(shí)現(xiàn)(icon組件) 本集定位: 這套u(yù)i組件我本來是先從button做的, 但是我發(fā)現(xiàn)每個(gè)組件都要用到icon這個(gè)組件, 如...

    dack 評(píng)論0 收藏0
  • 第二集: 從零開始實(shí)現(xiàn)一套pc端vue的ui組件庫(icon組件)

    摘要:第二集從零開始實(shí)現(xiàn)組件本集定位這套組件我本來是先從做的但是我發(fā)現(xiàn)每個(gè)組件都要用到這個(gè)組件如果沒有他很多組件沒法擴(kuò)展而且本身不依賴其他組件所以還是先把它作為本篇文章的重點(diǎn)吧組件讀過源碼的同學(xué)都知道他們選擇的是字體圖標(biāo)的方式來做組件的而我的這 第二集: 從零開始實(shí)現(xiàn)(icon組件) 本集定位: 這套u(yù)i組件我本來是先從button做的, 但是我發(fā)現(xiàn)每個(gè)組件都要用到icon這個(gè)組件, 如...

    wua_wua2012 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<