在自定义组件的wxml结构中,可以提供一个
节点(插槽),用于承载组件使用者提供的wxml结构
在小程序中,默认每个自定义组件中允许使用一个进行占位,这种个数上的限制叫做单个插槽
组件的封装者
这里是组件的内部节点
组件的使用者
这里是插入到组件slot中的内容
在小程序的自定义组件中,需要使用多插槽时,可以在组件的.js文件中,通过如下方式进行启用
示例代码如下:
Component({
options:{
multipleSlots:true // 在组件定义时的选项启用多slot支持
},
properties:{/* ... */},
methods:{/* ... */}
})
可以在组件的.wxml中使用多个标签,以不同的name来区分不同的插槽,示例代码如下:
组件模板
这是一段固定的文本内容
在使用带有多个插槽的自定义组件时,需要用slot属性来将节点插入到不同的中,示例代码如下:
引用组件的页面模板
这里是插入到组件slot name="before"中的内容
这里是插入到组件slot name="after"中的内容
属性绑定:用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据
事件绑定:用于子组件向父组件传递数据,可以传递任意数据
获取组件实例:父组件还可以通过this.selectComponent()获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法
属性绑定用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件,父组件的示例代码如下:
// 父组件的data节点
data:{count:0}
// 父组件的wxml结构
-----
父组件中:count值为:{{count}}
子组件在properties节点中声明对应的属性并使用,示例代码如下:
// 子组件的properties节点
properties:{
count:Number
}
// 子组件的wxml结构
子组件中,count值为:{{count}}
事件绑定用于实现子向父传值,可以传递任何类型的数据,使用步骤如下:
1 在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件
// 在父组件定义的syncCount方法
// 将来,这个方法会被传递给子组件,供子组件进行调用
syncCount(){console.log('syncCount')},
2 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
3 在子组件的js中,通过调用this.triggerEvent('自定义事件名称',{/*参数对象*/}),将数据发送到父组件
// 子组件的wxml结构
子组件中,count值为:{{count}}
// 子组件的js代码
methods:{
addCount(){
this.setData({count:this.properties.count+1})
this.triggerEvent('sync',{value:this,properties.count})
}
}
4 在父组件的js中,通过e.detail获取到子组件传递过来的数据
syncCount(e){
this.setData({count:e.detail.value})
}
可在父组件里调用this,selectComponent("id或class选择器"),获取子组件的实例对象,从而直接访问子组
件的任意数据和方法,调用时需要传入一个选择器,例如this.selectComponent(".my-component")
getChild(){ // 按钮的tap事件处理函数
// 切记下面参数不能传递标签选择器"my-test",不然返回的是null
const child = this.selectComponent('.customA') // 也可以传递id选择器#cA
child.setData({count:child.properties.count+1}) // 调用子组件的setData方法
child.addCount() // 调用子组件的addCount方法
}
behaviors是小程序中,用于实现组件间代码共享的特性,类似于Vue.js中的"mixins"
每个behavior可以包含一组属性、数据、生命周期函数和方法,组件引用它时,它的属性、数据和方法会被合并到组件中每个组件可以引用多个behavior,behavior也可以引用其他behavior
调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,供所有的组件使用:
// 调用Behavior()方法,创建实例对象
// 并使用module.exports将behavior实例对象共享出去
module.exports=Behavior({
// 属性节点
properties:{},
// 私有数据节点
data:{username:'zs'},
// 事件处理函数和自定义方法节点
methods:{},
// 其他节点...
})
在组件中,使用require()方法导入需要的behavior,挂载后即可访问behavior中的数据或方法,示例代码如下:
// 1 使用require()导入需要的自定义behavior模块
const myBehavior=require("../../behaviors/my-behavior")
Component({
// 2 将导入的behavior实例对象,挂载到behaviors数组节点中,即可生效
behaviors:[myBehavior],
// 组件的其他节点...
})
可用的节点 类型 是否必填 描述
properties Object Map 否 同组件的属性
data Object 否 同组件的数据
methods Object 否 同自定义组件的方法
behaviors String Array 否 引入其他的behavior
created Function 否 生命周期函数
attached Function 否 生命周期函数
ready Function 否 生命周期函数
moved Function 否 生命周期函数
detached Function 否 生命周期函数
组件和它引用的behavior中可以包含同名的字段,此时可以参考如下3种同名的处理规则
1 同名的数据字段(data)
2 同名的属性(properties)或方法(methods)
3 同名的生命周期函数
关于详细的覆盖和组合规则,大家可以参考微信小程序官方文档给出的说明
小程序对npm的支持与限制:
目前,小程序已经支持使用npm安装第三方包,从而提高小程序的开发效率,但是,在小程序中使用
npm包有如下3个限制:
1 不支持依赖于Node.js内置库的包
2 不支持依赖于浏览器内置对象的包
3 不支持依赖于C++插件的包
Vant Weapp是有赞前端团队开发的一套小程序UI组件库,助力开发者快速搭建小程序应用,它所使用的是
MIT开源许可协议,对商业使用比较友好
官方文档地址:https://youzan.github.io/vant-weapp
在小程序项目中,安装Vant组件库主要分为如下3步:
1 通过npm安装npm i @vant/weapp -S --production
2 构建npm包
3 修改app.json
安装完Vant组件库之后,可以在app.json的usingComponents节点中引入需要的组件,即可在wxml中
直接使用组件,示例代码如下:
"usingComponents": {
"van-button":"@vant/weapp/button/index"
}
按钮
在app.wxss中,写入css变量,即可对全局生效:
page{
/* 定制警告按钮的背景颜色和边框颜色 */
--button-danger-background-color:#C00000;
--button-danger-border-color:#D60000;
}
默认情况下,小程序官方提供的异步API都是基于回调函数实现的,例如,网络请求的API需要按照如下的方式调用:
wx.request({
method:'',
url:'',
data:{},
success:()=>{}, // 请求成功的回调函数
fail:()=>{}, // 请求失败的回调函数
complete:()=>{} // 请求完成的回调函数
})
API Promise化,指的是通过额外的配置,将官方提供的。基于回调函数的异步API,升级改造为基于
Promise的异步API,从而提高代码的可读性、维护性,避免回调地狱的问题
在小程序中,实现API Promise化主要依赖于miniprogram-api-promise这个第三方的npm包,它的安装
和使用步骤如下:
npm install --save [email protected]
// 在小程序入口文件中(app.js),只需调用一次promisifyAll()方法
// 即刻实现异步API的Promise化
import {promisifyAll} from 'miniprogram-api-promise'
const wxp=wx.p={}
promisifyAll(wx,wxp)
async getInfo(){
const {data:res}=await wx.p.request({
method:"GET",
url:"https://www.escook.cn/api/get",
data:{name:'zs',age:100}
})
console.log(res)
},
vant按钮
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题
开发中常用的全局数据共享方案有:Vuex、Redux、MobX等
在小程序中,可使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享,其中:
mobx-miniprogram用来创建Store实例对象
mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用
在项目中运行如下的命令,安装MobX相关的包:
npm install --save [email protected] [email protected]
注意:MobX相关的包安装完毕之后,记得删除miniprogram_npm目录后,重新构建npm
import {observable,action} from 'mobx-miniprogram'
export const store = observable({
// 数据字段
numA:1,
numB:2,
// 计算属性
get sum(){return this.numA+this.numB},
// actions方法,用来修改store中的数据
updateNum1:action(function(step){
this.numA+=step
}),
updateNum2:action(function(step){
this.numB+=step
}),
})
// 页面的.js文件
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Page({
onLoad:function(){ // 生命周期函数--监听页面加载
this.storeBindings=createStoreBindings(this,{
store,
fields:['numA','numB','sum'],
actions:['updateNum1']
})
},
onUnload:function(){ // 生命周期函数--监听页面卸载
this.storeBindings.destoyStoreBindings()
}
})
// 页面的.wxml结构
{{numA}}+{{numB}}={{sum}}
numA+1
numA-1
// 按钮tap事件的处理函数
btnHandler1(e){this.updateNum1(e.target.dataset.step)}
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Component({
behaviors:[storeBindingsBehavior], // 通过storeBindingsBehavior来实现自动绑定
storeBindings:{
store, // 指定要绑定的Store
fields:{ // 指定要绑定的字段数据
numA:()=>store.numA, // 绑定字段的第1种方式
numB:(store)=>store.numB, // 绑定字段的第2种方式
sum:'sum' // 绑定字段的第3种方式
},
actions:{ // 指定要绑定的方法
updateNum2:'updateNum2'
}
}
})
// 组件的.wxml结构
{{numA}}+{{numB}}={{sum}}
numB+1
numB-1
// 组件的方法列表
methods:{
btnHandler2(e){this.updateNum2(e.target.dataset.step)}
}