一、小程序API
1.界面交互
(1)loading提示框

其中mask:布尔值
true表示用户在数据加载中不可以点击
false表示用户在数据加载中可以点击
javascript
Page({
data: {
list: []
},
// 获取数据
getData () {
// 显示 loading 提示框
wx.showLoading({
// 用来显示提示的内容
// 提示的内容不会自动换行,如果提示的内容比较多,因为在同一行显示
// 多出来的内容就会被隐藏
title: '数据加载中...',
// 是否显示透明蒙层,防止触摸穿透
mask:false
})
// 如果需要发起网络请求,需要使用 wx.request API
wx.request({
// 接口地址
url: 'https://gamll-prod.atguigu.cn/mall-api/index/findBanner',
// 请求方式
method: 'GET',
// 请求参数
data: {},
// 请求头
header: {},
// API 调用成功以后,执行的回调
success: (res) => {
// console.log(res)
if (res.data.code === 200) {
this.setData({
list: res.data.data
})
}
},
// API 调用失败以后,执行的回调
fail: (err) => {
console.log(err)
},
// API 不管调用成功还是失败后,执行的回调
complete: (res) => {
// console.log(res)
// 关掉 loading 提示框
// hidLoading 和 showLoading 必须结合,配对使用才可以
wx.hideLoading()
}
})
}
})
(2)模态对话框-消息提示框

javascript
// 写在page里面
// 删除商品
async delHandler() {
// showModal 显示模态对话框
const { confirm } = await wx.showModal({
title: '提示',
content: '是否删除该商品?'
})
if (confirm) {
// showToast 消息提示框
wx.showToast({
title: '删除成功',
icon: 'none',
duration: 2000
})
} else {
wx.showToast({
title:'取消删除',
icon: 'error',
duration: 2000
})
}
2.本地存储

html
<button size="mini" plain type="warn" bind:tap="setStorage">存储</button>
<button size="mini" plain type="primary" bind:tap="getStorage">获取</button>
<button size="mini" plain type="warn" bind:tap="removeStorage">删除</button>
<button size="mini" plain type="primary" bind:tap="clearStorage">清空</button>
javascript
// pages/cate/cate.js
Page({
// 将数据存储到本地
setStorage () {
// 第一个参数:本地存储中指定的 key
// 第二各参数:需要存储的数据
wx.setStorageSync('num', 1)
// 在小程序中
// 如果存储的是对象类型数据,不需要使用JSON.stringify 和 JSON.parse 进行转换
// 直接进行存储和获取即可
wx.setStorageSync('obj', {name: 'tom', age: 10 })
// ----------------- 异步 API ---------------------------
wx.setStorage({
key: 'num',
data: 1
})
wx.setStorage({
key: 'obj',
data: { name: 'jerry', age: 18 }
})
},
// 获取本地存储的数据
async getStorage () {
// 从本地存储的数据中获取指定 key 的数据 内容
const num = wx.getStorageSync('num')
const obj = wx.getStorageSync('obj')
console.log(num)
console.log(obj)
// ----------------- 异步 API ---------------------------
const {data} = await wx.getStorage({
key: 'obj'
})
console.log(data)
},
// 删除本地存储的数据
removeStorage () {
// 从本地移除指定 key 的数据 内容
wx.removeStorageSync('num')
// ----------------- 异步 API ---------------------------
wx.removeStorage({
key: 'num'
})
},
// 清空本地存储的全部数据
clearStorage () {
// 不需要存任何参数
wx.clearStorageSync()
// ----------------- 异步 API ---------------------------
wx.clearStorage()
},
})// pages/cate/cate.js
Page({
// 将数据存储到本地
setStorage () {
// 第一个参数:本地存储中指定的 key
// 第二各参数:需要存储的数据
wx.setStorageSync('num', 1)
// 在小程序中
// 如果存储的是对象类型数据,不需要使用JSON.stringify 和 JSON.parse 进行转换
// 直接进行存储和获取即可
wx.setStorageSync('obj', {name: 'tom', age: 10 })
},
// 获取本地存储的数据
getStorage () {
// 从本地存储的数据中获取指定 key 的数据 内容
const num = wx.getStorageSync('num')
const obj = wx.getStorageSync('obj')
console.log(num)
console.log(obj)
},
// 删除本地存储的数据
removeStorage () {
// 从本地移除指定 key 的数据 内容
wx.removeStorageSync('num')
},
// 清空本地存储的全部数据
clearStorage () {
// 不需要存任何参数
wx.clearStorageSync()
},
})
3.路由与通信
(1)声明式导航:navigator 组件
(2)编程式导航:使用小程序提供的API

路径后可以带参数,参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔,eg:path?key=value&key2=value2
参数需要在跳转到的页面的onLoad钩子函数中通过形参进行接收
html
<button plain type="warn">navigateTo</button>
<button plain type="primary">redireectTo</button>
<button plain type="warn">switchTab</button>
<button plain type="primary">reLaunch</button>
// list
<button plain type="warn">navigateBack</button>
javascript
Page({
navigateTo () {
// 保留当前页面,跳转到应用中其他页面,不能跳转到 tabBar 页面
wx.navigateTo({
// 不知道为啥跳不过去,第一个跳转
url: '/pages/list/list?id=1&name=tom'
// url: '/pages/cate/cate'
})
},
redireectTo () {
// 关闭(销毁)当前页面,跳转到应用中其他页面,不能跳转到 tabBar 页面
wx.redireectTo({
url: '/pages/list/list?id=1&name=tom'
// url: '/pages/cate/cate'
})
},
switchTab () {
// 跳转到 tabBar 页面,不能跳转道非 tabBar 页面,路径后面不能传递参数
wx.switchTab({
// url: '/pages/list/list'
url: '/pages/cate/cate'
})
},
reLaunch () {
// 关闭所有的页面,然后跳转到应用中某一个页面
wx.reLaunch({
// url: '/pages/list/list'
url: '/pages/cate/cate?id=1&name=tom'
})
},
})
// list
Page({
navigateBack () {
// 关闭当前页面,返回上一页或者返回多级页面
// 默认返回上一页
wx.navigateBack({
delta: 1
})
},
onLoad(options) {
console.log(options)
}
})
4.页面处理函数
(1)上拉加载

(2)下拉刷新

html
<!--pages/market/market.wxml-->
<view wx:for="{{ numList }}" wx:key="this">{{ item }}</view>
javascript
// market.json
{
"usingComponents": {},
"onReachBottomDistance": 100,
"enablePullDownRefresh": true,
"backgroundColor": "#efefef",
"backgroundTextStyle": "light"
}
javascript
// pages/market/market.js
Page({
data: {
numList: [1,2,3]
},
// 监听用户上拉加载
onReachBottom () {
// console.log('监听用户上拉加载')
// 产品需求:
// 当用户上拉,需要数字进行累加
// 当用户上拉加载时,需要对数字进行累加,每次累加 3 个数字
// 目前是 [1, 2, 3],[1, 2, 3, 4, 5, 6]
// 怎么进行追加?
// 获取目前数组最后一项 n, n + 1, n + 2, n + 3
wx.showLoading({
title: '数据加载中...',
})
setTimeout(() => {
// 获取数组的最后一项
const lastNum = this.data.numList[this.data.numList.length - 1]
// 定义需要追加的元素
const newArr = [lastNum + 1, lastNum + 2, lastNum + 3]
this.setData({
numList: [...this.data.numList, ...newArr]
})
wx.hideLoading()
}, 1500)
},
// 监听用户下拉刷新
onPullDownRefresh () {
// console.log('监听用户下拉刷新')
// 产品需求:
// 当用户上拉加载更多以后,如果用户进行了下拉刷新
// 需要将数据进行重置
this.setData({
numList: [1, 2, 3]
})
// 在下拉刷新之后, loading 效果有可能不会回弹回去
if (this.data,numList.length === 3) {
wx.stopPullDownRefresh()
}
}
})
5.拓展-增强 scroll-view
使用 scroll-view 实现上拉加载更多和下拉刷新功能
html
<scroll-view
scroll-y
class="scroll-y"
lower-threshold="100"
bindscrolltolower="getMore"
enable-back-to-top
refresher-enabled
refresher-default-style="black"
refresher-background="#f7f7f8"
bindrefresherrefresh="refreshHandler"
refresher-triggered="{{isTriggered}}"
>
<view wx:for="{{ numList }}" wx:key="*this">{{ item }}</view>
</scroll-view>
css
.scroll-y {
height: 100vh;
background-color: #efefef;
}
view {
height: 400rpx;
display: flex;
align-items: center;
justify-content: center;
}
view:nth-child(odd) {
background-color: skyblue;
}
view:nth-child(even) {
background-color: lightsalmon;
}
javascript
// pages/profile/proflie.js
Page({
data: {
numList: [1, 2, 3],
isTriggered: false
},
refreshHandler () {
wx.showToast({
title: '下拉刷新...'
})
this.setData({
numList: [1, 2, 3],
isTriggered: false
})
},
// scroll-view 上拉加载更多事件的事件处理函数
getMore () {
wx.showLoading({
title: '数据加载中...',
})
setTimeout(() => {
// 获取数组的最后一项
const lastNum = this.data.numList[this.data.numList.length - 1]
// 定义需要追加的元素
const newArr = [lastNum + 1, lastNum + 2, lastNum + 3]
this.setData({
numList: [...this.data.numList, ...newArr]
})
wx.hideLoading()
}, 1500)
}
})
二、自定义组件
1.创建和注册组件



2.组件的数据以及方法

html
<!--index-->
<custom-checkbox />
<view class="line"></view>
<custom-checkbox />
html
<!--components/custom-checkbox/custom-checkbox.wxml-->
<!-- <text>我是自定义属性</text> -->
<view class="custom-checkbox-container">
<view class="custom-checkbox-box">
<checkbox checked="{{ isChecked }}" bind:tap="updateChecked"/>
</view>
</view>
javascript
// components/custom-checkbox/custom-checkbox.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据:用来定义当前组件内部所需要使用的数据
*/
data: {
isChecked: false
},
/**
* 组件的方法列表:在组件中,所有的事件处理程序都需要写到 methods 方法中
*/
methods: {
// 更新复选框的状态
updateChecked () {
this.setData({
isChecked: !this.data.isChecked
})
}
}
})
3.组件的属性properties

html
<!--index-->
<custom-checkbox label="我已阅读并同意 用户协议 和 隐私协议" position="right" />
<view class="line"></view>
<custom-checkbox label="匿名提交" position="left" />
html
<!--components/custom-checkbox/custom-checkbox.wxml--><view class="custom-checkbox-container">
<view class="custom-checkbox-box {{ position === 'left' ? 'left' : 'right' }}">
<checkbox class="custom-checkbox" checked="{{ isChecked }}" bind:tap="updateChecked"/>
<view>
<text>{{ label }}</text>
</view>
</view>
</view>
css
.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;
}
javascript
/**
* 组件的属性列表:组件的对外属性,主要用来接收组件使用者传递给组件内部的属性以及数据
*/
properties: {
// 如果需要接收传递的属性,有两种方式:全写、简写
// label: String
label: {
// type 组件使用者传递的数据类型
// 数据类型:String、Number、Boolean、Object、Array
// 可以设置为 null,表示不限制类型
type: String,
value: ''
},
/**
* 组件的方法列表:在组件中,所有的事件处理程序都需要写到 methods 方法中
*/
methods: {
// 更新复选框的状态
updateChecked () {
this.setData({
isChecked: !this.data.isChecked,
label: '在组件内部也可以修改 properties 中的数据'
})
// 在JS中可以访问和获取 properties 中的数据
// 但是一般情况下,不建议修改,因为会造成数据流的混乱
// console.log(this.properties.label)
}
}
4.组件wxml的slot-插槽

html
<!--cate-->
<custom01>
<text slot="slot-top">我需要显示到顶部</text>
<!-- 默认情况下,自定义组件的子节点内容不会进行展示 -->
<!-- 如果想内容进行展示,需要在组件模板中定义 slot 节点 -->
我是子节点内容
<text slot="slot-bottom">我需要显示到底部</text>
</custom01>
html
<!--index-->
<!-- label 文本显示的内容 -->
<!-- position 控制文本显示的位置 -->
<custom-checkbox label="我已阅读并同意 用户协议 和 隐私协议" position="right">
我已阅读并同意 用户协议 和 隐私协议 - 111
</custom-checkbox>
<view class="line"></view>
<custom-checkbox label="匿名提交" position="left">
匿名提交 - 222
</custom-checkbox>
html
<!--components/custom-checkbox/custom-checkbox.wxml-->
<view class="custom-checkbox-container">
<view class="custom-checkbox-box {{ position === 'left' ? 'left' : 'right' }}">
<checkbox class="custom-checkbox" checked="{{ isChecked }}" bind:tap="updateChecked"/>
<view>
<!-- label 和 子节点内容都进行了展示 -->
<!-- 要么展示 label 要么展示 子节点内容 -->
<!-- 如果用户传递了 label 属性,就展示label -->
<!-- 如果用户没有传递 label 属性,就展示子节点内容 -->
<text wx:if="{{ label !== '' }}">{{ label }}</text>
<slot wx:else />
</view>
</view>
</view>
5.组件样式以及注意事项

html
<!--cate-->
<view class="custom parent">
<view>
<custom02 />
<view class="son test">我是父级页面中的结构</view>
</view>
</view>
<!-- <text>我是父级页面中的结构</text> -->
css
/* cate */
/* .custom {
color: lightseagreen;
font-size: 50rpx;
} */
/* .label {
color: lightseagreen;
} */
/* text {
color: lightseagreen;
} */
.parent .son.test {
color: lightsalmon;
}
html
<!--components/custom02/custom02.wxml-->
<text class="content son">
<text class="label">给自定义组件设置样式</text>
</text>
css
/* components/custom02/custom02.wxss */
/* 第一个注意事项:在自定义的 wxss 文件中,不允许使用标签选择器,ID 选择器,属性选择器 */
/* 请改为class选择器 */
.content {
color: lightgreen;
}
/* 第二个注意事项:子选择器,只能用于 view 和 子组件,用于其他组件可能会出现样式失效的问题 */
.content > .label {
color: lightgreen;
}
/* 第三个注意事项:继承样式,例如:color/font 都会从组件外继承 */
/* 第四个注意事项:全局样式、组件所在页面的样式文件中的样式都对自定义组件无效 */
/* 第五个注意事项:官方不推荐做法 */
/* 不建议在全局样式文件以及父级页面之间使用标签选择器设置样式 */
/* 如果是在全局样式文件中设置样式,会影响项目中全部的相同组件 */
/* 如果是在页面样式文件中设置样式,会影响当前页面所有的相同组件 */
/* 第六个注意事项: */
/* 组件和组件使用者,如果使用了后代选择器,可能出现一些非预期情况 */
/* 如果出现,请避免 */
6.组件样式隔离

css
/* components/custom03/custom03.wxss */
.test {
color: lightseagreen;
font-size: 50rpx;
}
// cate
.label {
color: lightsalmon;
}
html
<!--cate-->
<custom03 />
<view class="test">我是组件使用者中的结构</view>
<!--components/custom02/custom02.wxml-->
<text class="content son">
<text class="label test">给自定义组件设置样式</text>
</text>
javascript
// components/custom03/custom03.js
Component({
options: {
// styleIsolation:配置组件样式隔离
// isolated:开启样式隔离,默认值
// 在默认情况下,自定义组件和组件使用者如果存在相同的类名,类名不会互相影响
// apply-shared:表示组件使用者、页面的 wxss 样式能够影响到自定义组件
// 但是自定义组件的样式不会影响组件使用者、页面的 wxss 样式
// shared:表示组件使用者、页面的 wxss 样式能够影响到自定义组件
// 自定义组件的样式会影响组件使用者、页面的 wxss 样式
// 和其他使用了 apply-shared 以及 share 属性的自定义组件
styleIsolation: "shared"
}
})
7.组件样式隔离(修改checkbox样式)
css
/* components/custom-checkbox/custom-checkbox.wxss */
/* 复选框组件是公共组件 */
/* 以后需要再多个页面或者需要在多个项目中进行使用 */
/* 所以,需要先给复选框组件准备,设置一些默认样式 */
/* 如果在其他页面或者其他项目中使用的时候,发现样式不符合产品需求 */
/* 可以进行修改、对默认的样式进行修改 */
/* 1.需要给复选框设置默认样式 */
/* 需要先找到小程序给复选框提供的类名,通过小程序给提供的类名修改才可以 */
/* 需要先打开小程序开发文档,找到复选框文档,审查元素,进行查找 */
/* 在自定义组件中,不能直接修改复选框样式 */
/* 如果需要进行修改,需要设置 styleIsolation 才可以 */
/* shared:修改其他页面的样式、组件使用者的样式、以及其他使用了 share 以及 apply-share 的组件 */
/* 这时候,不是想要的结果 */
/* 需求是:只想影响当前组件,可以添加命名空间 */
/* 复选框没有选中时默认的样式 */
.custom-checkbox .wx-checkboxe-input {
width: 24rpx !important;
height: 24rpx !important;
border-radius: 50% !important;
border: 1px solid #fda007 !important;
margin-top: -6rpx;
}
/* 复选框选中时默认的样式 */
.custom-checkbox .wx-checkedbox-input-checked {
background-color: #fda007 !important;
}
/* 复选框选中时 ✔ 样式 */
.custom-checkbox .wx-checkboxe-input.wx-checkedbox-input-checked:before {
font-size: 22rpx;
color: #fff;
}
/* 2.组件使用者也能够修改默认的样式 */
html
<!--index-->
<view class="custom">
<custom-checkbox label="匿名提交" position="left">
匿名提交 - 222
</custom-checkbox>
</view>
css
/**index.wxss**/
/* 组件使用者修改复选框的样式 */
.custom .custom-checkbox .wx-checkboxe-input {
border: 1px solid lightseagreen !important;
}
.custom .custom-checkbox .wx-checkedbox-input-checked {
background-color: lightseagreen !important;
}
8.数据监听器observers

html
<!--components/custom04/custom04.wxml-->
<view>{{ num }}</view>
<view>{{ count }}</view>
<view>{{ obj.name }}</view>
<view>{{ arr[1] }}</view>
<view>{{ label }}</view>
<button type="warn" plain bind:tap="updateData">更新数据</button>
<!--cate-->
<custom04 label="标题" />
javascript
// components/custom04/custom04.js
Component({
/**
* 组件的属性列表
*/
properties: {
label: {
type: String,
value: '测试'
}
},
/**
* 组件的初始数据
*/
data: {
num: 10,
count: 100,
obj: { name: 'Tom', age: 10 },
arr: [1, 2, 3]
},
// 用来监听数据已经属性是否发生了变化
observers: {
// key:需要监听的数据
// value:就是一个回调换上,形参:最新的数据
num:function (newNum) {
// 对 data 中的数据进行监听,如果数据没有发生改变,监听器不会执行
console.log(newNum)
},
// count:function (newCount) {
// console.log(newCount)
// }
// // 同时监听多个数据
// 'num, count': function (newNum, newCount) {
// console.log(newNum, newCount);
// }
// // 支持监听属性以及内部数据的变化
// 'obj.name': function (newName) {
// console.log(newName)
// },
// 'arr[1]': function (newItem) {
// console.log(newItem)
// }
// 使用通配符
// 'obj.**': function (newObj) {
// console.log(newObj)
// }
label: function (newLabel) {
// 只要组件使用者传递了数据,这个时候在监听器中就能获得传递的数据
// 也就是说,监听器立即就执行了
console.log(newLabel)
}
},
/**
* 组件的方法列表
*/
methods: {
// 更新数据
updateData () {
this.setData({
num: this.data.num + 1,
// count: this.data.count - 1
// 'obj.name': 'jerry',
// 'arr[1]': 666
label: '最新的标题'
})
}
}
})
9.组件通信
(1)父往子传值

javascript
// components/custom-checkbox/custom-checkbox.js
properties: {
// 复选框组件是公共组件
// 需要在多个页面或多个项目中进行使用
// 在使用的时候,有的地方是希望默认是被选中的效果,有的地方希望默认是没有被选中的效果
// 怎么处理呢?
// 首先让复选框默认还是没有被选中的效果
// 如果希望复选框默认被选中,这个时候传递属性(checked=true)到复选框组件
checked: {
type: Boolean,
value: false
}
},
observers: {
// 如果需要将 properties 中的数据赋值给 data
// 可以使用 observers 进行处理
checked: function (newChecked) {
// console.log(newChecked)
this.setData({
isChecked: newChecked
})
}
},
(2)子往父传值

html
<!--cart-->
<view>{{ num }}</view>
<!-- 需要在自定义组件标签上通过 bind 方法绑定自定义事件,同时绑定事件处理函数 -->
<custom05 bind:myevent="getData" />
<!--components/custom05/custom05.wxml-->
<button type="primary" plain bind:tap="sendData">传递数据</button>
javascript
// cart
Page({
data: {
num: ''
},
getData (event) {
// 可以通过事件对象 .detail 获取子组件传递给父组件的数据
// console.log(event)
this.setData({
num: event.detail
})
}
})
// components/custom05/custom05.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
num: 100
},
/**
* 组件的方法列表
*/
methods: {
// 将数据传递给父组件
sendData () {
// 如果需要将数据传递给父组件
// 需要使用 triggerEvent 发射自定义事件
// 第二个参数,是携带的参数
this.triggerEvent('myevent',this.data.num)
}
}
})
(3)获取组件实例

html
<!--index-->
<custom-checkbox
label="我已阅读并同意 用户协议 和 隐私协议"
position="right"
checked="{{ isChecked }}"
class="child"
id="child"
bind:changechecked="getData"
>
我已阅读并同意 用户协议 和 隐私协议 - 111
</custom-checkbox>
<view class="line"></view>
<view class="custom">
<custom-checkbox label="匿名提交" position="left">
匿名提交 - 222
</custom-checkbox>
</view>
<button type="primary" plain bind:tap="getChild">获取子组件实例对象</button>
javascript
// index
Page({
data: {
isChecked: true
},
getData (event) {
console.log(event.detail)
if (event.detail) {
console.log('提交')
} else {
console.log('请同意协议')
}
},
// 获取子组件的实例对象
getChild () {
// this.selectComponent 方法获取子组件实例对象
// 获取实例对象以后,就能获取子组件所有的数据,也能调用组件的方法
const res = this.selectComponent('.child')
console.log(res.data.isChecked)
}
})
10.组件生命周期

html
<!--components/custom06/custom06.wxml-->
<!-- <text>components/custom06/custom06.wxml</text> -->
<view>{{ name }}</view>
<!--profile-->
<custom06 wx:if="{{ num === 1 }}" />
<button type="warn" bind:tap="handler">销毁自定义组件</button>
javascript
// components/custom06/custom06.js
Component({
data: {
name: 'tom'
},
// 组件生命周期声明对象
lifetimes: {
// created:组件实例被创建好以后执行
created () {
console.log('组件 created')
// 所以在 created 钩子函数中不能调用 setData
// 可以给组件添加一些自定义的属性,可以通过 this 的方式进行添加
this.test = '测试'
// this.setData({
// name: 'jerry'
// })
},
// attached:组件被初始化完毕,模板解析完成,已经把组件挂载到页面上
attached () {
console.log('组件 attached')
console.log(this.test)
// 一般页面中的交互会在 attached 钩子函数中进行实现
this.setData({
name: 'jerry'
})
},
// detached:组件被销毁时触发执行
detached () {
console.log('组件 detached')
}
}
})
// profile.js
Page({
data: {
num: 1
},
handler () {
this.setData({
num: this.data.num + 1
})
}
})
11.组件所在页面的生命周期

javascript
// components/custom06/custom06.js
Component({
data: {
name: 'tom'
},
// 组件所在页面的生命周期
pageLifetimes: {
// 监听组件所在页面的展示(后台切前台)状态
show () {
console.log('组件所在页面被展示')
},
// 监听组件所在页面的隐藏(前台切后台、点击 tabBar)状态
hide () {
console.log('组件所在页面被隐藏')
}
}
})
12.小程序生命周期总结




13.拓展
(1)使用Component构造页面

html
<!--pages/detail/detail.wxml-->
<view>{{ name }}</view>
<button type="warn" plain bind:tap="updateName">更新 name</button>
<!--pages/profile/profile.wxml-->
<navigator url="/pages/detail/detail?id=10&title=测试">跳转到详情页面</navigator>
javascript
//detail.js
Component({
// 为什么需要使用 Component 方法构造页面
// Component 方法功能比 Page 方法强大很多
// 如果使用 Component 方法构造页面,可以实现更加复杂的页面逻辑开发
// 小程序页面也可以使用 Component 方法进行构造
// 注意事项:
// 1. 要求 .js 文件中必须包含 usingComponents 字段
// 2. 里面的配置项需要和 Component 中 配置项保持一致
// 3. 页面中 Page 方法有一些钩子函数、事件监听方法,这些钩子函数、事件监听方法必须放到 method 对象中
// 4. 组件的属性 properties 也可以接收页面的参数,在 onload 钩子函数中可以通过 this.data 进行获取
properties: {
id: String,
title: String
},
data: {
name: 'tom'
},
onLoad () {
console.log('页面加载 - 1')
},
methods: {
onLoad (options) {
// console.log('页面加载 - 2')
// console.log(options)
console.log(this.data.id)
console.log(this.data.title)
},
// 更新 name
updateName () {
this.setData({
name: 'jerry'
})
}
}
})
(2)组件复用机制 behaviors

html
<!--components/custom08/custom08.wxml-->
<!-- <text>components/custom08/custom08.wxml</text> -->
<view>{{ label }}</view>
<view>{{ name }}</view>
<view>{{ obj.name }} - {{ obj.age }}</view>
<button type="primary" plain bind:tap="updateName">更新数据</button>
javascript
// components/custom08/behavior.js
const behavior = Behavior({
/**
* 组件的属性列表
*/
properties: {
label: {
type:String,
value: '我已同意该协议'
}
},
/**
* 组件的初始数据
*/
data: {
name: 'tom',
obj: {
name: 'jerry'
}
},
/**
* 组件的方法列表
*/
methods: {
updateName () {
this.setData({
name: 'jerry'
})
console.log('我是 behavior 内部的方法!!!')
}
},
lifetimes: {
attached () {
console.log('我是 behavior 的生命周期函数~~~~~~~~~~~~~~~~~')
}
}
})
export default behavior
// components/custom08/custom08.js
import behavior from './behavior'
Component({
behaviors: [behavior],
// 在以后开发中,使用 behaviors 进行代码复用的时候
// 组件 和 behaviors 可能存在相同的字段
// 如果存在相同的 properties,就近原则,使用组件内部的数据
properties: {
label: {
type: String,
value: '匿名提交'
}
},
// 如果存在相同的 data
// 如果是对象类型,属性会进行合并
// 如果不是对象类型的数据,展示的以组件内部为准
data: {
name: '组件中的 name',
obj: {
name: '组件中的 obj name',
age: 100
}
},
// 如果存在相同的方法,就近原则,使用组件内部的数据
methods: {
updateName () {
console.log('我是组件内部的方法!!!')
}
},
// 如果存在相同的生命周期函数,生命周期函数都会被触发
lifetimes: {
attached () {
console.log('我是组件内部调用的生命周期函数!!!!')
}
}
})
(3)外部样式类

html
<!--profile.wxml-->
<!-- 属性是在 externalClasses 里面定义的元素 -->
<!-- 属性值必须是一个类名 -->
<custom09 extend-class="my-class" />
<!--components/custom09/custom09.wxml-->
<!-- <text>components/custom09/custom09.wxml</text> -->
<!-- 在同一个节点上,如果存在外部样式类 和 普通样式类 -->
<!-- 两个类的优先级是未定义的 -->
<!-- 建议:在使用外部样式类时,样式需要通过 !important 添加权重 -->
<view class="extend-class box">通过外部样式类修改组件的样式</view>
css
/* components/custom09/custom09.wxss */
.box {
color: lightseagreen;
}
/* profile.wxss */
.my-class {
color: lightsalmon !important;
}
javascript
// components/custom09/custom09.js
Component({
// 组件接受的外部样式类
externalClasses: ['extend-class']
})
14.完善复选框案例以及总结自定义组件
如果 styleIsolation: 'shared',则 externalClasses 选项会失效
