小程序自定義組件

自定義組件

1. 創建-注冊-使用組件

組件介紹

小程序目前已經支持組件化開發,可以將頁面中的功能模塊抽取成自定義組件,以便在不同的頁面中重復使用;

也可以將復雜的頁面拆分成多個低耦合的模塊,有助于代碼維護。

開發中常見的組件有兩種:

  1. 公共組件:將頁面內的功能模塊抽象成自定義組件,以便在不同的頁面中重復使用
  2. 頁面組件:將復雜的頁面拆分成多個低耦合的模塊,有助于代碼維護

如果是公共組件,建議將其放在小程序的目錄下的 components 文件夾中

如果是頁面組件,建議將其放在小程序對應頁面目錄下,當然你也可以放到頁面的 components 文件夾中

同時建議:一個組件一個文件夾,文件夾名稱和組件名稱保持一致

📌 注意事項

  1. 自定義組件的需要在 json 文件中需要配置 component 字段設為 true
  2. 自定義組件通過 Component 構造器進行構建,在構造器中可以指定組件的屬性、數據、方法等

創建自定義組件:

創建組件的步驟很簡單,以公共組件為例,創建的步驟如下:

  1. 在小程序的目錄下新建 components 文件夾

  2. components 文件夾上,點擊右鍵,選擇新建文件夾 ,然后輸入文件夾名稱,我們建議文件夾的名稱和組件的名稱保持一致,這樣方便后期對組件進行維護。我們這里新的的組件名稱叫做:custom-checkbox

  3. 在新建的組件文件夾上,點擊右鍵,選擇新建 Component,然后輸入組件的名稱,組件的名稱建議和文件夾保持一致

  4. 此時就已經創建了一個功能組件
    在這里插入圖片描述

使用自定義組件

開發中常見的組件主要分為 公共組件 和 頁面組件 兩種,因此注冊組件的方式也分為兩種:

  1. 全局注冊:在 app.json 文件中配置 usingComponents 節點進行引用聲明,注冊后可在任意組件使用
  2. 局部注冊:在頁面的 json 文件中配置 usingComponents 節點進行引用聲明,只可在當前頁面使用

在這里插入圖片描述

在配置 usingComponents 節點進行引用聲明時,需要提供自定義組件的標簽名和對應的自定義組件文件路徑,語法如下:

{"usingComponents": {"自定義組件的標簽名": "自定義組件文件路徑"}
}

這樣,在頁面的 wxml 中就可以像使用基礎組件一樣使用自定義組件。節點名即自定義組件的標簽名,節點屬性即傳遞給組件的屬性值。

{"usingComponents": {"custom-checkbox": "/components/custom-checkbox/custom-checkbox"}
}
<!--pages/index/index.wxml--><view><!-- 將導入的自定義組件當成標簽使用 --><custom-checkbox/>
</view>

2. 自定義組件-數據和方法

在組件的 .js 中,需要調用 Component 方法創建自定義組件,Component 中有以下兩個屬性:

data 數據:組件的內部數據

methods 方法:在組件中事件處理程序需要寫到 methods 中才可以

落地代碼:

?? components/custom-checkbox/custom-checkbox.wxml

<!--components/custom-checkbox/custom-checkbox.wxml-->
<!-- <text>我是自定義組件</text> --><view class="custom-checkbox-container"><view class="custom-checkbox-box"><checkbox checked="{{ isChecked }}" bindtap="updateChecked" /></view>
</view>

?? components/custom-checkbox/custom-checkbox.wxss

/* components/custom-checkbox/custom-checkbox.wxss */.custom-checkbox-container {display: inline-block;
}

?? components/custom-checkbox/custom-checkbox.js

Component({/*** 組件的初始數據:用來定義當前組件內部所需要使用的數據*/data: {isChecked: false},/*** 組件的方法列表:在組件中,所有的事件處理程序都需要寫到 methods 方法中*/methods: {// 更新復選框的狀態updateChecked () {this.setData({isChecked: !this.data.isChecked})console.log(this.data.isChecked)}}})

?? app.json

{"usingComponents": {"custom-checkbox": "./components/custom-checkbox/custom-checkbox"}
}

?? index.wxml

<custom-checkbox /><view class="line"></view><custom-checkbox />

3. 自定義組件-屬性

屬性 Properties 是指組件的對外屬性,主要用來接收組件使用者傳遞給組件內部的數據,和 data 一同用于組件的模板渲染

📌 注意事項:

  1. 設置屬性類型需要使用 type 屬性,屬性類型是必填項,value 屬性為默認值
  2. 屬性類型可以為 String、Number、Boolean、Object、Array ,也可以為 null 表示不限制類型

落地代碼:

?? index.wxml

<!-- label 文本顯示的內容 -->
<!-- position 控制文本顯示的位置 --><custom-checkbox label="我已閱讀并同意 用戶協議 和 隱私協議" position="right" /><view class="line"></view><custom-checkbox label="匿名提交" position="left" />

?? components/custom-checkbox/custom-checkbox.wxml

<!--components/custom-checkbox/custom-checkbox.wxml-->
<!-- <text>我是自定義組件</text> --><view class="custom-checkbox-container">
+   <view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left' }}">
+     <checkbox class="custom-checkbox" checked="{{ isChecked }}" bindtap="updateChecked" />
+ 
+     <view>
+       <text>{{ label }}</text>
+     </view></view>
</view>

?? components/custom-checkbox/custom-checkbox.wxss

/* components/custom-checkbox/custom-checkbox.wxss */.custom-checkbox-container {display: inline-block;
}.custom-checkbox-box {display: flex;align-items: center;
}.custom-checkbox-box.left {flex-direction: row-reverse;
}.custom-checkbox-box.right {flex-direction: row;
}.custom-checkbox {margin-left: 10rpx;
}

?? components/custom-checkbox/custom-checkbox.js

Component({+   /**
+    * 組件的屬性列表:組件的對外屬性,主要用來接收組件使用者傳遞給組件內部的屬性以及數據
+    */
+   properties: {
+     // 如果需要接收傳遞的屬性,有兩種方式:全寫、簡寫
+     // label: String
+ 
+     label: {
+       // type 組件使用者傳遞的數據類型
+       // 數據類型:String、Number、Boolean、Object、Array
+       // 也可以設置為 null,表示不限制類型
+       type: String,
+       value: ''
+     },
+ 
+     // 文字顯示位置
+     position: {
+       type: String,
+       value: 'right'
+     }
+   },/*** 組件的初始數據:用來定義當前組件內部所需要使用的數據*/data: {isChecked: false},/*** 組件的方法列表:在組件中,所有的事件處理程序都需要寫到 methods 方法中*/methods: {// 更新復選框的狀態updateChecked () {this.setData({isChecked: !this.data.isChecked,
+        // label: '在組件內部也可以修改 properties 中的數據'})+       // 在 JS 中可以訪問和獲取 properties 中的數據
+       // 但是一般情況下,不建議修改,因為會造成數據流的混亂
+       // console.log(this.properties.label)// console.log(this.data.isChecked)}}})

4. 組件 wxml 的 slot

在使用基礎組件時,可以給組件傳遞子節點傳遞內容,從而將內容展示到頁面中,自定義組件也可以接收子節點內容

只不過在組件模板中需要定義 <slot /> 節點,用于承載組件引用時提供的子節點
在這里插入圖片描述

默認情況下,一個組件的 wxml 中只能有一個 slot 。需要使用多 slot 時,可以在組件 js 中聲明啟用。

同時需要給 slot 添加 name 來區分不同的 slot,給子節點內容添加 slot 屬性來將節點插入到 對應的 slot 中
在這里插入圖片描述

知識點講解:

?? custom01.html

<view><slot name="slot-top" /><!-- slot 就是用來接收、承載子節點內容 --><!-- slot 只是一個占位符,子節點內容會將 slot 進行替換 --><!-- 默認插槽 --><view><slot /></view><slot name="slot-bottom" />
</view>

?? custom01.js

// components/custom01/custom01.jsComponent({options: {// 啟用多 slot 支持multipleSlots: true}})

?? cart.wxml

<custom01><text slot="slot-top">我需要顯示到頂部</text><!-- 默認情況下,自定義組件的子節點內容不會進行展示 --><!-- 如果想內容進行展示,需要再組件模板中定義 slot 節點 -->我是子節點內容<text slot="slot-bottom">我需要顯示到低部</text>
</custom01>

完善復選框案例

?? custom-checkbox.html

<!--components/custom-checkbox/custom-checkbox.wxml-->
<!-- <text>我是自定義組件</text> --><view class="custom-checkbox-container"><view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left' }}"><checkbox class="custom-checkbox" checked="{{ isChecked }}" bindtap="updateChecked" />+     <view>
+       <!-- lable 和 子節點內容都進行了展示 -->
+       <!-- 要么展示 lable 要么展示 子節點內容 -->
+       <!-- 如果用戶傳遞了 lable 屬性,就展示 lable -->
+       <!-- 如果用戶沒有傳遞 lable 屬性,就展示 子節點內容 -->
+       <text wx:if="{{ label !== '' }}">{{ label }}</text>
+ 
+       <slot wx:else />
+     </view></view>
</view>

?? index.html

<!-- label 文本顯示的內容 -->
<!-- position 控制文本顯示的位置 -->
<custom-checkbox label="我已閱讀并同意 用戶協議 和 隱私協議" position="right">我已閱讀并同意 用戶協議 和 隱私協議 - 111
</custom-checkbox><view class="line"></view><custom-checkbox label="匿名提交" position="left">匿名提交 - 222
</custom-checkbox>

5. 組件樣式以及注意事項

選擇器使用注意事項:

類似于頁面,自定義組件擁有自己的 wxss 樣式,組件對應 wxss 文件的樣式,只對組件wxml內的節點生效。

編寫組件樣式時,需要注意以下幾點:

  1. app.wxss 或頁面的 wxss 中使用了標簽名(view)選擇器(或一些其他特殊選擇器)來直接指定樣式
    這些選擇器會影響到頁面和全部組件,通常情況下這是不推薦的做法

  2. 組件和引用組件的頁面不能使用 id 選擇器(#a)、屬性選擇器([a]) 和 標簽名選擇器,請改用 class 選擇器

  3. 組件和引用組件的頁面中使用后代選擇器(.a .b)在一些極端情況下會有非預期的表現,如遇,請避免使用

  4. 子元素選擇器(.a>.b)只能用于 view 組件與其子節點之間,用于其他組件可能導致非預期的情況。

  5. 繼承樣式,如 font 、 color ,會從組件外繼承到組件內。

  6. 除繼承樣式外, 全局中的樣式、組件所在頁面的的樣式對自定義組件無效 (除非更改組件樣式隔離選項)

#a { } /* 在組件中不能使用 */
[a] { } /* 在組件中不能使用 */
button { } /* 在組件中不能使用 */
.a > .b { } /* 除非 .a 是 view 組件節點,否則不一定會生效 */

落地代碼:

?? custom02.wxml

<text id="content" class="content son"><text class="label">給自定義組件設置樣式</text>
</text>

?? custom02.wxss

/* components/custom02/custom02.wxss *//* 第一個注意事項:在自定義的 wxss 文件中,不允許使用標簽選擇器,ID 選擇器,屬性選擇器 */
/* 請改為 class 選擇器 */
/* text {color: lightseagreen;
} *//* #content {color: lightseagreen;
} *//* [id=content] {color: lightseagreen;
} *//* .content {color: lightseagreen;
} *//* 第二個注意事項:子選擇器,只能用于 view 和 子組件,用于其他組件可能會出現樣式失效的問題 */
/* .content > .label {color: lightseagreen;
} *//* 第三個注意事項:繼承樣式,例如:color\font 都會從組件外繼承 *//* 第四個注意事項:全局樣式、組件所在頁面的樣式文件中的樣式都對自定義組件無效 *//* 第五個注意事項:官方不推薦做法 */
/* 不建議在 全局樣式文件 以及 父級頁面之間使用標簽選擇器設置樣式 */
/* 如果是在全局樣式文件中設置樣式,會影響項目中全部的相同組件 */
/* 如果是再頁面樣式文件中設置樣式,會影響當前頁面所有的相同組件 *//* 第六個注意事項: */
/* 組件和組件使用者,如果使用了后代選擇器,可能會出現一些非預期情況 */
/* 如果出現,請避免 */

?? cate.wxml

<view class="custom parent"><view><custom02 /><view class="son test">我是父級頁面中的結構</view></view>
</view>

?? cate.wxss

/* pages/cate/cate.wxss *//* .custom  {color: lightseagreen;font-size: 50rpx;
} *//* .label {color: lightseagreen;
} *//* text {color: lightseagreen;
} */.parent .son.test {color: lightsalmon;
}

?? app.wxss

/* .label {color: lightseagreen;
} *//* text {color: lightseagreen;
} */

6. 組件樣式隔離

默認情況下,自定義組件的樣式只受到自定義組件 wxss 的影響。除非以下兩種情況:

  1. app.wxss 或頁面的 wxss 中使用了標簽名(view)選擇器(或一些其他特殊選擇器)來直接指定樣式,這些選擇器會影響到頁面和全部組件。通常情況下這是不推薦的做法。

  2. 指定特殊的樣式隔離選項 styleIsolation

    Component({options: {styleIsolation: 'isolated'}
    })
    

styleIsolation 選項它支持以下取值:

  • isolated 表示啟用樣式隔離,在自定義組件內外,使用 class 指定的樣式將不會相互影響(一般情況下的默認值);
  • apply-shared 表示頁面 wxss 樣式將影響到自定義組件,但自定義組件 wxss 中指定的樣式不會影響頁面;
  • shared 表示頁面 wxss 樣式將影響到自定義組件,自定義組件 wxss 中指定的樣式也會影響頁面和其他設置了 apply-sharedshared 的自定義組件。

落地代碼:

?? custom03.wxml

<!--components/custom03/custom03.wxml--><text class="label">演示組件樣式隔離</text>

?? custom03.wxss

/* components/custom03/custom03.wxss */.test {color: lightseagreen;font-size: 50rpx;
}

?? custom03.js

// components/custom03/custom03.js
Component({options: {// styleIsolation:配置組件樣式隔離// isolated:開啟樣式隔離,默認值// 在默認情況下,自定義組件和組件使用者如果存在相同的類名,類名不會相互影響// apply-shared:表示組件使用者、頁面的 wxss 樣式能夠影響到自定義組件// 但是自定義組件的樣式不會影響組件使用者、頁面的 wxss 樣式// styleIsolation: "apply-shared"// shared:表示組件使用者、頁面的 wxss 樣式能夠影響到自定義組件// 自定義組件的樣式會影響組件使用者、頁面的 wxss 樣式// 和其他使用了 apply-share 以及 share 屬性的自定義組件styleIsolation: 'shared'}})

?? cate.wxml

<custom03 />

?? cate.wxss

.label {color: lightsalmon;
}

7. 拓展-小程序修改checkbox樣式

知識點:

技巧:在官方文檔,找到官方提供的案例,審查元素,就能看到對應的類名

在這里插入圖片描述

📌 注意事項

  1. .custom-checkbox .wx-checkbox-input {}:復選框沒有選中時默認的樣式
  2. .custom-checkbox .wx-checkbox-input-checked {}: 復選框選中時默認的樣式
  3. .custom-checkbox .wx-checkbox-input.wx-checkbox-input-checked:before {}:復選框選中時 √ 樣式

這幾個類名,在全局樣式文件、頁面樣式文件都可以對修改復選框樣式,

但是在自定義組件內部使用的時候,需要添加 styleIsolation: 'shared' 屬性

落地代碼:

?? components/custom-checkbox/custom-checkbox.wxss

/* 復選框組件是公共組件 */
/* 以后需要再多個頁面或者需要再多個項目中進行使用 */
/* 所以呢,需要先給復選框組件準備、設置一些默認樣式 */
/* 如果在其他頁面或者其他項目中使用的時候,發現樣式不符合產品需求 */
/* 可以進行修改、對默認的樣式進行修改 *//* 1. 需要給復選框設置默認樣式 */
/* 需要先找到小程序給復選框提供的類名,通過小程序給提供的類名修改才可以 */
/* 需要先打開小程序開發文檔,找到復選框文檔,審查元素,進行查找 *//* 在自定義組件中,不能直接修改復選框樣式 */
/* 如果需要進行修改,需要設置 styleIsolation 才可以 */
/* shared:修改其他頁面的樣式、組件使用者的樣式、以及其他使用了 share 以及 apply-share 的組件 */
/* 這時候,不是想要的結果 */
/* 需求是:只想影響當前組件,可以添加命名空間 *//* 復選框沒有選中時默認的樣式 */
.custom-checkbox .wx-checkbox-input {width: 24rpx !important;height: 24rpx !important;border-radius: 50% !important;border: 1px solid #fda007 !important;margin-top: -6rpx;
}/* 復選框選中時默認的樣式 */
.custom-checkbox .wx-checkbox-input-checked {background-color: #fda007 !important;
}/* 復選框選中時 √ 樣式 */
.custom-checkbox .wx-checkbox-input.wx-checkbox-input-checked:before {font-size: 22rpx;color: #fff;
}/* 2. 組件使用者也能夠修改默認的樣式 */

?? components/custom-checkbox/custom-checkbox.js

Component({options: {styleIsolation: 'shared'}})

?? index.wxss

/* 組件使用者修改復選框的樣式 */
.custom .custom-checkbox .wx-checkbox-input {border: 1px solid lightseagreen !important;
}.custom .custom-checkbox .wx-checkbox-input-checked {background-color: lightseagreen !important;
}

8. 數據監聽器

知識點:

數據監聽器可以用于監聽和響應任何屬性和數據字段的變化,有時,需要在一些數據字段被 setData 設置時,需要執行一些操作。那么就可以使用 observers 數據監聽器來實現。語法如下:

Component({data: {num: 10,count: 1,obj: { name: 'Tom', age: 10 },arr: [1, 2, 3]},observers: {// key 是需要檢測數據// value 是一個函數,函數接收一個形參作為參數,是最新的值num: function(newNum) {console.log(newNum)},// 數據監聽器支持監聽屬性或內部數據的變化,可以同時監聽多個'num, count': function (newNum, newCount) {console.log(newNum, newCount)}// 監聽器可以監聽子數據字段'obj.age': function(newAge) {console.log(newAge)},// 如果需要監聽所有子數據字段的變化,可以使用通配符 ** 'obj.**': function(newAge) {console.log(newAge)},'arr[0]': function (val) {}}
})

9. 組件間通信與事件

9.1 父往子傳值

知識點:

父組件如果需要向子組件傳遞指定屬性的數據,在 WXML 中需要使用數據綁定的方式

與普通的 WXML 模板類似,使用數據綁定,這樣就可以向子組件的屬性傳遞動態數據。

父組件如果需要向子組件傳遞數據,只需要兩個步驟:

1.在父組件 WXML 中使用 數據綁定 的方式向子組件傳遞動態數據

2.子組件內部使用 properties 接收父組件傳遞的數據即可

知識點代碼:

<!-- 引用組件的頁面模板 -->
<view><costom prop-a="{{ name }}" prop-b="{{ age }}" />
</view>

在組件內部,需要在 Component 構造器中通過 properties 接收傳遞的數據,接收方式有兩種:

Component({/*** 組件的屬性列表 props*/properties: {propA: {type: String, // 傳遞的數據類型value: '' // 默認值},propB: Number // 簡化的定義方式},// coding...
})

在子組件中也可以通過 this.setData()properties 中的數據進行修改,但是一般不建議修改

// components/custom01/custom01.js
Component({/*** 組件的方法列表*/methods: {// 修改列表中的數據updateProp () {this.setData({propB: this.properties.propB + 1})}}
})

復選框組件案例:

?? index.js

Page({data: {isChecked: true},// coding...})

?? index.wxml

<custom-checkboxlabel="我已閱讀并同意 用戶協議 和 隱私協議"position="right"
+   checked="{{ isChecked }}">我已閱讀并同意 用戶協議 和 隱私協議 - 111
</custom-checkbox>

?? components/custom-checkbox/custom-checkbox.js

Component({options: {styleIsolation: 'shared'},properties: {// coding...// 復選框組件公共組件// 需要再多個頁面、在多個項目中進行使用// 在使用的時候,有的地方希望默認是選中的效果,有的地方希望默認是沒有被選中的效果// 怎么處理 ?// 首先讓復選框默認還是沒有被選中的效果// 如果希望復選框默認被選中,這時候傳遞屬性(checked=true)到復選框組件
+     checked: {
+       type: Boolean,
+       value: false
+     }},/*** 組件的初始數據:用來定義當前組件內部所需要使用的數據*/data: {isChecked: false},+   observers: {
+     // 如果需要將 properties 中的數據賦值給 data
+     // 可以使用 observers 進行處理
+     checked: function (newChecked) {
+       // console.log(newChecked)
+       this.setData({
+         isChecked: newChecked
+       })
+     }
+   },/*** 組件的方法列表:在組件中,所有的事件處理程序都需要寫到 methods 方法中*/methods: {// 更新復選框的狀態updateChecked () {this.setData({
+         isChecked: !this.data.isChecked,
+         // checked: !this.properties.checked// label: '在組件內部也可以修改 properties 中的數據'})// 在 JS 中可以訪問和獲取 properties 中的數據// 但是一般情況下,不建議修改,因為會造成數據流的混亂// console.log(this.properties.label)// console.log(this.data.isChecked)}}})

?? components/custom-checkbox/custom-checkbox.wxml

<!--components/custom-checkbox/custom-checkbox.wxml-->
<!-- <text>我是自定義組件</text> --><view class="custom-checkbox-container"><view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left' }}">
+     <checkbox class="custom-checkbox" checked="{{ isChecked }}" bindtap="updateChecked" /><view class="content"><!-- lable 和 子節點內容都進行了展示 --><!-- 要么展示 lable 要么展示 子節點內容 --><!-- 如果用戶傳遞了 lable 屬性,就展示 lable --><!-- 如果用戶沒有傳遞 lable 屬性,就展示 子節點內容 --><text wx:if="{{ label !== '' }}">{{ label }}</text><slot wx:else /></view></view>
</view>
9.2 子往父傳值

子組件如果需要向父組件傳遞數據,可以通過小程序提供的事件系統實現傳遞傳遞,可以傳遞任意數據。

事件系統是組件間通信的主要方式之一,自定義組件可以觸發任意的事件,引用組件的頁面可以監聽這些事件,流程如下:

  1. 自定義組件觸發事件時,需要使用 triggerEvent 方法發射一個自定義的事件
  2. 自定義組件標簽上通過 bind 方法監聽發射的事件

觸發事件:

<!-- 在自定義組件中 -->
<button type="primary" plain bindtap="sendData">傳遞數據</button>
// components/custom05/custom05.js
Component({// 組件的初始數據data: {num: 666},// 組件的方法列表methods: {// 將數據傳遞給父組件sendData () {// 如果需要將數據傳遞給父組件// 需要使用 triggerEvent 發射自定義事件// 第二個參數,是攜帶的參數this.triggerEvent('myevent', this.data.num)}}
})

監聽事件:

<view>{{ num }}</view>
<!-- 需要在自定義組件標簽上通過 bind 方法綁定自定義事件,同時綁定事件處理函數 -->
<custom05 bind:myevent="getData" />
Page({data: {num: ''},getData (event) {// 可以通過事件對象.detail 獲取子組件傳遞給父組件的數據// console.log(event)this.setData({num: event.detail})}})

復選框組件案例:

?? components/custom-checkbox/custom-checkbox.js

Component({/*** 組件的方法列表:在組件中,所有的事件處理程序都需要寫到 methods 方法中*/methods: {// 更新復選框的狀態updateChecked () {this.setData({isChecked: !this.data.isChecked,// label: '在組件內部也可以修改 properties 中的數據'})// 在 JS 中可以訪問和獲取 properties 中的數據// 但是一般情況下,不建議修改,因為會造成數據流的混亂// console.log(this.properties.label)// console.log(this.data.isChecked)+       // 目前復選框組件的狀態是存儲在復選框組件內部的、存儲在自定義組件內部的
+       // 但是,在以后實際開發中,組件使用者、父組件有時候也需要獲取到復選框內部的狀態
+       // 怎么辦 ?
+       // 這時候,自定義組件內部就需要發射一個自定義事件,
+       // 如果組件使用者、父組件需要使用數據,綁定自定義事件進行獲取即可
+       this.triggerEvent('changechecked', this.data.isChecked)}}})

?? index.html

<custom-checkboxlabel="我已閱讀并同意 用戶協議 和 隱私協議"position="right"checked="{{ isChecked }}"class="getchild"
+  bind:changechecked="getData"
>我已閱讀并同意 用戶協議 和 隱私協議 - 111
</custom-checkbox>

?? index.js

Page({data: {isChecked: true},getData (event) {console.log(event.detail)if (event.detail) {console.log('提交')} else {console.log('請同意協議!')}}})
9.3 獲取組件實例

如果前面兩種方式不足以滿足需要。

可在父組件里調用 this.selectComponent() ,獲取子組件的實例對象,就可以直接拿到子組件的任意數據和方法。調用時需要傳入一個匹配選擇器 selector,如:this.selectComponent(".my-component")

<!-- 父組件 -->
<costom bind:myevent="getData" class="custom" />
<button bindtap="getChildComponent"></button>
// 父組件
Page({data: {},getChildComponent: function () {const child = this.selectComponent('.custom')console.log(child)}
})

復選框組件案例:

?? index.html

<custom-checkboxlabel="我已閱讀并同意 用戶協議 和 隱私協議"position="right"checked="{{ isChecked }}"
+   class="child"
+  id="child"bind:changechecked="getData"
>我已閱讀并同意 用戶協議 和 隱私協議 - 111
</custom-checkbox><button type="primary" plain bindtap="getChild">獲取子組件實例對象</button>

?? index.js

Page({// coding...// 獲取子組件的實例對象getChild () {// this.selectComponent 方法獲取子組件實例對象// 獲取到實例對象以后,就能獲取子組件所有的數據、也能調用子組件的方法const res = this.selectComponent('#child')console.log(res.data.isChecked)}})

10. 組件生命周期

組件的生命周期:指的是組件自身的一些鉤子函數,這些函數在特定的時間節點時被自動觸發

組件的生命周期函數需要在 lifetimes 字段內進行聲明

最重要的生命周期是 created attached detached 包含一個組件生命周期流程的最主要時間點

定義段描述
created在組件實例剛剛被創建時執行,注意此時不能調用 setData (還沒有對模板解析)
attached在組件實例進入頁面節點樹時執行 (模板已經解析完畢,并且掛載到頁面上)
ready在組件布局完成后執行
moved在組件實例被移動到節點樹另一個位置時執行
detached在組件實例被從頁面節點樹移除時執行 (組件被銷毀了)
在這里插入圖片描述
  1. 【組件實例剛剛被創建好時】, created 生命周期被觸發。此時,組件數據 this.data 就是在 Component 構造器中定義的數據 data此時還不能調用 setData 通常情況下,這個生命周期只應該用于給組件 this 添加一些自定義屬性字段。

  2. 【在組件完全初始化完畢】、進入頁面節點樹后, attached 生命周期被觸發。此時, this.data 已被初始化為組件的當前值。這個生命周期很有用,絕大多數初始化工作可以在這個時機進行。

  3. 【在組件離開頁面節點樹后】, detached 生命周期被觸發。退出一個頁面時,如果組件還在頁面節點樹中,則 detached 會被觸發。

Component({lifetimes: {created: function () {// 在組件實例剛剛被創建時執行,注意此時不能調用 setData // 一般用來為組件添加一些自定義屬性字段。},attached: function() {// attached 在組件完全初始化完畢、進入頁面節點樹后執行// 模板已經解析完畢,并且掛載到頁面上// 一般都是在這里寫對應的交互},detached: function() {// 在組件實例被從頁面節點樹移除時執行},// coding...}// coding...
})

11. 組件所在頁面的生命周期

組件還有一些特殊的生命周期,這類生命周期和組件沒有很強的關聯

主要用于組件內部監聽父組件的展示、隱藏狀態,從而方便組件內部執行一些業務邏輯的處理

組件所在頁面的生命周期有 4 個: show、 hide、 resize、 routeDone,需要在 pageLifetimes 字段內進行聲明
在這里插入圖片描述

// components/custom06/custom06.js
Component({// coding...// 組件所在頁面的生命周期pageLifetimes: {// 監聽組件所在的頁面展示(后臺切前臺)狀態show () {console.log('組件所在的頁面被展示')},// 監聽組件所在的頁面隱藏(前臺切后臺、點擊 tabBar)狀態hide () {console.log('組件所在的頁面被隱藏')}}})

12. 小程序生命周期總結

小程序冷啟動,鉤子函數執行的順序

保留當前頁面(navigate) 以及 關閉當前頁面(redirect)

切后臺 以及 切前臺(熱啟動)

13. 拓展:使用 Component 構造頁面

Component 方法用于創建自定義組件

小程序的頁面也可以視為自定義組件,因此頁面也可以使用 Component 方法進行創建,從而實現復雜的頁面邏輯開發

📌 注意事項:

  1. 要求對應 json 文件中包含 usingComponents 定義段

  2. 頁面使用 Component 構造器創建,需要定義與普通組件一樣的字段與實例方法

  3. 頁面 Page 中的一些生命周期方法(如 onLoad() 等以“on”開頭的方法),在 Component 中要寫在 methods 屬性中才能生效

  4. 組件的屬性 Properties 可以用于接收頁面的參數,在 onLoad() 中可以通過 this.data 拿到對應的頁面參數

落地代碼:

Component({// 為什么需要使用 Component 方法進行構造頁面// Component 方法功能比 Page 方法強大很多// 如果使用 Component 方法構造頁面,可以實現更加復雜的頁面邏輯開發// 小程序頁面也可以使用 Component 方法進行構造// 注意事項:// 1. 要求 .json 文件中必須包含 usingComponents 字段// 2. 里面的配置項需要和 Component 中的配置項保持一致// 3. 頁面中 Page 方法有一些鉤子函數、事件監聽方法,這些鉤子函數、事件監聽方法必須方法 methods 對象中// 4. 組件的屬性 properties 也可以接受頁面的參數,在 onLoad 鉤子函數中可以通過 this.data 進行獲取properties: {id: String,title: String},data: {name: 'tom'},// onLoad () {//   console.log('頁面加載 - 1')// },methods: {// 更新 nameupdateName() {this.setData({name: 'jerry'})},onLoad (options) {// console.log('頁面加載 - 2')// console.log(options)console.log(this.data.id)console.log(this.data.title)console.log(this.properties.id)},}})

14. 拓展:behaviors

小程序的 behaviors 方法是一種代碼復用的方式,可以將一些通用的邏輯和方法提取出來,然后在多個組件中復用,從而減少代碼冗余,提高代碼的可維護性。

如果需要 behavior 復用代碼,需要使用 Behavior() 方法,每個 behavior 可以包含一組屬性、數據、生命周期函數和方法

組件引用它時,它的屬性、數據和方法會被合并到組件中,生命周期函數也會在對應時機被調用。

注冊 behavior:

如果需要注冊一個 behavior,需要借助 Behavior() 方法,接受一個 Object 類型的參數

// my-behavior.jsmodule.exports = Behavior({behaviors: [],properties: {myBehaviorProperty: {type: String}},data: {myBehaviorData: 'my-behavior-data'},created: function () {console.log('[my-behavior] created')},attached: function () {console.log('[my-behavior] attached')},ready: function () {console.log('[my-behavior] ready')},methods: {myBehaviorMethod: function () {console.log('[my-behavior] log by myBehaviorMehtod')},}
})

使用 behavior:

// my-component.js
const myBehavior = require('my-behavior')Component({behaviors: [myBehavior]// coding...
})

組件和它引用的 behavior 中可以包含同名的字段,對這些字段的處理方法如下:

  1. 如果有同名的屬性或方法,采用 “就近原則”,組件會覆蓋 behavior 中的同名屬性或方法

  2. 如果有同名的數據字段且都是對象類型,會進行對象合并,其余情況會 采用 “就近原則” 進行數據覆蓋

  3. 生命周期函數和 observers 不會相互覆蓋,會是在對應觸發時機被逐個調用,也就是都會被執行

詳細的規則:同名字段的覆蓋和組合規則

15. 拓展:外部樣式類

默認情況下,組件和組件使用者之間如果存在相同的類名不會相互影響,組件使用者如果想修改組件的樣式,需要就解除樣式隔離,但是解除樣式隔離以后,在極端情況下,會產生樣式沖突、CSS 嵌套太深等問題,從而給我們的開發帶來一定的麻煩。

外部樣式類:在使用組件時,組件使用者可以給組件傳入 CSS 類名,通過傳入的類名修改組件的樣式。

如果需要使用外部樣式類修改組件的樣式,在 Component 中需要用 externalClasses 定義若干個外部樣式類。

外部樣式類的使用步驟:

1.在 Component 中用 externalClasses 定義段定義若干個外部樣式類

2.自定義組件標簽通過 屬性綁定 的方式提供一個樣式類,屬性是 externalClasses 定義的元素,屬性值是傳遞的類名

3.將接受到的樣式類用于自定義組件內部

📌注意事項:

? 在同一個節點上使用普通樣式類和外部樣式類時,兩個類的優先級是未定義的

? 因此需要添加 !important 以保證外部樣式類的優先級

落地代碼:

?? custom09.js

// components/custom09/custom09.js
Component({// 組件接受的外部樣式類externalClasses: ['extend-class']
})

?? custom09.wxml

<!-- 在同一個節點上,如果存在外部樣式類 和 普通的樣式類 -->
<!-- 兩個類的優先級是未定義的 -->
<!-- 建議:在使用外部樣式類的時,樣式需要通過 !important 添加權重 -->
<view class="extend-class box">通過外部樣式類修改組件的樣式</view>

?? custom09.wxss

.box {color: lightseagreen;
}

?? profile.wxml

<!-- 屬性是在 externalClasses 里面定義的元素 -->
<!-- 屬性值必須是一個類名 -->
<custom09 extend-class="my-class" />

?? profile.wxss

/* pages/index/index.wxss */.my-class {color: lightsalmon !important;
}

16. 完善復選框案例并總結自定義組件

總結自定義組件:

  1. 組件基本使用:數據、屬性、方法、插槽

  2. 組件樣式使用:組件樣式、注意事項、樣式隔離、外部樣式類

  3. 組件通信傳值:父往子傳值、子往父傳值、獲取組件實例

  4. 組件生命周期:組件的生命周期、組件所在頁面的生命周期、總結了小程序全部的生命周期

  5. 組件數據監聽器:observers

  6. 組件拓展:使用 Component 構造頁面、組件復用機制 behaviors 等

完善復選框案例

?? components/custom-checkbox/custom-checkbox.wxml

<!--components/custom-checkbox/custom-checkbox.wxml-->
<!-- <text>我是自定義組件</text> --><view class="custom-checkbox-container"><view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left' }}">
+    <label class="custom-label"><checkbox class="custom-checkbox" checked="{{ isChecked }}" bindtap="updateChecked" /><view class="content"><!-- lable 和 子節點內容都進行了展示 --><!-- 要么展示 lable 要么展示 子節點內容 --><!-- 如果用戶傳遞了 lable 屬性,就展示 lable --><!-- 如果用戶沒有傳遞 lable 屬性,就展示 子節點內容 --><text wx:if="{{ label !== '' }}">{{ label }}</text><slot wx:else /></view>
+    </label></view>
</view>

?? components/custom-checkbox/custom-checkbox.wxss

+ .custom-checkbox-box .custom-label {display: flex;align-items: center;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711823.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711823.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711823.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

111790-37-5 ,生物素-氨基,一種生物素化合物,可與-NHS、-COOH反應

您好&#xff0c;歡迎來到新研之家 文章關鍵詞&#xff1a;111790-37-5 &#xff0c;生物素-氨基&#xff0c;生物素氨基&#xff0c;Biotin-NH2&#xff0c;Biotin-amine 一、基本信息 【產品簡介】&#xff1a;Biotin-NH2 provides a convenient biotinylation method for…

OSCP靶場--DVR4

OSCP靶場–DVR4 考點(1.windows&#xff1a;路徑遍歷獲取私鑰getshell 2.ssh shell中runas切換用戶) 1.nmap掃描 ┌──(root?kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.161.179 --min-rate 2000 Starting Nmap 7.92 ( https://nmap.org ) at 2024-02-29 07:14 EST…

Springboot接口參數校驗

在設計接口時我們通常需要對接口中的非法參數做校驗&#xff0c;以降低在程序運行時因為一些非法參數而導致程序發生異常的風險&#xff0c;例如登錄的時候需要校驗用戶名密碼是否為空&#xff0c;創建用戶的時候需要校驗郵件、手機號碼格式是否準確。如果在代碼中對接口參數一…

系統集成Prometheus+Grafana

根據產品需求在自己的系統中添加一個系統監控的頁面&#xff0c;其中有主機信息的顯示&#xff0c;也有一些業務信息的顯示。調研后的方案是 主機信息通過Prometheus采集和存儲&#xff0c;業務信息通過自己系統的調度任務統計后存儲在Mysql中&#xff0c;使用Grafana對接Prome…

Java必須掌握的繼承的特點和繼承體系的設計(含面試大廠題和源碼)

Java繼承是面向對象編程的一個基本特性&#xff0c;它允許一個類繼承另一個類的屬性和方法。設計良好的繼承體系是高質量軟件開發的關鍵。在大廠面試中&#xff0c;面試官可能會詢問關于Java繼承特點及如何設計一個合理的繼承體系的問題&#xff0c;以評估你的面向對象設計能力…

ICLR 2024|ReLU激活函數的反擊,稀疏性仍然是提升LLM效率的利器

論文題目&#xff1a; ReLU Strikes Back: Exploiting Activation Sparsity in Large Language Models 論文鏈接&#xff1a; https://arxiv.org/abs/2310.04564 參數規模超過十億&#xff08;1B&#xff09;的大型語言模型&#xff08;LLM&#xff09;已經徹底改變了現階段人工…

gcc和g++的區別,如何看自己的編譯器支持的C++的版本

gcc和g的區別 用一句話來說&#xff0c;就是gcc將程序視為c語言的&#xff0c;g將程序視為C的 gcc和g的區別主要在于它們處理不同后綴的文件類型、編譯和連接階段的不同調用方式&#xff0c;以及它們對C特性的支持方式。以下是詳細介紹&#xff1a;123 文件類型。gcc將后綴為…

通過多線程并發方式實現服務器

與多進程實現對比來看。 示例來源于網絡視頻 #include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <ctype.h> #include <unistd.h> #include <fcntl.h>#include "wrap.h"#de…

【C++ 測試】

C 測試 一、二維數組二、私有成員三、function用法四、類里面創建另一個類五、lambda六、Map動態申請 一、二維數組 #include <iostream> #include<windows.h> #include <map> // SetConsoleOutputCP ( CP_UTF8 ) ; using namespace std;void test1() {map…

求最短路徑之迪杰斯特拉算法

對fill用法的介紹 1.用鄰接矩陣實現 const int maxn100; const int INF100000000;//無窮大&#xff0c;用來初始化邊 int G[maxn][maxn];//用鄰接矩陣存儲圖的信息 int isin[maxn]{false};//記錄是否已被訪問 int minDis[maxn];//記錄到頂點的最小距離void Dijkstra(int s,in…

網格圖的搜索

來自靈神網格圖題單。 1. 網格圖 1.1. LC 200 島嶼數量 這題我一開始想繁了&#xff0c;想維護并查集&#xff0c;然后看等價類個數。其實完全沒有必要。因為連通分量深搜到頭就可以直接給答案計數1。利用vis數組維護訪問過的點&#xff0c;然后碰到新連通分量重新深搜即可。…

Pinia使用

官方地址&#xff1a;Pinia | The intuitive store for Vue.js (vuejs.org)https://pinia.vuejs.org/ 1.安裝 npm install pinia npm install pinia-plugin-persistedstate Pinia是一個基于Vue 3的狀態管理庫&#xff0c;它使得管理Vue的全局狀態變得更加容易和直觀。 而…

自定義el-dialog的樣式

實現效果&#xff1a; 樣式代碼如下&#xff1a;&#xff08;可以寫在common.scss文件夾中&#xff09; .el-dialog__header {padding: 16px 20px;border-bottom: 1px solid #DCDFE6;display: flex;align-items: center;.el-dialog__title {font-size: 16px;position: relativ…

utniy urp shinyssrr插件使用

文章目錄 前言步驟1首先在URP的配置文件里添加SSR后處理2 修改RenderingPath為延遲渲染3 啟用深度紋理4 為物體添加腳本 插件下載 前言 用來實現屏幕空間反射效果 unity 版本為2021.3.8LTS&#xff0c;低版本的untiy URP的參數設置位置z可能會不同 步驟 1首先在URP的配置文件…

記錄阿里云換源失敗的慘痛教訓

聲明 首先我不是一個云服務器小白&#xff0c;但是之前一直在使用騰訊云和火山引擎的云服務器。從未見過阿里云這樣如此**的運營商。 問題 服務器到手&#xff0c;第一步在我進行sudo apt update的時候&#xff0c;也就是更新軟件包的時候&#xff0c;我發現&#xff0c;一直…

1028. 從先序遍歷還原二叉樹(三種方法:棧+遞歸+集合)

文章目錄 1028. 從先序遍歷還原二叉樹&#xff08;三種方法&#xff1a;棧遞歸集合&#xff09;一、棧 while迭代1.思路2.代碼 二、遞歸法1.思路2.代碼 三、集合存儲1.思路2.代碼 1028. 從先序遍歷還原二叉樹&#xff08;三種方法&#xff1a;棧遞歸集合&#xff09; 一、棧 wh…

hive報錯:FAILED: NullPointerException null

發現問題 起因是我虛擬機的hive不管執行什么命令都報空指針異常的錯誤 我也在網上找了很多相關問題的資料&#xff0c;發現都不是我這個問題的解決方法&#xff0c;后來在hive官網上與hive 3.1.3版本相匹配的hadoop版本是3.x的版本&#xff0c;而我的hadoop版本還是2.7.2的版本…

HTTPS的加密過程

文章目錄 前言一、為什么需要加密&#xff1f;二、只用對稱加密可以嗎&#xff1f;三、只使用非對稱加密四、雙方都使用非對稱加密五、使用非對稱加密對稱加密六、引入證書1.如何放防止數字證書被篡改&#xff1f;2.中間人有可能篡改該證書嗎&#xff1f;3.中間人有可能掉包該證…

開窗函數rank() over,dense_rank() over,row_number() over的區別

1.rank() over 查詢出指定的條件進行排名&#xff0c;條件相同排名相同的話&#xff0c;排名之間是不連續的 例如排名如 1 2 3 3 5 6 7 等&#xff0c;相同的排名會自動跳過 2.dense_rank() over 查詢出指定的條件后進行排名&#xff0c;條件相同&#xff0c;排名相同的話&…

【YOLO系列】YOLOv9論文超詳細解讀(翻譯 +學習筆記)

前言 時隔一年&#xff0c;YOLOv8還沒捂熱&#xff0c;YOLO系列最新版本——YOLOv9 終于閃亮登場&#xff01; YOLOv9的一作和v7一樣。v4也有他。 他于2017年獲得臺灣省National Central University計算機科學與信息工程博士學位&#xff0c;現在就職于該省Academia Sinica的…