注册小程序开发账号:使用浏览器打开: https://mp.weixin.qq.com 网址,点击右上角的"立即注册",即可进入小程序开发账号的注册流程,完成相关流程。
获取小程序的AppID:扫码登入网址后->点击开发->开发设置->AppID
下载开发者工具:https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html
安装成功后,扫码登录
App.json 文件
app.json是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底部tab等。普通快速启动项⽬⾥边的app.json配置
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black"
},
"style":"v2",
"sitemapLocation":"sitemap.json"
}
字段的含义:
sitemap.json文件
sitemap的索引提示是默认开启的,如需要关闭sitemap的索引提示,可在小程序项目配置文件project.config.json的setting中配置字段checkSiteMap为false
页面的.json文件
页面中的配置会覆盖app.json的window中相同的配置项
宿主环境:指的是程序运行所必须的依赖环境,脱离了宿主环境的软件是没有任何意义的
手机微信就是小程序的宿主环境,小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能
通信模型
小程序通信的主体是逻辑层和渲染层,其中:WXML模板和WXSS样式工作在渲染层,JS脚本工作在逻辑层
小程序的通信模型:逻辑层和渲染层之间的通信(由微信客户端进行转发);逻辑层和第三方服务器之间的通信(由微信客户端进行转发)
运行机制
小程序启动过程:下载代码包到本地–>解析app.json全局配置文件–>执行app.js小程序入口文件,调用App()创建小程序实例–>渲染小程序首页–>小程序启动完成
页面渲染过程:加载解析页面的.json配置文件–>加载页面的.wxml模板和.wxss样式–>执行页面的.js文件,调用Page()创建页面实例–>页面渲染完成
组件
容器类组件:view(普通视图区域,类似于div,是块级元素,用来实现页面的布局效果);scroll-view:(可滚动的视图区域,常用来实现滚动列表效果);swiper和swiper-item(轮播图组件和轮播图item组件)
如下是swiper的属性:
基础类组件:text(文本文件,类似于span,是行内元素,text的selectable属性,实现长按选中文本内容);rich-text(富文本文件,通过组件的nodes属性结点,把HTML字符串渲染为对应的UI结构)
nodes属性设置:
button(按钮组件,通过open-type属性可以调用微信提供的各种功能)
img(图片组件,默认width=300px,height=240px,支持懒加载)
navigator(页面导航组件,类似于a标签)
API
数据绑定的基本原则
在data中定义页面的数据:在页面对应的js文件中,把数据定义到data对象中即可
Page({
data: {
info:'hello world'
},
})
Mustache语法的格式:把data中的数据绑定到页面中渲染,使用Mustache语法(双大括号)将变量包起来即可
Mustache语法的应用场景:绑定内容、绑定属性、运算
动态绑定内容:
动态绑定属性:
Page({
data: {
imgSrc:'http://www.itheima.com/images/logo.png'
},
})
<image src="{{imgSrc}}"></image>
三元运算:
算数运算:randomNum:Math.random().toFixed(2)
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap或bind:tap | 手指触摸后马上离开,类似于HTML中的click时间 |
input | bindinput或bind:input | 文本框的输入事件 |
change | bindchange或bind:change | 状态改变时触发 |
事件对象的属性列表
其中,target是触发该事件的源头组件,而currentTarget则是当前事件所绑定的组件
bindtap的语法格式
<input bindinput="handleInput" /> <!-- wxml -->
Page({ // js
// 绑定的事件
handleInput: function(e) {
console.log(e);
console.log("值被改变了");
}
})
在事件处理函数中为data中的数据赋值
通过调用this.setData(dataObject)
方法,可以给页面data中的数据重新赋值,实例如下
Page({
data: {
count:0
},
// 修改count的值
changeCount(){
this.setData({
count:this.data.count+1
})
},
})
事件传参
不能在绑定事件的同时为事件处理函数传递参数,可以通过为组件提供data-*
自定义属性传参,其中的*
代表的是参数的名字,在事件处理函数中,可以通过even.target.dataset.参数名即可获取到具体参数的值,实例代码如下:
<!-- wxml -->
<button type="primary" data-currentCount="{{2}}" bindtap="btnTap2">+2</button>
<!-- js -->
btnTap2(e){
this.setData({
count:this.data.count+e.target.dataset.current
})
}
注意:data-后面的参数不能写驼峰
bindinput的语法格式
inputHandler(e){
console.log(e.detail.value);
},
<input type="text" bindinput="inputHandler"/>
实现文本框和data之间的数据同步:定义数据,渲染结构,美化样式,绑定input事件处理函数
<!-- js -->
Page({
data:{
msg:'你好'
},
inputHandler(e){
// console.log(e.detail.value);
this.setData({
msg:e.detail.value
})
}
})
<!-- wxml -->
<input type="text" bindinput="inputHandler" value="{{msg}}" />
<!-- wxss -->
input{
border: 1px solid #eee;
margin: 5px;
padding: 5px;
border-radius: 3px;
}
wx:if
在框架中,使⽤wx:if="{{condition}}"来判断是否需要渲染该代码块
男
女
保密
结合
使用wx:if
:实现一次性控制多个组件的展示和隐藏,并在block标签上使用wx:if来控制属性,另外,block并不是一个组件,只是一个包裹性质的容器,不会在页面中做任何渲染
view1
view2
hidden:直接使用hidden="{{condition}}"也可以实现元素的显示与隐藏
条件为true,隐藏元素,否则隐藏
wx:for 可以根据指定的数组,循环渲染重复的组件结构
wx:for-item可以指定数组当前元素的变量名,wx:for-index可以指定数组当前下标的变量名
<view wx:for="{{arr}}" wx:key="*this">
索引是:{{index}},item项是:{{item}}
</view>
<view wx:for="{{arr}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this">
索引是:{{idx}},item项是:{{itemName}}
</view>
<!-- 默认情况下,当前循环项的索引用index表示,当前循环用item表示 -->
wx:key ⽤来提⾼数组渲染的性能
<view wx:for="{{userList}}" wx:key="id">{{item.name}}</view>
data:{
userList:[
{id:1,name:'小红'},
{id:2,name:'小白'},
{id:3,name:'小化'},
]
}
// wx:key的值还可取:保留字*this,它的意思是item本⾝,*this代表的必须是唯⼀的字符串和数组
与CSS相比,WXSS扩展的特性:rpx尺寸单位,@import样式导入
rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx
建议:开发微信小程序时设计师可以⽤iPhone6作为视觉稿的标准。
使用步骤:
语法格式:@import后跟需要导入的外联样式表的相对路径,用==;==表示语句结束,如
@import '/common/common.wxss';
全局样式:定义在app.wxss中的样式为全局样式,作用于每一个页面
在页面的.wxss文件中定义的样式为局部样式,只作用于当前页面
当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式
当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局样式
tabBar是移动端应用常见的页面效果,用于实现页面的快速切换,小程序中通常将其分为:底部tabBar,顶部tabBar
注意:tabBar中只能配置最后2个,最多5个tab页签,当渲染顶部tabBar时,不显示icon,只显示文本
tabBar的6个组成部分
tabBar节点的配置项
每个tabBar项的配置选项
小程序中网络数据请求的限制
配置request的合法域名
登录到微信小程序的管理后台->开发->开发设置->服务器域名->修改request合法域名
发起GET请求
调用微信小程序提供的wx.request()方法,可以发起GET数据请求
getInfo(){
wx.request({
url: 'https://www.escook.cn/api/get',
method:'GET',
data:{
name:'zs',
age:20
},
success:(res)=>{
console.log(res.data);
}
})
},
发起POST请求
调用微信小程序提供的wx.request()方法,可以发起POST数据请求
postInfo(){
wx.request({
url: 'https://www.escook.cn/api/post',
method:"POST",
data:{
name:'ls',
age:33
},
success:(res)=>{
console.log(res.data);
}
})
},
在页面加载时请求数据
onLoad: function (options) {
this.getInfo()
this.postInfo()
}
跳过request合法域名校验(只能在开发与调试阶段使用)
小程序中实现页面导航的两种方式
导航组件;通过点击
组件实现页面跳转导航到 tabBar 页面:在使用
组件跳转到指定的 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中:
/
开头switchTab
导航到非tabBar页面:在使用
组件跳转到普通的非 tabBar 页面时,则需要指定 url 属性和 open-type 属性,其中:
/
开头navigate
后退导航:如果要后退到上一页面或多级页面,则需要指定 open-type 属性和 delta 属性,其中:
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator>
<navigator url="/pages/index/index" open-type="navigate">导航到index页面</navigator>
<navigator open-type="navigateBack" delta="1">后退一个页面</navigator>
导航到 tabBar 页面:调用 wx.switchTab(Object object) 方法。参数的属性如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的 tabBar 页面的路径,路径后不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
导航到非tabBar页面:调用 wx.navigateTo(Object object) 方法,参数的属性如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转到的非 tabBar 页面的路径,路径后可以带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
后退导航:调用 wx.navigateBack(Object object) 方法,可以返回上一页面或多级页面,参数的属性如下:
属性 | 类型 | 默认值 | 是否必选 | 说明 |
---|---|---|---|---|
delta | number | 1 | 否 | 返回的页面数,如果 delta 大于现有页面数,则返回到首页 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
<button bindtap="gotoMessage">跳转到message页面</button>
<button bindtap="gotoIndex">跳转到index页面</button>
<button bindtap="gotoBack">后退一个页面</button>
// 通过编程式导航跳转到tabBar页面
gotoMessage(){
wx.switchTab({
url: '/pages/message/message',
})
}
// 通过编程式导航跳转到非tabBar页面
gotoIndex(){
wx.navigateTo({
url: '/pages/index/index',
})
}
// 后退一个页面
gotoBack(){
wx.navigateBack()
},
声明式导航传参:在路径的后面还可以携带参数:参数与路径之间使用?
分隔;参数键与参数值用 =
相连;不同参数用&
分隔
<navigator url="/pages/index/index?name=zs&age=20">跳转到index页面</navigator>
编程式导航传参:调用 wx.navigateTo(Object object) 方法跳转页面时,也可以携带参数
<button bindtap="gotoIndex2">跳转到index页面</button>
gotoIndex2(){
wx.navigateTo({
url: '/pages/index/index?name=zs&age=20',
})
},
在onLoad中接收导航参数(声明式或编程式都一样接收,并且是在跳转页面对应的onLoad中接收)
onLoad: function (options) {
console.log(options);
},
启用下拉刷新有两种方式:
在全局或页面的 .json 配置文件中,通过 backgroundColor 和 backgroundTextStyle 来配置下拉刷新窗口的样式,其中:
监听页面的下拉刷新事件:在页面的 .js 文件中,通过 onPullDownRefresh() 函数即可监听当前页面的下拉刷新事件
<button bindtap="addCount">点击+1</button>
addCount(){
this.setData({
count:this.data.count+1
})
}
onPullDownRefresh: function () {
// console.log("触发了Message下拉刷新事件");
this.setData({
count:0
})
},
停止下拉刷新:调用 wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
// console.log("触发了Message下拉刷新事件");
this.setData({
count:0
})
// 当数据重置成功后,调用此函数,关闭下拉刷新的效果
wx.stopPullDownRefresh()
},
是指通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
监听页面的上拉触底事件:在页面的 .js 文件中,通过 onReachBottom() 函数即可监听当前页面的上拉触底事件
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
console.log("上拉触底事件触发了");
},
配置上拉触底距离(触发上拉触底事件时,滚动条距离页面底部的距离):可以在全局或页面的 .json 配置文件中,通过 onReachBottomDistance 属性来配置上拉触底的距离(默认50px)
生命周期(Life Cycle)是指一个对象从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段
生命周期的分类:
生命周期函数:是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行,允许程序员在特定的时间点,执行某些特定的操作
注意:生命周期强调的是时间段,生命周期函数强调的是时间点
生命周期函数的分类:
应用生命周期函数:小程序的应用生命周期函数需要在 app.js 中进行声明
App({
// 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
onLaunch: function () {},
// 当小程序启动,或从后台进入前台显示,会触发 onShow
onShow: function (options) {},
// 当小程序从前台进入后台,会触发 onHide
onHide: function () {},
// 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
onError: function (msg) {}
})
页面的生命周期函数:小程序的页面生命周期函数需要在页面的 .js 文件中进行声明
Page({
onLoad: function (options) {}, // 生命周期函数--监听页面加载,一个页面只调用一次
onReady: function () {}, // 生命周期函数--监听页面初次渲染完成,一个页面只调用一次
onShow: function () {}, // 生命周期函数--监听页面显示
onHide: function () {}, // 生命周期函数--监听页面隐藏
onUnload: function () {}, // 生命周期函数--监听页面卸载,一个页面只调用一次
})
WXS(WeiXin Script)是小程序独有的一套脚本语言,结合 WXML,可以构建出页面的结构
内嵌WXS脚本
wxml 文件中的每个
标签,必须提供 module 属性,用来指定当前 wxs 的模块名称,方便在 wxml 中访问模块中的成员
<view>{{m1.toUpper(username)}}</view>
<wxs module="m1">
module.exports.toUpper=function(str){
return str.toUpperCase()
}
</wxs>
定义外联的WXS脚本
wxs 代码还可以编写在以 .wxs 为后缀名的文件内,就像 javascript 代码可以编写在以 .js 为后缀名的文件中一样
function toLower(str){
return str.toLowerCase()
}
module.exports={
toLower:toLower
}
使用外联的WXS脚本
在 wxml 中引入外联的 wxs 脚本时,必须为
标签添加 module 和 src 属性,其中:module 用来指定模块的名称,src 用来指定要引入的脚本的路径,且必须是相对路径
<view>{{m2.toLower(country)}}</view>
<wxs src="../../utils/tools.wxs" module="m2"></wxs>
创建组件
局部引用组件:在页面的 .json 配置文件中引用组件的方式
// 在页面的.json文件中,引入组件
{
"usingComponents": {
"my-test1":"/components/test/test"
}
}
// 在页面的.wxml中引入组件
<my-test1></my-test1>
全局引用组件:在 app.json 全局配置文件中引用组件的方式
// 在app.json文件中,引入组件
{
"pages":[....],
"window":{....},
"usingComponents": {
"my-test2":"/components/test/test"
},
}
// 在页面的.wxml中引入组件
<my-test2></my-test2>
组件和页面的区别
组件样式隔离:默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的 UI 结构
组件样式隔离的注意点:
修改组件的样式隔离选项:可以通过 styleIsolation 修改组件的样式隔离选项
// 在组件的.js中新增如下配置
Component({
options:{
styleIsolation:'isolated'
}
})
// 或在组件的.json中新增如下配置
{
"styleIsolation":"isolated"
}
建议:在组件和引用组件的页面中建议使用 class 选择器,不要使用 id、属性、标签选择器
data数据:在小程序组件中,用于组件模板渲染的私有数据,需要定义到 data 节点中,data 更倾向于存储组件的私有数据
methods 方法:在小程序组件中,事件处理函数和自定义方法需要定义到 methods 节点中
properties属性:在小程序组件中,properties 是组件的对外属性,用来接收外界传递到组件中的数据,properties 更倾向于存储外界传递到组件中的数据
Component({
properties: { // 组件的属性列表
/* max:{ // 完整定义属性的方式
type:Number, // 属性值的数据类型
value:10 // 属性默认值
}, */
max:Number // 简化方式,不指定默认值
},
data: { // 组件的初始数据
count:0
},
methods: { // 组件的方法列表(包含事件处理函数和自定义方法)
addCount(){ // 事件处理函数
if(this.data.count>=this.properties.max) return
this.setData({
count:this.data.count+1,
// max:this.properties.max+1 // 使用setData修改properties值
})
this._showCount() // 通过this调用自定义方法
},
_showCount(){ // 自定义方法建议以 _ 开头
wx.showToast({
title: 'count的值为: '+this.data.count,
icon:'none'
})
}
}
})
<my-test1 max="10"></my-test1>
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于 vue 中的 watch 侦听器
数据监听器的基本用法:
<view>{{n1}}+{{n2}}={{sum}}</view>
<button bindtap="addN1">n1+1</button>
<button bindtap="addN2">n2+1</button>
Component({
data:{n1:0,n2:0,sum:0},
methods:{
addN1(){
this.setData({
n1:this.data.n1+1
})
},
addN2(){
this.setData({
n2:this.data.n2+1
})
}
},
observers:{
'n1,n2':function(newN1,newN2){
this.setData({
sum:newN1+newN2
})
}
}
})
监听对象属性的变化
数据监听器案例
<view style="background-color: rgb({{fullColor}});" class="color-box">颜色值:{{fullColor}}</view>
<button size="mini" type="default" bindtap="changeR">R</button>
<button size="mini" type="primary" bindtap="changeG">G</button>
<button size="mini" type="warn" bindtap="changeB">B</button>
Component({
options:{
pureDataPattern:/^_/ // 指定所有的_开头的为纯数据字段
},
data: {
rgb:{ // _rgb为纯数据字段
r:0,
g:0,
b:0
},
fullColor:'0,0,0'
},
methods: {
changeR(){
this.setData({
'_rgb.r':this.data.rgb.r+5>255?255:this.data.rgb.r+5
})
},
changeG(){
this.setData({
'rgb.g':this.data.rgb.g+5>255?255:this.data.rgb.g+5
})
},
changeB(){
this.setData({
'rgb.b':this.data.rgb.b+5>255?255:this.data.rgb.b+5
})
}
},
observers:{
'rgb.r,rgb.g,rgb.b':function(newR,newG,newB){ // 'rgb.**':function(obj){
this.setData({
fullColor:`${newR},${newG},${newB}` // :`${obj.r},${obj.g},${obj.b}`
})
}
}
})
监听对象中所有属性的变化:使用通配符**
来监听,如 'rgb.**':function(obj){}
纯数据字段指的是那些不用于界面渲染的 data 字段
使用规则:在 Component 构造器的 options 节点中,指定 pureDataPattern 为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段
在自定义组件的 wxml 结构中,可以提供一个
节点(插槽),用于承载组件使用者提供的 wxml 结构
启用多个插槽:在组件的 .js 文件定义
定义多个插槽:在组件的 .wxml 中使用多个
标签,以不同的 name 来区分不同的插槽
父子组件的通信方式
属性绑定
事件绑定步骤:
获取组件实例:可在父组件里调用 this.selectComponent(“id或class选择器”) ,获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器,如 this.selectComponent(".my-component")
是在小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”
behaviors 的工作方式:每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。每个组件可以引用多个 behavior,behavior 也可以引用其它 behavior
创建:调用 Behavior(Object object) 方法即可创建一个共享的 behavior 实例对象,供所有的组件使用
导入并使用:在组件中,使用 require() 方法导入需要的 behavior,挂载后即可访问 behavior 中的数据或方法
behavior可用节点
同名字段处理规则:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html
官方文档地址 https://youzan.github.io/vant-weapp
安装 :https://youzan.github.io/vant-weapp/#/quickstart#an-zhuang
使用:安装完 Vant 组件库之后,可以在 app.json 的 usingComponents 节点中引入需要的组件,即可在 wxml 中直接使用组件
定义全局主体样式:https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties
在 app.wxss 中,写入 CSS 变量,即可对全局生效,所有可用的颜色变量
默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的
实现:在小程序中,实现 API Promise 化主要依赖于 miniprogram-api-promise
这个第三方的 npm 包
注意,微信小程序每次安装第三方包之后必须需要构建npm,建议先将miniprogram_npm先删除再构建
调用
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题,如Vuex,Redux,MobX 等
在小程序中,可使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享。其中:
安装包:npm i --save [email protected] [email protected]
注意:MobX 相关的包安装完毕之后,记得删除 miniprogram_npm 目录后,重新构建 npm
创建 MobX 的 Store 实例 store.js
将 Store 中的成员绑定到页面中
在页面上使用 Store 中的成员
将 Store 中的成员绑定到组件中
在组件中使用 Store 中的成员
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载
分包后,小程序项目由 1 个主包 + 多个分包组成:
加载规则
体积限制
配置方法
打包规则
引用规则
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行
独立分包与普通分包的区别:
应用场景
当小程序从普通的分包页面启动时,需要首先下载主包
而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
注意:一个小程序中可以有多个独立分包
配置方法
引用规则
是指在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
配置:会在进入指定的页面时触发,在 app.json 中,使用 preloadRule 节点定义分包的预下载规则
限制:同一个分包中的页面享有共同的预下载大小限额 2M
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html
首先在app.json中设置如下:
在根目录新建store/store.js文件
// 在这个js文件中,专门创建Store的实例对象
import {observable,action} from 'mobx-miniprogram'
export const store=observable({
// 数据字段
numA:1,
numB:2,
activeTabBarIndex: 0,
// 计算属性
get sum(){
return this.numA+this.numB
},
// actions方法,用来修改store中的数据
updateActiveTabBarIndex:action(function(index){
this.activeTabBarIndex=index
})
})
在根目录新建custom-tab-bar文件夹,在里面新建index组件,名字固定
// custom-tab-bar/index.js
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../store/store'
Component({
options:{
styleIsolation:'shared'
},
behaviors:[storeBindingsBehavior],
storeBindings:{
// 数据源
store,
fields:{
sum:'sum',
active:'activeTabBarIndex'
},
actions:{
updateActive:'updateActiveTabBarIndex'
}
},
observers:{
'sum':function(val){
this.setData({
'list[1].info':val
})
}
},
data: { // 组件的初始数据
"list": [
{
"pagePath": "/pages/home/home",
"text": "首页",
"iconPath": "/images/tabs/home.png",
"selectedIconPath": "/images/tabs/home-active.png"
},
{
"pagePath": "/pages/message/message",
"text": "消息",
"iconPath": "/images/tabs/message.png",
"selectedIconPath": "/images/tabs/message-active.png",
"info":2
},
{
"pagePath": "/pages/contact/contact",
"text": "联系我们",
"selectedIconPath": "/images/tabs/contact-active.png",
"iconPath": "/images/tabs/contact.png"
}
],
},
methods: { // 组件的方法列表
onChange(event) {
// event.detail 的值为当前选中项的索引
// this.setData({ active: event.detail });
this.updateActive(event.detail)
wx.switchTab({
url: this.data.list[event.detail].pagePath,
})
},
}
})
<!--custom-tab-bar/index.wxml-->
<van-tabbar active="{{active}}" bind:change="onChange" active-color="#13A7A0">
<van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}">
<image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 25px; height: 25px;"/>
<image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 25px; height: 25px;"/>
{{item.text}}
</van-tabbar-item>
</van-tabbar>
/* custom-tab-bar/index.wxss */
.van-tabbar-item{
--tabbar-item-margin-bottom:0
}