赞
踩
目录
开发小程序的第一步,你需要拥有一个小程序帐号,通过这个帐号你就可以管理你的小程序。
如果是第一次做微信小程序,你需要注册一个小程序开发账号。如果已经有小程序开发账号,直接使用浏览器打开https://mp.weixin.qq.com/网址扫码登录。
使用浏览器打开https://mp.weixin.qq.com/网址,点击右上角的“立即注册”即可进入到小程序开发账号的注册流程。
信息登记,就可以拥有自己的小程序帐号。
扫码登录进入到 小程序后台 ,我们可以在菜单 “开发”-“开发设置” 看到小程序的 AppID 了 。
(1)打开https://mp.weixin.qq.com/网址,扫码进入微信官方文档
(2)点击管理模块中的成员管理,点击下拉箭头,添加成员
微信开发者工具是官方推荐使用的小程序开发工具,它提供的主要功能如下:
1.快速创建小程序项目
2.代码的查看和编辑
3.对小程序功能进行调试
4.小程序的预览和发布
推荐下载和安装最新的稳定版(Stable Build)的微信开发者工具,下载页面的链接如下:
https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html
(1)查看项目效果:点击编译进行查看
(2)在手机上查看项目效果:点击预览会生成二维码,扫描二维码进行查看
(3)查看微信官方文档:点击帮助中的开发者文档,可直接跳转到微信官方文档
(4)查看不同型号:点击机型,可以调整不同的手机型号。也可以调整显示比例和字体大小
(5)自定义编译
在开发页面的过程中,重新编译完成后,页面都会显示到主页,如果要调试其它页面会很不方便,配置自定义编译,重新编译后,页面会显示到配置的页面,步骤:点击编译左边的下拉框→选择添加编译模式→更改启动页面的路径→确定
(1)击开发者工具顶部工具栏中的“上传”按钮
(2)填写版本号以及项目备注
注:上传成功后,需要联系管理员在小程序管理后台将本次上传设置为体验版本。
在微信开发者工具中上传项目后,登录小程序管理后台(https://mp.weixin.qq.com/),点击管理→版本管理→开发版本,即可查看提交上传的版本了。
为了保证小程序的质量,以及符合相关的规范,小程序的发布是需要经过腾讯官方审核的,点击版本管理→开发版本中的提交审核。
审核通过后,管理员的微信中会收到小程序通过审核的通知,此时在审核版本的列表中,点击“发布”按钮之后,即可把“审核通过”的版本发布为“线上版本”,供所有小程序用户访问和使用。
获取小程序码的步骤:
登录小程序管理后台→设置→基本设置→小程序码及线下物料下载
(1)在“小程序后台查看”
登录小程序理后台→点击侧边的“统计”→点击相应的tab可以看到相关的数据
(2)使用“小程序数据助手”查看
打开微信→搜索“小程序数据助手”→查看已发布的相关小程序相关的数据
(1)把小程序的代码包下载到本地
(2)解析app.json全局配置文件
(3)执行app.js小程序入口文件,调用APP()创建小程序实例
(4)渲染小程序首页
(5)小程序启动完成
(1)加载解析页面的.json配置文件
(2)加载页面的.wxml模板和 .wxss样式
(3)执行页面的.js文件,调用Page()创建页面实例
(4)页面渲染完成
小程序的应用生命周期函数需要在app.js中进行声明,示例代码如下:
- // app.js 文件
-
- App({
- //小程序初始化完成时,执行此函数,全局只触发一次。可以做一些初始化的工作
- onLaunch:function(options){},
-
- //小程序启动,或从后台进入前台显示时触发
- onShow:function(options){},
-
- // 小程序从前台进入后台时触发
- onHide:function(options){}
- })
小程序的页面生命周期函数需要在页面的.js文件中进行声明,示例代码如下:
- 页面的.js文件:
-
- Page({
- onLoad:function(options){}, //监听页面加载,一个页面只调用一次
- onShow:function(){}, //监听页面显示
- onReady:function(){}, //监听页面出次渲染完成,一个页面只调用1次
- onHide:function(){}, //监听页面隐藏
- onUnload:function(){} //监听页面卸载,一个页面只调用一次
- })
微信官方文档有小程序的组件,地址:
https://developers.weixin.qq.com/miniprogram/dev/component/cover-image.html
小程序官方把API分为了如下3大类:
特点:以on开头,用来监听某些事件的触发
举例:wx.onWindowResize(function callback)监听窗口尺寸变化的时间
特点1:以Sync结尾的API都是同步API
特点2:同步API的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
举例:wx.setStorageSync('key','value')向本地存储中写入内容
(3)异步API
特点:类似于JQuery中的$.ajax(options)函数,需要通过success、fail、complete接受调用的结果
举例:wx.request()发起网络数据请求,通过success回调函数接受数据
参考官网:https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/data.html
1.数据绑定的基本原则:
(1)在data中定义数据
在页面对应的.js文件中,把数据定义到data对象中即可
- Page({
- data:{
- //字符串类型的数据
- info:'init data',
- //数组类型的数据
- msgList:[{msg:'hello'},{msg:'world'}]
- }
- })
(2)在WXML中使用数据
把data中的数据绑定到页面中渲染,使用Mustache语法(双大括号)将变量包起来即可,语法格式为:
<view>{{要绑定的数据名称}}</view>
事件是渲染层到逻辑层的通讯方式。通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理。
小程序中常用的事件
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap或bind:tap | 手指触摸后马上离开,类似于HTML中的click事件 |
input | bindinput或bind:input | 文本框的输入事件 |
change | bindchange或bind:change | 状态改变时触发 |
小程序根目录下的app.json文件是小程序的全局配置文件。常用的配置项如下:
(1)pages:记录当前小程序所有页面的存放路径
(2)window:全局设置小程序窗口的外观
(3)tabBar:设置小程序底部的tabBar效果
(4)style:是否启用新版的组件样式
(1)概念:
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
设置步骤:app.json→window→把enablePullDownRefresh的值设置为true
注意:在app.json中启用下拉刷新功能,会作用于每个小程序页面
(2)设置下拉刷新时窗口的背景色
当全局开启下拉刷新功能之后,默认的窗口背景为白色。如果自定义下拉刷新窗口背景色,
设置步骤为:app.json →window→为backgroundColor指定16进制的颜色值。
(3)设置下拉刷新时loading的样式
当全局开启下拉刷新功能之后,默认窗口的loading 样式为白色,如果要更改loading样式的效果,
设置步骤为app.json -> window ->为backgroundTextStyle设定值,仅支持dark/light。
(4)设置上拉触底的距离
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
设置步骤: app.json -> window ->为onReachBottomDistance设置新的数值
注意:默认距离为50px,如果没有特殊需求,建议使用默认值即可。
(1)什么是tabBar
tabBar是移动端应用常见的页面效果,用于实现多页面的快速切换。小程序中通常将其分为:
底部 tabBar、顶部 tabBar
注意:tabBar中只能配置最少2个、最多5个tab页签当渲染顶部 tabBar时,不显示icon,只显示文本
(2)tabBar的六个组成部分
backgroundColor: tabBar的背景色
borderStyle: tabBar上边框的颜色
iconPath:未选中时的图片路径
selectediconPath:选中时的图片路径
selectedColor: tab 上的文字选中时的颜色
color: tab 上文字的默认(未选中)颜色
(3)tabBar节点的配置项
属性 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
position | String | 否 | bottom | tabBar的位置,仅支持bottom/top |
borderStyle | String | 否 | black | tabBar上边框的颜色,仅支持black/white |
color | HexColor | 否 | tab上文字的默认(未选中)颜色 | |
selectedColor | HexColor | 否 | tab上的文字选中时的颜色 | |
backgroundColor | HexColor | 否 | tabBar的背景色 | |
list | Array | 是 | tab页签的列表,最少2个,最多5个tab |
(4)每个tab项的配置选项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
pagePath | String | 是 | 页面路径,页面必须在pages中预先定义 |
text | String | 是 | tab上显示的文字 |
iconPath | String | 否 | 未选中时的图标路径;当position为top时,不显示icon |
selectedIconPath | String | 否 | 选中时的图标路径,当position为top时,不显示icon |
(5)示例
步骤:
<1> 新建images文件夹,把需要的图标放到文件夹中
<2> 通过app.json文件的page节点,新建3个对应的tab页面,配置好路径,pages文件夹中会自动新建3个对应的文件夹
<3> 配置tabBar选项:和pages、window平级,新增tabBar节点,在tabBar节点中,新增list数组,在list数组中,新增每个tab项的配置对象
小程序中,app.json中的window节点,可以全局配置小程序中每个页面的窗口表现。
如果某些小程序页面想要拥有特殊的窗口表现,此时,“页面级别的.json配置文件”就可以实现这种需求。
注意:当页面配置与全局配置冲突时,根据就近原则,最终的效果以页面配置为准。
参考官网:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html
出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
只能请求HTTPS类型的接口
必须将接口的域名添加到信任列表中
需求描述:
假设在自己的微信小程序中,希望请求https://www.escook.cn/域名下的接口
配置步骤:
登录微信小程序管理后台→>开发→>开发设置→>服务器域名->开始配置 / 修改request合法域名
注意事项:
域名只支持https 协议
域名不能使用IP地址或 localhost 域名必须经过ICP备案
服务器域名一个月内最多可申请5次修改
在微信小程序管理后台上配置好域名,打开微信开发者工具的详情→项目配置,域名信息会自动刷新为配置好的域名
调用微信小程序提供的wx.request()方法,可以发起GET请求,示例如下:
(1) 在home.js中写get请求
(2)在home.wxml中添加按钮,并用bindtap方法
点击按钮,调试器中会打印data
POST请求与GET请求类似,调用微信小程序提供的wx.request()方法,可以发起POST 数据请求,示例代码如下:
- home.wxml页面:
- <button bindtap="postInfo">发起POST请求</button>
-
-
- home.js页面:
-
- // 发起POST数据请求
- postInfo(){
- wx.request({
- url:'https://www.escook.cn/api/post',
- method:'POST',
- data:{
- name:'ls',
- age:'33'
- },
- success:(res)=>{
- console.log(res);
- }
- })
- },

在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据。此时需要在页面的onLoad事件中调用获取数据的函数,例如在onLoad()中调用get和post请求,页面一加载就会返回数据。示例代码如下:
如果后端程序员仅仅提供了http协议的接口、暂时没有提供 https协议的接口。此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS版本及HTTPS证书」选项,跳过request合法域名的校验。
注意:跳过request合法域名校验的选项,仅限在开发与调试阶段使用
跨域问题只存在于基于浏览器的Web 开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax技术的核心是依赖于浏览器中的XMLHttpRequest这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做“发起 Ajax请求”,而是叫做“发起网络数据请求”。
页面导航指的是页面之间的相互跳转。例如,浏览器中实现页面导航的方式有如下两种:
<a>链接
location.href
(1)声明式导航
在页面上声明一个<navigator>导航组件,通过点击<navigator>组件实现页面跳转
(2)编程式导航
调用小程序的导航API,实现页面的跳转
tabBar页面指的是被配置为tabBar的页面。
在使用<navigator>组件跳转到指定的tabBar页面时,需要指定url属性和 open-type属性,
其中:url表示要跳转的页面的地址,必须以/开头
open-type表示跳转的方式,必须为switchTab
示例代码如下:
非tabBar页面指的是没有被配置为tabBar的页面。
在使用<navigator>组件跳转到普通的非tabBar页面时,则需要指定url属性和open-type属性,其中:
url表示要跳转的页面的地址,必须以/开头
open-type表示跳转的方式,必须为navigate
注意:为了简便,在导航到非tabBar页面时,open-type="navigate"属性可以省略不写
示例代码如下:
<navigator url="/pages/info/info" open-type="navigate">导航到info页面</navigator>
如果要后退到上一页面或多级页面,则需要指定open-type属性和delta属性,其中:
open-type 的值必须是navigateBack,表示要进行后退导航
delta 的值必须是数字,表示要后退的层级
注意:为了简便,如果只是后退到上一页面,则可以省略delta属性,因为其默认值就是1
示例代码如下:
<navigator open-type="navigateBack" delta="1">返回上一级</navigator>
调用wx.switchTab(Object object)方法,可以跳转到tabBar页面。其中Object参数对象的属性列表如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的tabBar页面的路径,路径后不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码如下:
- home.wxml页面:
-
- <button bindtap="gotoMessage">跳转到message页面</button>
-
-
- home.js页面:
-
- gotoMessage(){
- wx.switchTab({
- url:'/pages/message/message' // 路径前面加 /
- })
- },
- home.wxml页面:
-
- <button bindtap="gotoInfo">跳转到info页面</button>
-
-
- home.js页面:
-
- gotoInfo(){
- wx.navigateTo({
- url:'/pages/info/info'
- })
- },
调用wx.navigateBack(Object object)方法,可以返回上一页面或多级页面。其中Object 参数对象可选的属性列表如下:
属性 | 类型 | 默认值 | 是否必选 | 说明 |
---|---|---|---|---|
delta | number | 1 | 否 | 返回的页面数,如果delta大于现有页面数,则返回首页 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码如下:
- info.wxml页面:
-
- <button bindtap="goBack">后退</button>
-
-
- info.js页面:
-
- goBack(){
- wx.navigateBack({
- delta:1 //delta为1时可以省略不写
- })
- },
navigator组件的url属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数:
●参数与路径之间使用 ? 分隔
●参数键与参数值用 = 相连
●不同参数用 & 分隔
示例代码如下:
- home.wxml页面:
-
- <navigator url="/pages/info/info?name=zs&age=20">跳转到info页面</navigator>
查看传参结果:
左下角点击小三角→选择页面参数→就会出现传的参数
调用wx.navigateTo(0bject object)方法跳转页面时,也可以携带参数,代码示例如下:
- home.wxml页面:
-
- <button bindtap="gotoInfo">跳转到info页面</button>
-
- home.js页面:
-
- gotoInfo(){
- wx.navigateTo({
- url:'/pages/info/info?name=ls&gender=男'
- })
- },
通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取到,
(在主页面传的参数,可以在跳转页取到)
示例代码如下:
- info.js页面:
-
- data: {
- query:{} //导航传递过来的参数
- },
- onLoad(options) {
- console.log('sasas',options);
- this.setData({
- query:options //把值存起来以便其它方法使用
- })
- },
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
启用下拉刷新有两种方式:
在app.json 的 window节点中,将enablePullDownRefresh 设置为true
在页面的.json配置文件中,将enablePullDownRefresh设置为true
在实际开发中,推荐使用第2种方式,为需要的页面单独开启下拉刷新的效果
在全局或页面的.json配置文件中,通过backgroundColor和 backgroundTextStyle 来配置下拉刷新窗口的样式,其中:
backgroundColor用来配置下拉刷新窗口的背景颜色,仅支持16进制的颜色值
backgroundTextStyle用来配置下拉刷新lgading的样式,仅支持dark和 light
在页面的.js文件中,通过onPullDownRefresh()函数即可监听当前页面的下拉刷新事件。例如,在页面的wxml中有如下的UI结构,点击按钮可以让count值自增+1:
在触发页面的下拉刷新事件的时候,如果要把count的值重置为0,示例代码如下:
- home.wxml页面:
-
- <view>count值是:{{count}}</view>
- <button bindtap="addCount">点击+1</button>
-
-
- home.js页面:
-
- //页面的初始数据
- data: {
- count:0
- },
-
- addCount(){
- this.setData({
- count:this.data.count+1
- })
- },
-
- //页面相关事件处理函数--监听用户下拉动作
- onPullDownRefresh() {
- this.setData({
- count:0
- })
- },

当处理完下拉刷新后,下拉刷新的loading效果会一直显示,不会主动消失,所以需要手动隐藏loading效果。此时,调用wx.stopPullDownRefresh()可以停止当前页面的下拉刷新。示例代码如下:
- home.js页面:
-
- onPullDownRefresh() {
- console.log('触发了下拉刷新');
- this.setData({
- count:0
- })
- //停止下拉刷新效果
- wx.stopPullDownRefresh()
- },
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行
在页面的.js文件中,通过onReachBottom()函数即可监听当前页面的上拉触底事件。示例代码如下:
上拉触底距离指的是触发上拉触底事件时,滚动条距离页面底部的距离。
可以在全局或页面的.json配置文件中,通过onReachBottomDistance属性来配置上拉触底的距离。
小程序默认的触底距离是50px,在实际开发中,可以根据自己的需求修改这个默认值
对上拉触底进行节流处理:
<1> 在data中定义 isloading节流阀
false表示当前没有进行任何数据请求,true表示当前正在进行数据请求
<2> 在getColors()方法中修改isloading节流阀的值
在刚调用getcolors时将节流阀设置true
在网络请求的complete回调函数中,将节流阀重置为false
<3> 在onReachBottom中判断节流阀的值,从而对数据请求进行节流控制
如果节流阀的值为 true,则阻止当前请求
如果节流阀的值为false,则发起数据请求
示例代码如下:
- home.wxml页面:
- <view wx:for="{{colorList}}" wx:key="index" class="num-item" style="background-color:rgba({{item}})">{{item}}</view>
-
-
- home.js页面:
-
- data: {
- colorList:[],
- isloading:false //是否节流初始值
- },
-
- getColors(){
- this.setData({
- isloading:true
- })
- // 需要展示loading效果
- wx.showLoading({
- title:'数据加载中...'
- })
- wx.request({
- url:'https://www.escook.cn/api/color',
- method:'GET',
- success:({data:res})=>{
- console.log(res);
- this.setData({
- colorList:[...this.data.colorList,...res.data]
- })
- },
- //数据加载完成后隐藏加载
- complete:()=>{
- wx.hideLoading()
- // this.setData({
- // isloading:false
- // })
- }
- })
- },
-
-
- //生命周期函数--监听页面加载
-
- onLoad() {
- this.getColors()
- },
-
- onReachBottom() {
- if(this.data.isloading){
- return
- }
- this.getColors()
- },

WXS ( weiXin Script)是小程序独有的一套脚本语言,结合WXML,可以构建出页面的结构。
wxml中无法调用在页面的.js 中定义的函数,但是,wxml 中可以调用wxs 中定义的函数。因此,小程序中wxs的典型应用场景就是“过滤器”。
虽然wxs 的语法类似于JavaScript,但是 wxs和JavaScript是完全不同的两种语言:
number 数值类型、string字符串类型、boolean布尔类型、object对象类型、function函数类型、array 数组类型、date日期类型、regexp正则
不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc... 支持:var定义变量、普通function函数等类似于ES5的语法
module对象
require()函数
module.exports对象
wxs 代码可以编写在wxml文件中的<wxs>标签内,就像Javascript代码可以编写在html文件中的<script>标签内一样。
wxml文件中的每个<wxs></wxs>标签,必须提供 module 属性,用来指定当前wxs的模块名称,方便在wxml中访问模块中的成员:
- home.wxml页面:
-
- <view>{{ml.toUpper(username)}}</view> //调用wxs中的方法
-
- <wxs module="ml"> //定义module属性
- module.exports.toUpper=function(str){ //用module.exports抛出
- return str.toUpperCase()
- }
-
-
- home.js页面:
- data: {
- username:'zs'
- },
定义外联的wxs 脚本:
wxs 代码还可以编写在以.wxs为后缀名的文件内,就像javascript 代码可以编写在以.js 为后缀名的文件中一样。示例代码如下:
使用外联的wxs 脚本:
在wxml中引入外联的wxs脚本时,必须为<wxs>标签添加module和 src属性, 其中:module用来指定模块的名称
src用来指定要引入的脚本的路径,且必须是相对路径
- home.wxml页面:
-
- <view>{{m2.toUpper(username)}}</view>
-
- <wxs src="./tool.wxs" module="m2"></wxs>
-
-
- tool.wxs页面:
-
- function toUpper(str){
- return str.toUpperCase()
- }
- module.exports={
- toUpper:toUpper //wxs不支持对象属性简写,所以要写全
- }
-
- home.js页面:
- data: {
- username:'zs'
- },
-
-

(1)为了降低wxs (Weixin Script)的学习成本,wxs语言在设计时借大量鉴了JavaScript的语法。但是本质上,wxs和JavaScript是完全不同的两种语言!
(2)不能作为组件的事件回调
wxS典型的应用场景就是“过滤器”,经常配合Mustache语法进行使用
(3)隔离性
隔离性指的是 wxs的运行环境和其他JavaScript代码是隔离的。体现在如下两方面: wxs不能调用js中定义的函数
wxs不能调用小程序提供的API
(4)性能好
在iOS设备上,小程序内的wxs会比JavaScript代码快2~20倍 在android设备上,二者的运行效率无差异
在项目的根目录中,鼠标右键,创建components → test文件夹
在新建的components→test文件夹上,鼠标右键,点击“新建Component""
在输入组件的名称之后回车,会自动生成组件对应的4个文件,后缀名分别为.js,.json,.wxml和.wxss
组件的引用方式分为“局部引用”和“全局引用”
根据组件的使用频率和范围,来选择合适的引用方式:
如果某组件在多个页面中经常被用到,建议进行“全局引用” 如果某组件只在特定的页面中被用到,建议进行“局部引用”
组件只能在当前被引用的页面内使用,示例代码如下:
- home.json页面:
-
- {
- "usingComponents": {
- "my-test1":"/components/test/test"
- },
- "enablePullDownRefresh": true,
- "backgroundColor": "#efefef",
- "backgroundTextStyle": "dark"
- }
-
-
- home.wxml页面:
-
- <my-test1></my-test1>
组件可以在每个小程序页面中使用
在app.json全局配置文件中引用组件的方式,叫做“全局引用”,示例代码如下:
- app.json页面:
-
- //和pages,window平级
- "usingComponents": {
- "my-test1":"/components/test/test"
- }
-
-
- //全局配置的在wxml页面都可以用
- home.wxml页面:
- <my-test1></my-test1>
-
-
- message.wxml页面:
- <my-test1></my-test1>
从表面来看,组件和页面都是由.js、.json、.wxml和.wxss这四个文件组成的。但是,组件和页面的.js与.json文件有明显的不同:
组件的.json文件中需要声明"component": true属性
组件的.js 文件中调用的是Component()函数
组件的事件处理函数需要定义到 methods节点中
app.wxss中的全局样式对组件无效
只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响
建议:在组件和引用组件的页面中建议使用class选择器,不要使用id、属性、标签选择器
默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过stylelsolation修改组件的样式隔离选项,用法如下:
- //在组件的.js文件中新增如下配置
- Component({
- options:{
- styleIsolation:'apply-shared'
- },
- })
-
- //或在组件的.json文件中新增如下配置
- {
- "styleIsolation":"apply-shared"
- }
styleIsolation的可选值:
可选值 | 默认值 | 描述 |
---|---|---|
isolated | 是 | 表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会相互影响 |
apply-shared | 否 | 示页面wxss样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面 |
shared | 否 | 表示页面wxss样式将影响到自定义组件,自定义组件wxss 中指定的样式也会影响页面和其他设置了apply-shared 或shared的自定义组件 |
在小程序组件中,properties是组件的对外属性,用来接收外界传递到组件中的数据,示例代码如下:
- test.js页面(组件页)
- properties: { //属性定义
- max:{ //完整定义属性的方式(当需要指定属性默认值时,建议使用此方式)
- type:Number, //属性值的数据类型
- value:10 //属性默认值(当wxml页面没传max值时,max默认为10)
- },
- 或者
- max:Number //简化定义属性的方式(不需要指定属性默认值时,建议使用此方式)
- },
-
- 注:this.properties.max就可以取到传到组件的值
-
-
- home.wxml页面:
- <my-test1 max='102'></my-test1>
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于vue 中的watch侦听器。在小程序组件中,数据监听器的基本语法格式如下:
- Component({
- observers({
- '字段A,字段B':function (字段A的新值,字段B的新值) {
- //do something
- }
- })
- })
案例如下:如 n1+n2=sum,通过监听n1和n2的变化,实时更新sum的值
- test.wxml页面:
- <view>{{n1}}+{{n2}}={{sum}}</view>
- <button bindtap="addn1">n1+1</button>
- <button bindtap="addn2">n2+1</button>
-
-
- test.js页面(组件页):
- 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
- })
- }
- }
- })

数据监听器支持监听对象中单个或多个属性的变化,示例语法如下:
- Component({
- observers({
- '对象.属性A,对象.属性B,':function (属性A的新值,属性B的新值) {
- //触发此监听器的3种情况:
- //[为属性A赋值]使用setData设置this.data.对象.属性A时触发
- //[为属性B赋值]使用setData设置this.data.对象.属性B时触发
- //[直接为属性赋值]使用setData设置this.data.对象时触发
- //do something
- }
- })
- })
如果某个对象中需要被监听的属性太多,为了方便,可以使用通配符**来监听对象中所有属性的变化。
概念:纯数据字段指的是那些不用于界面渲染的data字段。
应用场景︰例如有些情况下,某些data中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。带有这种特性的data字段适合被设置为纯数据字段。
好处:纯数据字段有助于提升页面更新的性能。
在Component构造器的options 节点中,指定pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段,示例代码如下:
- Component({
- options:{
- pureDataPattern:/^_/ //指定所有_开头的数据字段为纯数据字段
- },
- data:{
- a:true, //普通数据字段
- _b:true //纯数据字段
- }
- })
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面节点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行 |
error | Object Error | 每当组件方法抛出错误时执行 |
在小程序组件中,最重要的生命周期函数有3个,分别是created、attached、detached。它们各自的特点如下:
①组件实例刚被创建好的时候,created生命周期函数会被触发
此时还不能调用setData
通常在这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性字段
②在组件完全初始化完毕、进入页面节点树后,attached生命周期函数会被触发
此时, this.data已被初始化完毕
这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
③在组件离开页面节点树后,detached生命周期函数会被触发
退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
此时适合做一些清理性质的工作
定义生命周期函数——lifetimes节点
在小程序组件中,生命周期函数可以直接定义在Component构造器的第一级参数中,可以在 lifetimes字段内进行声明(这是推荐的方式,其优先级最高)。示例代码如下:
- Component({
- lifetimes: {
- attached: function() { //或者attached() { }
- // 在组件实例进入页面节点树时执行
- },
- detached: function() {
- // 在组件实例被从页面节点树移除时执行
- },
- },
- // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
- attached: function() {
- // 在组件实例进入页面节点树时执行
- },
- detached: function() {
- // 在组件实例被从页面节点树移除时执行
- },
- })

有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。
例如:每当触发页面的show生命周期函数的时候,我们希望能够重新生成一个随机的RGB颜色值。在自定义组件中,组件所在页面的生命周期函数有如下3个,分别是:
生命周期函数 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在的页面被展示时执行 |
hide | 无 | 组件所在的页面被隐藏时执行 |
resize | object Size | 组件所在的页面尺寸变化时执行 |
定义组件所在页面生命周期函数——pageLifetimes节点
组件所在页面的生命周期函数,需要定义在pageLifetimes节点中,示例代码如下:
- Component({
- pageLifetimes: {
- show: function() { }, //页面被展示
- hide: function() { }, //页面被隐藏
- resize: function(size) { }, //页面尺寸变化
- }
- })
在自定义组件的wxml结构中,可以提供一个<slot>节点(插槽),用于承载组件使用者提供的wxml结构。
在小程序中,默认每个自定义组件中只允许使用一个<slot>进行占位,这种个数上的限制叫做单个插槽。示例代码如下:
- test.wxml页面:(自定义组件)
-
- <view>111</view>
- <slot></slot> //插槽
-
-
- home.wxml页面:
-
- <my-test1>
- <view>这是通过插槽填充的内容</view>
- </my-test1>
-
-
- app.json页面:
-
- "usingComponents": {
- "my-test1":"/components/test/test", //配置test页面
- },
-
-
- //页面展示:
- 111
- 这是通过插槽填充的内容

在小程序的自定义组件中,需要使用多<slot>插槽时,可以在组件的.js文件中,通过如下方式进行启用。示例代码如下:
- test.js页面:(自定义组件)
- Component({
- options:{
- multipleSlots:true
- },
- })
如何区分多个插槽?
可以在组件的.wxml中使用多个<slot>标签,以不同的name 来区分不同的插槽。在使用带有多个插槽的自定义组件时,需要用slot 属性来将节点插入到不同的<slot>中。示例代码如下:
- test.wxml页面:
-
- <slot name='before'></slot>
- <view>111</view>
- <slot name='after'></slot>
-
-
- home.wxml页面:
-
- <my-test1>
- <view slot='before'>这就是通过插槽填充的内容111</view>
- <view slot='after'>这就是通过插槽填充的内容222</view>
- </my-test1>
-
-
- test.js页面:
-
- Component({
- options:{
- multipleSlots:true
- },
- })

①属性绑定
用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据
属性绑定用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件。子组件在properties 节点中声明对应的属性并使用。
②事件绑定
用于子组件向父组件传递数据,可以传递任意数据,使用步骤如下:
<1>在父组件的js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件
<2>在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
<3>在子组件的js中,通过调用this.triggerEvent('自定义事件名称',{/*参数对象*/}),将数据发送到父组件<4>在父组件的js 中,通过e.detail 获取到子组件传递过来的数据
③获取组件实例 父组件还可以通过this.selectComponent()获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法
可在父组件里调用this.selectComponent("id或class选择器"),获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器,例如 this.selectComponent(".my-component")。
父子相互传值示例代码如下:
- home.wxml页面:
- <my-test1 count="{{count}}" bind:sync="ayncCount"></my-test1>
- //<2>通过自定义事件的形式bind:sync,将home.js页面中定义的ayncCount函数引用(注:sync是自己命名的)
-
- home.js页面:
- data: {
- count:0
- },
- ayncCount(){ //<1>定义一个函数
- console.log('ayncCount');
- console.log(e.detail.value);
- this.setData({ //<4>通过e.detail 获取到子组件传递过来的数据
- count:e.detail.value
- })
- },
-
- test.js页面:
- properties: {
- count:Number
- },
- methods: {
- addCount(){
- this.setData({
- count:this.properties.count+1
- })
- //<3>触发自定义事件,将数值同步给父组件
- this.triggerEvent('sync',{value:this.properties.count})
- }
- }
-
- test.wxml页面:
- <view>子组件中,count值是:{{count}}</view> //count是子组件取的父组件传过来的值
- <button bindtap="addCount">+1</button> //子组件count自增

behaviors 是小程序中,用于实现组件间代码共享的特性,类似于Vue.js 中的“mixins”。
每个behavior可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
注:每个组件可以引用多个behavior,behavior也可以引用其它behavior。
调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,供所有的组件使用:
在组件中,使用require()方法导入需要的 behavior,挂载后即可访问behavior中的数据或方法
示例代码如下:
- 新建behavior文件夹,及myBehavior.js页面:
-
- //myBehaviorjs页面:
- module.exports=Behavior({
- data:{
- username:'zs'
- },
- properties:{},
- methods:{
-
- }
- })
-
-
- //test.js页面:
- const myBehavior=require('../../behavior/my-behavior')
- Component({
- behaviors:[myBehavior],
- })
-
-
- //test.wxml页面:
- <view>在behavior中定义的用户名是:{{username}}</view>
-
-
- //页面显示:behavior中定义的用户名是:zs

behavior中所有可用的节点:
可用的节点 | 类型 | 是否必填 | 描述 |
---|---|---|---|
properties | Object Map | 否 | 同组件的属性 |
data | Object | 否 | 同组件的数据 |
methods | Object | 否 | 同自定义组件的方法 |
behaviors | String Array | 否 | 引入其它的behavior |
created | Function | 否 | 生命周期函数 |
attached | Function | 否 | 生命周期函数 |
ready | Function | 否 | 生命周期函数 |
moved | Function | 否 | 生命周期函数 |
detached | Function | 否 | 生命周期函数 |
组件和它引用的 behavior中可以包含同名的字段,此时可以参考如下3种同名时的处理规则:
①同名的数据字段(data)
②同名的属性(properties)或方法(methods) ③同名的生命周期函数
关于详细的覆盖和组合规则,大家可以参考微信小程序官方文档给出的说明:
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html
Vant weapp是有赞前端团队开源的一套小程序UI组件库,助力开发者快速搭建小程序应用。它所使用的是MIT开源许可协议,对商业使用比较友好。具体操作参考官方文档。
官方文档地址:https://youzan.github.io/vant-weapp
<1> 首先确保文件中有package.json,如果没有,先进行初始化:npm init -y
<2> npm安装:npm i @vant/weapp -S --production
<3> 将 app.json 中的 "style": "v2"去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。
<4> 构建npm包:打开微信开发者工具,点击工具→构建npm,勾选npm模块选项(注:新版本自动构建npm了,所以没有这个选项了,只需要点击工具→构建npm,构建成功即可)
注:每次npm安装完一个新包时,都要重新构建一下,再重新操作一遍点击工具→构建npm
Vant weapp使用CSS变量来实现定制主题。关于CSS变量的基本用法,参考MDN文档:
https://developer.mozilla.org/zh-CN/docs/web/csS/Using_css_custom_properties
在app.wxss 中,写入CSS变量,即可对全局生效:
例如:想修改默认按钮的颜色:
- app.wxss页面:
-
- Page{
- --button-default-background-color:#f999
- }
默认情况下,小程序官方提供的异步API都是基于回调函数实现的,例如,网络请求的API需要按照如下的方式调用:
- wx.request({
- method:'',
- url:'',
- data:{},
- success:()=>{},
- fail:()=>{},
- complete:()=>{},
- })
缺点:容易造成回调地狱的问题,代码的可读性、维护性差!
APl Promise化,指的是通过额外的配置,将官方提供的、基于回调函数的异步API,升级改造为基于Promise 的异步API,从而提高代码的可读性、维护性,避免回调地狱的问题。
在小程序中,实现 APl Promise化主要依赖于miniprogram-api-promise这个第三方的npm包。它的安装和使用步骤如下:
①鼠标放在最外的文件夹名上,右键,选择在外部终端窗口中打开
②输入npm i --save miniprogram-api-promise
③点击工具→构建npm
- //在小程序入口文件中(app.js),只需调用一次promisifyAll()方法
- //即可实现异步API的Promise化
-
- app.js页面:
- import {promisifyAll} from 'miniprogram-api-promise'
- const wxp=wx.p={}
- promisifyAll(wx,wxp)
调用Promise化之后的异步API
- home.wxml页面:
- <van-button type="default" bindtap="getInfo">默认按钮</van-button>
-
- /home.js页面:
- async getInfo(){
- const (res)=await wx.p.request({
- method:"GET",
- url:"https://www.escook.cn/api/get",
- data:{
- name:'zs',
- age:20
- }
- })
- console.log(res);
- },
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。 开发中常用的全局数据共享方案有:Vuex、Redux、MobX等。
在小程序中,可使用mobx-miniprogram配合 mobx-miniprogram-bindings实现全局数据共享。 其中:mobx-miniprogram用来创建Store实例对象
mobx-miniprogram-bindings 用来把Store 中的共享数据或方法,绑定到组件或页面中使用
使用步骤:
①安装MobX相关的包,并且点击工具→构建npm
在项目中运行如下的命令,安装MobX相关的包:
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
②创建store文件夹,并且新建store.js文件,创建Mobx的store实例
- //在这个js文件中,专门来创建store的实例对象
- import {observable,action}from 'mobx-miniprogram'
-
- export const store=observable({ //store是实例对象
- //数字字段
- numA:1,
- numB:2,
- //计算属性
- get sum(){ //定义get,为只读模式,因为计算属性的值不需要重新赋值
- return this.numA+this.numB
- },
- //action方法,用来修改store中的数据
- updateNum1:action(function(step){
- this.numA+=step
- }),
- updateNum2:action(function(step){
- this.numB+=step
- })
- })

③将store中的成员绑定到home.js页面中并使用store中的数据
- home.js页面:
-
- import {createStoreBindings}from 'mobx-miniprogram-bindings'
- import {store} from '../../store/store'
- Page({
-
- //生命周期函数--监听页面加载
- onLoad:function(options) {
- this.storeBindings=createStoreBindings(this,{
- store, //数据源
- fields:['numA','numB','sum'], //字段或计算属性
- actions:['updateNum1'] //方法
- })
-
- },
- //调用home.wxml页面方法,并使用store.js中的方法
- btnHandler1(e){
- this.updateNum1(e.target.dataset.step)
- },
- btnHandler2(e){
- this.updateNum1(e.target.dataset.step)
- },
- //生命周期函数--监听页面卸载
- onUnload() {
- this.storeBindings.detroyStoreBindings()
- },
- })
-
-
- home.wxml页面:
- <view>{{numA}}+{{numB}}={{sum}}</view>
- <van-button type="default" bindtap="btnHandler1" data-step="{{1}}">numA+1</van-button>
- <van-button type="primary" bindtap="btnHandler2" data-step="{{-1}}">numA-1</van-button>
-

④将store中的成员绑定到组件中并使用store中的数据
- component.js页面:
-
- import {createStoreBindings}from 'mobx-miniprogram-bindings'
- import {store} from '../../store/store'
- Component({
- behaviors:{storeBindingsBehavior},
- storeBindings{
- store,
- fields:{
- numA:'numA',
- numB:'numB',
- sum:'sum'
- },
- actions:{}
- }
- methods:{
- btnHandler2(e){
- this.updateNum1(e.target.dataset.step)
- },
- }
- //生命周期函数--监听页面卸载
- onUnload() {
- this.storeBindings.detroyStoreBindings()
- },
- })
-
-
- component.wxml页面:
- <view>{{numA}}+{{numB}}={{sum}}</view>
- <van-button type="default" bindtap="btnHandler2" data-step="{{1}}">numA+1</van-button>
- <van-button type="primary" bindtap="btnHandler2" data-step="{{-1}}">numA-1</van-button>
-

分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
对小程序进行分包的好处主要有以下两点:
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后,小程序项目由1个主包+多个分包组成:
主包:一般只包含项目的启动页面或TabBar页面、以及所有分包都需要用到的一些公共资源 分包:只包含和当前分包有关的页面和私有资源
①在小程序启动时,默认会下载主包并启动主包内页面:tabBar页面需要放到主包中
②当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示:
非tabBar页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
目前,小程序分包的大小有以下两个限制:
整个小程序所有分包大小不超过16M(主包+所有分包) 单个分包/主包大小不能超过2M
在app.json中进行配置:
和pages平级,添加"subPackages": [],有几个分包,就添加几个对象,root属性指定分包的根目录,保存后会自动创建页面。
- app.json页面:
-
- {
- "pages": [ //主包所有页面
- "pages/home/home",
- "pages/message/message",
- "pages/contact/contact"
- ],
- "subPackages": [ //通过subPackages节点,声明分包的节后
- {
- "root": "pkgA", //第一个分包的根目录
- "name": "p1",
- "pages": [ //当前分包下,所有页面的存放路径
- "pages/cat/cat",
- "pages/dog/dog"
- ]
- },
- {
- "root": "pkgB",
- "name": "p2",
- "pages": [
- "pages/apple/apple"
- ]
- }
- ],
- }

①小程序会按subpackages 的配置进行分包,subpackages之外的目录将被打包到主包中 ②主包也可以有自己的pages(即最外层的pages字段)
③tabBar页面必须在主包内
④分包之间不能互相嵌套
①主包无法引用分包内的私有资源
②分包之间不能相互引用私有资源 ③分包可以引用主包内的公共资源
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
最主要的区别:是否依赖于主包才能运行
普通分包必须依赖于主包才能运行
独立分包可以在不下载主包的情况下,独立运行
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
当小程序从普通的分包页面启动时,需要首先下载主包
而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度 注意:一个小程序中可以有多个独立分包
在普通分包的基础上, 添加"indepenfent":true即可
- {
- "root": "pkgB",
- "name": "p2",
- "pages": [
- "pages/apple/apple"
- ],
- "independent":true
- }
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源! 例如: ① 主包无法引用独立分包内的私有资源
②独立分包之间,不能相互引用私有资源
③独立分包和普通分包之间,不能相互引用私有资源 ④特别注意:独立分包中不能引用主包内的公共资源
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
预下载分包的行为,会在进入指定的页面时触发。在 app.json中,使用preloadRule,节点定义分包的预下载规则,示例代码如下:
- "preloadRule": { //分包预下载的规则
- "pages/contact/contact":{ //触发分包预下载的页面路径
- "packages": ["pkgA"],
- "network": "all"
- }
- },
-
- //packages表示进入页面后,预下载哪些分包。可以通过root或name指定预下载哪些分包
- //network表示在指定的网络模式下进行预下载,写选值为:all(不限网络)和wifi(仅wifi模式下进行预下载),默认值为wifi
同一个分包中的页面享有共同的预下载大小限额2M,例如:
转自黑马程序员:基于uni-app开发的电商项目
具体操作参考:https://applet-base-api-t.itheima.net/
附uni-app官方文档:https://uniapp.dcloud.net.cn/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。