UI组件库
vant
vant.github
vant使用直接进入vant官网地址,按说明使用
WeUI
WeUI.github
weui使用需进入weui的github仓库按照说明下载,选择文件夹使用微信开发者工具打开,按所需赋值,且没有详细说明
ECharts.github
ECharts的微信小程序版本,方便开发图表,满足各种可视化需求
标准开发模式
微信公众平台申请小程序开发账号
安装小程序开发者工具
创建和配置小程序项目
小程序项目结构
pages:存放所有小程序页面
utils:存放工具性质模块(如格式化时间的自定义模块)
app.js:小程序项目入口文件
app.json:小程序项目全局配置文件
app.wxss:小程序项目全局样式文件
project.config.json:项目配置文件
sitemap.json:配置小程序及其页面是否允许被微信索引
每个页面以单独文件夹存在并由四个基本文件组成
.js文件:页面脚本文件,存放页面数据、事件处理函数等
.json文件:当前页面配置文件,配置窗口的外观、表现等
.wxml文件:页面的模板结构文件
.wxss文件:当前页面的样式表文件
WXML和HTML区分
标签名不同
HTML(div,span,img,a)
WXML(view,text,image,navigator)
属性节点不同
<a href="#">超链接</a>
提供类似vue中的模板语法
数据绑定
列表渲染
条件渲染
WXSS和CSS区分
新增rpx尺寸单位
提供全局样式和局部样式
根目录app.wxss作用于所有小程序页面
局部页面的.wxss仅对当前页面生效
WXSS仅支持部分css选择器
.class和#id
element
并级选择器、后代选择器
::after和::before等伪类选择器
.js文件分类
app.js:整个小程序项目入口文件,通过调用App()函数启动整个小程序
页面.js文件:页面的入口文件,通过调用Page()函数创建并运行页面
普通.js文件:普通的功能模块文件,封装公共的函数或属性供页面使用
小程序启动过程
小程序代码包下载到本地
解析app.json全局配置文件
执行app.js小程序入口文件,调用App()创建小程序实例
渲染小程序首页
小程序启动完成
页面渲染过程
加载解析页面.json配置文件
加载页面.wxml模板和.wxss样式
执行页面.js文件,调用Page()创建页面实例
页面渲染完成
小程序组件分类
视图组件
基础内容
表单组件
导航组件
媒体组件
map地图组件
canvas画布组件
开放能力
无障碍访问
视图容器类组件
view:普通视图区域,类似div的块级元素,常用实现页面布局效果
scroll-view:可滚动视图区域,常用实现滚动列表效果
swiper和swiper-item:轮播图容器组件和轮播图item组件
swiper组件常用属性
indicator-dots="false"
:是否显示面板指示点
indicator-color="rgba(0, 0, 0, .3)"
:指示点颜色
indicator-active-color="#000000"
:当前选中的指示点颜色
autoplay="false"
:是否自动切换
interval="5000"
:自动切换时间间隔
circular="false"
:是否采用衔接滑动
基础内容组件
text:文本组件,类似span的行内元素
rich-text:富文本组件,支持吧html祖父穿渲染为wxml结构
text组件基本使用
selectable属性实现长按选中文本内容效果
rich-text组件基本使用
nodes属性节点把html祖父穿渲染为对应ui结构
其他常用组件
button:按钮组件,通过open-type属性调用微信提供各种功能
image:图片组件,默认宽度300px,高度约240px
navigator:页面导航组件,类似a链接
image组件mode属性用来指定图片裁剪和缩放
mode值 | 说明 |
---|---|
scaleToFill | 默认值,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
aspectFit | 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。(常用) |
aspectFill | 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。(少用) |
widthFix | 宽度不变,高度自动变化,保持原图宽高比不变(常用) |
heightFix | 高度不变,宽度自动变化,保持原图宽高比不变 |
小程序API类型
类型 | 特点 |
---|---|
事件监听API | 以on开头,监听某些事件触发 |
同步API | 以Sync结尾,其执行结果可以通过函数返回值直接获取,执行出错抛出异常 |
异步API | 类似jQuery中的$.ajax()函数,需要通过success、fail、complete接收调用结果 |
数据绑定
在data中定义数据,在wxml中使用插值表达式{{数据}}使用数据
{{数据}}使用场景:绑定内容、绑定属性、三元运算、算术运算
事件绑定
事件是渲染层到逻辑层的通讯方式
常用事件
绑定方式 | 事件描述 |
---|---|
bindtap或bind:tap | 手指触摸后马上离开,类似click事件 |
bindinput或bind:input | 文本框输入事件 |
bindchange或bind:change | 状态改变时触发 |
事件对象属性
属性 | 类型 | 说明 |
---|---|---|
type | String | 事件类型 |
timeStamp | Integer | 页面打开到触发事件所经过毫秒数 |
target | Object | 触发事件组件的一些属性值集合,触发事件的源头组件,主要为了区分冒泡(重点) |
currentTarget | Object | 当前组件的一些属性值集合,当前事件所绑定组件 |
detail | Object | 额外的信息(重点) |
touches | Array | 触摸事件,当前停留在屏幕中触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
事件处理函数中为data中数据赋值
调用this.setData(dataObject)
方法,给data中数据重新赋值
事件传参
小程序事件传参特殊,不能在绑定事件同时为事件处理函数传递数据
为组件提供data-*
自定义属性传参,*
代表参数名,如data-info="{{2}}"
info为参数名,2为参数值
事件处理函数中通过event.target.dataset.参数名
获取到具体参数值
通过bindinput为文本框绑定输入事件,在.js文件中定义事件处理函数,e.detail.value
是变化后文本框最新值
条件渲染
小程序中使用wx:if="{{true/false}}"
判断是否渲染代码块
wx:if="{{}}"
wx:elif="{{}}"
wx:else
一次性控制多个组件的显示和隐藏,使用<block></block>
标签包装多个组件并使用wx:if控制属性(block是一个包裹性质容器,不是组件,不会渲染在页面中)
hidden="{{true}}"
控制元素显示和隐藏,与wx:if区别在于
运行方式 | 使用建议 |
---|---|
wx:if动态创建和移除元素方式控制显隐 | 控制条件复杂时使用wx:if搭配wx:elifw、wx:else切换显隐 |
hidden切换样式方式控制元素显隐 | 频繁切换时使用 |
列表循环
通过wx:for="{{数组或者对象}}"
根据指定数组,循环渲染重复的组件结构,默认情况下当前循环项索引为index
,当前循环项为item
使用wx:for-index="循环项的索引"
指定当前循环项索引的变量名
使用wx:for-item="循环项的名称"
指定当前项的变量名
使用wx:key="唯一的值"
在小程序列表渲染时,用来提高渲染的性能
window节点常用配置
属性名 | 默认值 | 说明 |
---|---|---|
navigationBarTitleText | 字符串 | 导航栏标题文字 |
navigationBarBackgroundColor | #000000 | 导航栏背景颜色 |
navigationBarTextStyle | white | 导航栏标题颜色,仅支持black/white |
backgroundColor | #000000 | 窗口背景色 |
backgroundTextStyle | dark | 下拉loading样式,仅支持dark/light |
enablePullDownRefresh | false | 是否开启下拉刷新 |
onReachBottomDistance | 50 | 页面上拉触底事件触发时距页面底部距离,单位px |
tabBar节点常用配置
属性名 | 默认值 | 说明 |
---|---|---|
position | bottom | tabBar位置,仅支持bottom/top |
borderStyle | black | tabBar上边框颜色,仅支持black/white |
color | tab上文字的默认颜色 | |
selectedColor | tab上文字选中时颜色 | |
backgroundColor | tabBar上背景色 | |
list | tab页签的数组列表,2-5个(必填) |
每个tab项的配置项
属性名 | 必填 | 说明 |
---|---|---|
pagePath | 是 | 页面路径,页面必须在pages中预先定义 |
text | 是 | tab上显示文字 |
iconPath | 否 | 未选中时图标路径,postion为top时不显示icon |
selectediconPath | 否 | 选中时图标路径,postion为top时不显示icon |
页面配置常用的配置项
属性名 | 默认值 | 说明 |
---|---|---|
navigationBarBackgroundColor | #000000 | 当前页面导航栏背景颜色 |
navigationBarTextStyle | white | 当前页面导航栏标题颜色,仅支持black/white |
navigationBarTitleText | 字符串 | 当前页面导航栏标题文字 |
backgroundColor | #000000 | 当前页面窗口背景色 |
backgroundTextStyle | dark | 当前页面拉loading样式,仅支持dark/light |
enablePullDownRefresh | false | 是否开启当前页面下拉刷新 |
onReachBottomDistance | 50 | 页面上拉触底事件触发时距页面底部距离,单位px |
小程序网络数据请求
数据接口请求限制:只能请求HTTPS类型接口,必须将接口域名添加到信任列表中
调用wx.request()
方法发起网络数据请求,配置方法类似axios
暂时只有http协议接口可以在本地设置中开启不校验合法域名,仅在开发和调试阶段使用
页面导航
声明式导航
页面中声明一个<navigator>
导航组件,点击导航组件实现页面跳转
导航到tabBar页面
指定url属性和open-type属性,url表示跳转的页面地址,以/开头,open-type表示跳转方式,必须为switchTab
导航到非tabBar页面
指定url属性和open-type属性,url表示跳转的页面地址,以/开头,open-type表示跳转方式,必须为navigate,可省略
后退导航
指定open-type属性和delta属性,open-type表示进行后退导航,必须为navigateBack,delta表示后退层级,必须是数字,后退一步可省略
编程式导航
调用小程序导航API实现页面跳转
导航到tabBar页面
调用wx.switchTab(Object)方法,Object参数对象属性如下
属性名 | 必填 | 说明 |
---|---|---|
url | 是 | 需要跳转的tabBar页面路径,路径后不带参数 |
success | 否 | 接口调用成功的回调函数 |
fail | 否 | 接口调用失败的回调函数 |
complete | 否 | 接口调用结束的回调函数(成功失败都会执行) |
导航到非tabBar页面
调用wx.navigateTo(Object)方法,Object参数对象属性如下
属性名 | 必填 | 说明 |
---|---|---|
url | 是 | 需要跳转的非tabBar页面路径,路径后可以带参数 |
success | 否 | 接口调用成功的回调函数 |
fail | 否 | 接口调用失败的回调函数 |
complete | 否 | 接口调用结束的回调函数(成功失败都会执行) |
后退导航
调用wx.navigateBack(Object)方法,Object参数对象属性如下
属性名 | 必填 | 说明 |
---|---|---|
dalta | 是 | 返回的页面数,delta大于现有页面则返回首页 |
success | 否 | 接口调用成功的回调函数 |
fail | 否 | 接口调用失败的回调函数 |
complete | 否 | 接口调用结束的回调函数(成功失败都会执行) |
页面事件
监听用户下拉动作:onPullDownRefresh()
处理完下拉刷新后不会主动消失,需要调用wx.stopPullDownRefresh()
停止当前页面的下拉刷新
监听页面上拉触底事件:onReachBottom()
处理完下拉刷新后不会主动消失,需要调用wx.stopPullDownRefresh()
停止当前页面的下拉刷新
自定义组件
创建components文件夹,文件夹内新建test文件夹,右键新建component自动创建所需文件
组件引用分全局和局部
局部引用:
//在页面.json文件中引入
{
"usingComponents": {
"my-test": "/components/test1/test1"
}
}
//在wxml文件中使用
<my-test1></my-test1>
全局引用:
//在页app.json文件中引入
{
"pages": [],
"window": {},
"usingComponents": {
"my-test": "/components/test1/test1"
}
}
//在wxml文件中使用
<my-test1></my-test1>
自定义组件和页面区别
组件.json文件需要声明"component": true
组件.js文件中调用的是Componen()
函数
组件的事件处理函数需要定义到methods节点中
自定义组件样式隔离
app.wxss中全局样式对组件无效,但是只有class选择器无效
可以通过stylelsolation修改组件样式隔离
//在组件.js文件中新增如下配置
Component({
options: {
styleIsolation: 'isolated'
}
})
//在组件.json文件中新增如下配置
{
"stylelsolation": "isolated"
}
stylelsolation可选值
可选值 | 默认值 | 说明 |
---|---|---|
isolated | 是 | 表示启用样式隔离,自定义组件内外使用class指定样式不会相互影响 |
apply-shared | 否 | 表示页面wxss样式将影响到自定义组件,但自定义组件wxss中指定样式不会影响页面 |
shared | 否 | 表示页面wxss样式将影响到自定义组件,自定义组件wxss中指定样式也会影响页面和其他设置了apply-shared或shared的自定义组件 |
接收外接传递到组件中的数据
Component({
properties: {
max: { //完整定义属性的方式,需要指定属性默认值时建议使用
type: Number, //属性值的数据类型
value: 10 // 属性默认值
},
max: Nuber //简化定义属性的方式,不需指定属性默认值时建议使用简化方式
}
})
<my-test1 max="10"></my-test1>
data和properties区别
都是可读可写,data倾向于存储组件私有数据,properties倾向于存储外接传递到组件中的数据,二者都可以使用setdata修改
数据监听器
Component({
observers: {
'字段a, 字段b': function(字段a的新值, 字段b的新值) {
新值处理函数
}
}
})
Component({
//监听对象中单个或多个属性变化
observers: {
'对象.属性a, 对象.属性b': function(属性a的新值, 属性b的新值) {
为对象、属性a、属性b赋值都会触发
}
}
})
Component({
observers: {
//使用通配符监听对象上所有属性变化
'对象.**': function(obj) {
thsi.setData({
赋值对象: `${obj.r}, ${obj.r}, ${obj.r}`
})
}
}
})
纯数据字段
不用渲染也不会传递,仅在当前组件内部使用的data字段,纯数据字段有助于提升页面更新性能
使用规则:Component构造器的options节点中指定pureDataPattern为一个正则表达式,字段名符合正则表达式的字段为纯数据字段
Component({
options: {
//指定所有_开头的数据字段为纯数据字段
pureDataPattern: /^_/
}
})
组件生命周期
生命周期函数 | 参数 | 说明 |
---|---|---|
created | 无 | 在组件实例刚被创建时执行(重点) |
attached | 无 | 在组件实例进入页面节点树时执行(重点) |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行(重点) |
error | Object Error | 每当组件方法抛出错误时执行 |
组件主要的生命周期函数
created:组件实例刚被创建好的时候触发,此时不能调用setData,只应该用于给组件的 this 添加一些自定义的属性字段
attached:在组件完全初始化完毕、进入页面节点树后触发,此时this.data初始化完毕,绝大多数初始化的工作在此时进行(如发请求获取数据)
detached:在组件离开页面节点树后触发,退出一个页面时触发页面内每个自定义组件的 detached 生命周期函数,此时做一些清理工作
Lifetimes节点
在lifetimes 字段内进行声明,其优先级最高
Component({
lifetimes: {
attached() {}, //组件实例进入页面节点树时执行
detached() {} //组件实例被从页面节点树移除时执行
}
})
组件所在页面生命周期
自定义组件的行为依赖页面状态变化,通过生命周期监听页面变化
生命周期需要定义在pageLifetimes节点中
生命周期函数 | 参数 | 说明 |
---|---|---|
show | 无 | 组件所在页面被展示时执行 |
hide | 无 | 组件所在页面被隐藏时执行 |
resize | Object Size | 组件所在页面尺寸变化时执行 |
Component({
pageLifetimes: {
show: function() {}, //页面被展示
hide: function() {}, //页面被隐藏
resize: function(size) {} //页面尺寸变化
}
})
组件插槽
组件中预先定义<slot></slot>
节点,用于承载组件使用者提供的wxml结构,默认每个组件中只允许一个插槽
多个插槽启用需要在组件js文件中options添加multipleSlots: true
多个插槽使用需要在组件中<slot name="名字1"></slot>
,然后再组件使用者提供的wxml结构中<view slot="名字1"></view>
父子组件通信
属性绑定
父传子,仅能设置JSON 兼容的数据或普通数据
//父组件data节点
data: {
count: 0
}
//父组件wxml结构
<my-test count="{{count}}"></my-test>
//在子组件properties节点中声明对应属性即可在子组件中使用
properties: {
count: Number
}
事件绑定
子传父,可以传递任意数据
1.在父组件js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件
syncCount() {}
2.在父组件wxml 中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
<my-test count="count" bind:sync="syncCount"></my-test>
3.在子组件js 中,通过调用this.triggerEvent('自定义事件名称', {参数对象})
,将数据发送到父组件
this.triggerEvent('sync', {value: 最新值})
4.在父组件js 中,通过e.detail.value
获取子组件传递过来的数据
获取组件实例
父组件还可以通过this.selectComponent("id或class选择器")
获取子组件实例对象,如此可以直接访问子组件的任意数据和方法
behaviors
用于实现组件间代码共享的特性,每个behaviors包含一组属性、数据、生命周期函数和方法,组件引用时其属性、数据和方法会被合并到组件中,每个组件可引用多个behaviors,behaviors之间也可相互引用
创建:
// 新建一个behaviors,js文件
// 调用behaviors()方法,创建实例对象并暴露出去
module.wxports = behaviors({
properties: {}, //属性节点
data: {}, //私有数据节点
methods: {} //事件处理函数和自定义方法节点
})
导入:
//使用require导入需要的自定义behaviors模块
const myBehavior = require("../../地址")
Component({
//将导入的behavior实例对象挂载到behaviors数组节点中即可生效
behaviors: [myBehavior],
})
behaviors所有可用节点
节点 | 类型 | 必填 | 说明 |
---|---|---|---|
properties | Object Map | 否 | 同组件属性 |
data | Object | 否 | 同组件数据 |
methods | Object | 否 | 同自定义组件方法 |
behaviors | String Array | 否 | 引入其他behaviors |
created | function | 否 | 生命周期函数 |
attached | function | 否 | 生命周期函数 |
ready | function | 否 | 生命周期函数 |
moved | function | 否 | 生命周期函数 |
detached | function | 否 | 生命周期函数 |
组件和引用的behaviors可以包含同名字段,对象会合并,其余情况会按照组件>父behaviors>子behaviors从大到小覆盖
API Promise化
实现API Promise化小程序中,实现API Promise化主要依赖与miniprogram-api-promise
第三方包
安装:npm install --save miniprogram-api-promise@1.0.4
使用:
// app.js中
import { promisifyAll } from 'miniprogram-api-promise'
const wxp = wx.p = {}
promisifyAll(wx, wxp}
//使用时
async getInfo() {
const res = await wx.p.request({
method: 'get',
url: 'url地址',
data: {
}
})
全局数据共享方案
mobx-miniprogram:用来创建Store实例对象
mobx-miniprogram-bindings:用来把Store中共享数据或方法绑定到组件或页面中使用
安装mobx包:包安装完毕后删除miniprogram_npm目录,重新构建npm
npm i --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
创建mobx的store实例:
//根目录创建文件夹 store,在文件夹里创建一个 store.js 文件
import { observable, action } from "mobx-miniprogram"
export const store = observable({
userName:'xxs',
age:20,
//计算属性,以 get 开头,表明只读
get sum(){
return age++;
},
//action 修改store 数据
updateAge: action(function(val){
this.age = 18;
})
})
Store成员绑定到页面中
//页面js
import { createStoreBindings } from 'mobx-miniprogram-bindings';
import { store } from "../../store/store";
Page({
onLoad: function (options) {
this.storeBindings = createStoreBindings(this, {
store, //指定绑定的数据源
fields: ['age', 'name'], //字段、计算属性
actions: ['updateAge'] // 方法
})
},
onUnload: function () {
this.storeBindings.destoryStoreBindings();
}
})
Store成员绑定到组件中
//页面js
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings';
import { store } from "../../store/store";
Component({
behaviors: [storeBindingsBehavior], //通过storeBindingsBehavior实现自动绑定
storeBindings: {
store,//指定数据源
fields:{//绑定的字段、计算属性
name:"name",//前面的name是自定义字段,可以自己随意修改
age:(store)=>store.age,//也可以 ()=>store.age
sum:'sum'
},
actions: { //指定绑定的方法
updateAge:"updateAge"
}
},
})
分包
把完整小程序项目根据需求划分不同子包,构件式打包成不同分包,使用时按需加载,优化了小程序首次启动下载时间,多团队共同开发时能更好解耦协作
//app.json
{
"pages": [ //主包所有页面
"pages/index/index",
"pages/user/index",
],
"preloadRule": { //分包预下载规则
“pages/countact/countact”: { //触发分包预下载的页面路径
"network": "all", //network表示在指定网络模式下进行预下载,可选all(不限网络)和wifi(仅在wifi模式下预下载,默认)
"packages": ["pkgA"] //packages表示进入页面后,预下载哪些分包,通过root或name指定
}
},
"subpackages": [ //通过subpackages节点声明分包结构
{
"root": "packA", //分包的根路径,彼此之间不可以重复
"name": "home", //分包的标识名字,用于预加载分包时用
"pages": [ //分包下所有页面相对存放路径(不预加载的时候,用户进入分包路径才会加载分包资源)
"shop_house/shop_house"
],
"independent":false //是否独立分包(可以不加载主包就独立加载的包,独立分包不能当做全局资源)
},
]
}
使用注意事项
echarts图表悬浮不跟随父元素及页面滑动的问题
使用旧的cavas即设置force-use-old-canvas=“true"即可,
< ec-canvas id=“mychart-dom-bar” canvas-id=“mychart-bar” ec=”{{ ec }}" force-use-old-canvas=“true” >< /ec-canvas>
config
种是否设置config = {“disableScroll”:true}
,需设为false
page
标签是否设置height:100%;
或者overflow
属性,如果有就去掉。
canvas的所有父级元素不能设置height:100%/overflow
相关属性(visible除外),以及position
相关的属性(relative
,static
除外)。
echarts图表层级最高,设置遮罩层z-index:999
后,开发者工具查看工具无效果
不用理,真机上是好的
微信小程序
e.target.dataset
事件触发源头组件的信息
e.currentTarget.dataset
事件绑定组件的信息
bindinput
触发input输入事件, e.detail.value
获取input最新的值