【前端小程序】第九章 自定義組件

類似vue或者react中的自定義組件

  1. ?程序允許我們使??定義組件的?式來(lái)構(gòu)建??。

1. 創(chuàng)建?定義組件

類似于頁(yè)面,一個(gè)自定義組件由 wxss json wxml js 4個(gè)文件組成

  1. 可以在微信開(kāi)發(fā)者?具中快速創(chuàng)建組件的?件結(jié)構(gòu),首先創(chuàng)建一個(gè) component 文件夾用于存放自定義組件。
使用微信開(kāi)發(fā)者工具快速創(chuàng)建組件目錄結(jié)構(gòu)
創(chuàng)建完成之后的文件結(jié)構(gòu)

2. 聲明組件

  1. ?先需要在組件的json?件中進(jìn)??定義組件聲明;
{
  "component": true,
  "usingComponents": { // 可以使用其他組件}
}
  1. 新建一個(gè)頁(yè)面使用自定義組件 ;


    自定義新的頁(yè)面
  2. 在新建的頁(yè)面的 json 中使用自定義組件 :

{
    "usingComponents": {
        "Tabs": "../../component/Tabs/Tabs"
    }
}
  1. wxml文件中使用引入的自定義組件:
<Tabs>
</Tabs>

3. 自定義組件-Tabs樣式優(yōu)化

  1. wxml代碼:

<!-- 
    1. 自定義組件 - 優(yōu)化組件樣式
 -->

 <view class="tabs">
    <view class="title">
       <view wx:for="{{tabs}}" wx:key="{{item.id}}"  class="title-item {{item.isActive ? 'active':''}}">
        {{item.name}}
       </view>      
    </view>
    <view class="content">內(nèi)容</view>
</view>
  1. 需要將tabs菜單的數(shù)據(jù)進(jìn)行抽取到數(shù)組中進(jìn)行遍歷展示:
   // component/Tabs/Tabs.js
Component({
    /**
     * 組件的屬性列表
     */
    properties: {

    },

    /**
     * 組件的初始數(shù)據(jù)
     */
    data: {

        tabs: [{
                id: 0,
                name: '首頁(yè)',
                isActive: true
            },
            {
                id: 1,
                name: '原創(chuàng)',
                isActive: false
            },
            {
                id: 2,
                name: '分類',
                isActive: false
            },
            {
                id: 3,
                name: '關(guān)于',
                isActive: false
            },
        ]
    },

    /**
     * 組件的方法列表
     */
    methods: {

    }
})
  1. 編寫(xiě)樣式文件 :
.title {
    display: flex;
    padding: 10rpx 0;
}

.title-item {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
}

.active {
    color: red;
    border-bottom: 5rpx solid #f00;
}

4. 實(shí)現(xiàn)tabs激活選中

  1. 需要為view綁定一個(gè)單擊事件,并傳遞當(dāng)前點(diǎn)擊的item的索引 。
    <!-- 
    1. 自定義組件 - 優(yōu)化組件樣式
 -->

 <view class="tabs">
    <view class="title">
       <view 
         wx:for="{{tabs}}" 
         wx:key="{{item.id}}"  
         class="title-item {{item.isActive ? 'active':''}}"
         bindtap="handleItemTap"
         data-index="{{index}}">
         {{item.name}}
       </view>      
    </view>
    <view class="content">內(nèi)容</view>
</view>
綁定一個(gè)點(diǎn)擊事件,并傳遞當(dāng)前點(diǎn)擊的 item項(xiàng)的索引
  1. 處理單擊事件:
     /**
     * 組件的方法列表
     */
    methods: {
        handleItemTap(e) {
            // 進(jìn)行解構(gòu)賦值 下面這句相當(dāng)于 this.index = e.currentTarget.dataset.index
            const { index } = e.currentTarget.dataset;
            // 解構(gòu)是對(duì)復(fù)雜類型進(jìn)行解構(gòu)的時(shí)候復(fù)制一份變量引用而已
            // 最嚴(yán)謹(jǐn)?shù)淖龇ň褪侵匦驴截愐环輸?shù)組再對(duì)這個(gè)數(shù)組的備份進(jìn)行處理
            // 不要直接this.data.屬性
            let { tabs } = this.data;
            // 下面是最嚴(yán)謹(jǐn)?shù)膶?xiě)法
            // let tabs = JSON.parse(JSON.stringify(this.data.tabs));
            tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
            this.setData({
                tabs
            })
        }
    }
需要在methods內(nèi)完成方法的編寫(xiě)
  1. 注意單擊事件中的解構(gòu)賦值:
          // 進(jìn)行解構(gòu)賦值 下面這句相當(dāng)于 this.index = e.currentTarget.dataset.index
            const { index } = e.currentTarget.dataset;
            // 解構(gòu)是對(duì)復(fù)雜類型進(jìn)行解構(gòu)的時(shí)候復(fù)制一份變量引用而已
            // 最嚴(yán)謹(jǐn)?shù)淖龇ň褪侵匦驴截愐环輸?shù)組再對(duì)這個(gè)數(shù)組的備份進(jìn)行處理
            // 不要直接this.data.屬性
            let { tabs } = this.data;
            // 下面是最嚴(yán)謹(jǐn)?shù)膶?xiě)法
            // let tabs = JSON.parse(JSON.stringify(this.data.tabs));

5. 父組件向子組件傳遞數(shù)據(jù)

  1. 在父組件引用子組件的page中的標(biāo)簽上傳遞一個(gè)數(shù)據(jù): 里面的屬性名稱任意,符合命名規(guī)范
 <Tabs parent="父親"></Tabs>
  1. 在子組件的 properties 中接收父組件傳遞的值:
接收父組件傳遞的值
  1. 此時(shí)便可以在子組件的標(biāo)簽中直接使用該屬性。

  2. 將上面的tabs數(shù)組通過(guò)父?jìng)髯拥姆绞剑瑥母附M件將數(shù)據(jù)傳遞到子組件:

在data域中定義一個(gè)tabs數(shù)組
父組件傳遞tabs數(shù)組
子組件接收父組件數(shù)據(jù)
  1. 但是以上的寫(xiě)法是有問(wèn)題的 : 因?yàn)樽咏M件中修改了tabs的數(shù)據(jù),但是父組件中的數(shù)據(jù)并未實(shí)現(xiàn)修改:
父組件中的tabs未實(shí)現(xiàn)修改
  1. 實(shí)現(xiàn)父組件中數(shù)據(jù)的修改需要使用到子組件向父組件傳遞數(shù)據(jù)的方式。

6. 子組件向父組件傳遞數(shù)據(jù)

  1. 在父組件中定義一個(gè)父組件的自定義事件 : bindItemChange
父組件自定義事件(我使用bindItemChange這種方式好像不被支持)
查閱官方文檔之后采用 bind:自定義事件名稱的方式可以
  1. 子組件向父組件通過(guò)事件的方式傳遞數(shù)據(jù) :
methods: {
        handleItemTap(e) {
            // 進(jìn)行解構(gòu)賦值 下面這句相當(dāng)于 this.index = e.currentTarget.dataset.index
            const { index } = e.currentTarget.dataset;
            // 點(diǎn)擊tabs觸發(fā)事件的時(shí)候需要傳遞數(shù)據(jù)給父組件  this.triggerEvent("父組件自定義事件的名稱",要傳遞的參數(shù))
            // 子組件通過(guò)事件的方式向父組件傳遞數(shù)據(jù) 參數(shù)需要傳遞一個(gè)對(duì)象
            this.triggerEvent("itemChange", { index });
        }
    }
  1. 父組件接收子組件通過(guò)事件傳遞的數(shù)據(jù) :
 handleItemChange(e) {
        // 解構(gòu)
        const { index } = e.detail;
        let { tabs } = this.data;
        tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false)
        this.setData({
            // 這里 tabs 等價(jià)于 this.tabs = tabs
            tabs
        })
    }

7. slot 插槽(占位符)標(biāo)簽

  1. 在自定義組件中使用 slot標(biāo)簽進(jìn)行占位 :
在自定義組件中使用slot進(jìn)行占位
  1. 在父組件中定義需要顯示的內(nèi)容 :
根據(jù)isActive屬性判斷顯示內(nèi)容

8. 組件的其他屬性

定義段 類型 是否必填 描述
properties ObjectMap 組件的對(duì)外屬性,是屬性名到屬性設(shè)置的映射表,參?下?
data Object 組件的內(nèi)部數(shù)據(jù),和 properties?同?于組件的模板渲染
observers Object 組件數(shù)據(jù)字段監(jiān)聽(tīng)器,?于監(jiān)聽(tīng) propertiesdata 的變化,參?數(shù)據(jù)監(jiān)聽(tīng)器
methods Object 組件的?法,包括事件響應(yīng)函數(shù)和任意的?定義?法,關(guān)于事件響應(yīng)函數(shù)的使?,參?組件事件
created Function 組件?命周期函數(shù),在組件實(shí)例剛剛被創(chuàng)建時(shí)執(zhí)?,注意此時(shí)不能調(diào)? setDatasetData ,參?組件?命周期
attached Function 組件?命周期函數(shù),在組件實(shí)例進(jìn)???節(jié)點(diǎn)樹(shù)時(shí)執(zhí)?,參?組件?命周期
ready Function 組件?命周期函數(shù),在組件布局完成后執(zhí)?,參?組件?命周期
moved Function 組件?命周期函數(shù),在組件實(shí)例被移動(dòng)到節(jié)點(diǎn)樹(shù)另?個(gè)位置時(shí)執(zhí)?,參?組件?命周期
detached Function 組件?命周期函數(shù),在組件實(shí)例被從??節(jié)點(diǎn)樹(shù)移除時(shí)執(zhí)?,參?組件?命周期
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容