前言
微信小程序是一种不需要下载安装即可使用的应用,运行环境为微信,用户只需扫一扫就可以或者搜一下即可使用。具有容易小规模试错,然后快速迭代,跨平台等优点。
一.微信小程序环境准备
微信小程序的运行环境就是微信,所有需要使用微信开发者工具来开发。
1.注册账号
打开链接:微信官方文档 | 微信开放文档
微信支付文档:文档更新日志|微信支付商户平台文档中心
依次填写注册信息
2.获取APPID
由于后期调用微信小程序的接口功能,需要索取开发者的小程序APPID,登录微信开发者平台就可以看见APPID
2.下载微信开发者工具
打开开发工具,然后填写APPID,项目名称:自取名称和路径,开发模式:小程序,语言:javascript或者typescript
3.熟悉微信开发者工具
官网详细链接:概览 | 微信开放文档
二.框架
1.pages存放的主要是小程序的页面
2.utils存放js共享方法的文件
3.全局配置app.json
1.*pages:[{}] 页面路径列表
2.*window:
navigationBarBackgroundColor:配置导航栏背景颜色
navigationBarTextStyle:配置导航栏标题样式
navigationBarTitleText:配置导航栏的颜色
backgroundColor:配置窗口的背景颜色
3.底部tabbar
color :tabar上文字的颜色
selectedColor:tabbar上文字选中的颜色(十六进制)
backgroundColor:tab背景颜色
borderstyle: tabbar背景颜色white/black
4.subpackages声明分包结构
{"pages":["pages/index/index"]
}
{
"pages": [//注册页面
"pages/index/index"
],
"requiredPrivateInfos": [
"getLocation"
],
"permission": {
"scope.userLocation": {
"desc": " "
}
},
"plugins": {//插件
"captcha": {
"version": "2.0.3",
"provider": "wx16c573059683b2ca"
}
},
"window": {//小程序全局配置
"backgroundColor": "#D22020",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#D22020",
"navigationBarTitleText": "text",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": false
},
"tabBar": {//底部导航栏
"selectedColor": "#A52A2A",
"list": [
{
"pagePath": "pages/user/userCenter/userCenter",
"text": "个人中心",
"iconPath": "images/account.png",
"selectedIconPath": "images/account1.png"
}
]
},
"subPackages": [//分包管理
{
"root": "pages/userComponent/",
"pages": [
"pages/coupon/couponList/couponList"
]
}
],
4.app.js文件:小程序的入口文件,全局文件
var util = require('/utils/util.js');
//app.js
App({
onLaunch(options){//小程序应用的生命周期钩子,只在小程序初次启动的时候执行
console.log('launch',options)
},
onShow(option){//小程序被切换到前台模式的时候会自动执行,执行多次
console.log('show',option)
},
onHide(){},//小程序从前台切换到后台就会执行
add(){//自定义函数
},
globalData:{//定义全局数据,可以在任意页面中获取,在 页面中引入APP实列获取,如
// var app=getApp(),需要在页面的Page({})前面定义,在页面中修改数据:app/getApp().globalData.name = "王二麻子";在App.js中修改: this.globalData.name = '李四'
name:'张三'
},
onError(error) {//当页面运行过程中出现一些异常的时候就会触发
console.log(error)
},
onPageNotFound(result) {//当我们访问不存在的页面时触发
console.log(result)
}
})
5.app.wxss文件:微信全局样式配置
/**app.wxss**/
/* 页面全局属性 */
//引入wxss文件:@import 'style/common.wxss'/**只支持相对路径**/
page{
width: 100%;
height: 100%;
background-color: #EEE;
color: #444;
font-size: 32rpx;
}
/* 通用样式 */
.hidden{
display: none;
}
6.project.config.json文件:项目功能配置文件
比如小程序APPID配置,是否可以使用es6语法
"setting": {
"urlCheck": false,
"es6": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"bundle": false,
"useIsolateContext": false,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false
},
7.sitemap.json配置-发布的时候使
配置小程序及其页面是否允许被微信索引
{
"rules": [{
"action": "allow",
"page": "*"
}]
}
4.页面配置
1.配置项
在app.json中引用则为全局注册,在页面的.json文件中注册则为局部组件
navigtionBarbackgroundColor:导航栏背景颜色
navigatorBarTextStyle white/black 导航栏标题的颜色
navigationStyle 导航栏样式
enablePullDownRefresh:是否开启下拉刷新默认false
onReachBottomDistance (默认number:50)
usingComponent:注册局部组件
注意:每个小程序都需要在app.js中调用App方法注册小程序的实列
App({
onLaunch(option){},//小程序初始完成触发
onShow(options){},//小程序进入前台或者启动运行触发
onHide(){},//小程序从前台转到后台出发
onError(meg){},
golbaldata:'定义一个全局数据'
})
2.页面.js文件
Page({
data: {
text: "This is page data."//定义页面数据
},
onLoad: function(options) {
// 生命周期,监听页面加载,一般一个页面只调用一次
},
onShow: function() {
//生命周期页面展示触发
},
onReady: function() {
//生命周期 监听页面的初次渲染
},
onHide: function() {
// 生命周期监听页面的隐藏.
},
onUnload: function() {
// 生命周期页面关闭或销毁时触发.
},
onPullDownRefresh: function() {
//下拉刷新需要在.json文件中配置.
},
onReachBottom: function() {
// 离窗口底部还有多远触发需要在.json文件中配置.
},
onShareAppMessage: function () {
// 监听用户点击右上角菜单“收藏”按钮的行为,并自定义收藏内容.或者是分享小程序时执行,分享成功时才触发
},
onShareTimeline:function(){//监听分享朋友圈的行为
},
onPageScroll: function() {
// Do something when page scroll
},
onResize: function() {
// Do something when page resize
},
onTabItemTap(item) {
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 自定义函数.
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
}
})
3.页面路由配置
页面路由器对象。可以通过 this.pageRouter
或 this.router
获得当前页面或自定义组件的路由器对象。路由的相对路径:页面路由有 switchTab
, reLaunch
, redirectTo
,navigateTo,
navigateBack;
五个方法,与 wx 对象向同名的五个方法 switchTab, reLaunch, redirectTo ,navigateTo, navigateBack; 功能相同;唯一的区别是,页面路由器中的方法调用时,相对路径永远相对于 this
指代的页面或自定义组件。
如下:实现相同的跳转功能
// index/index.js
Page({
wxNavAction: function () {
wx.navigateTo({
url: './new-page'
})
},
routerNavAction: function () {
this.pageRouter.navigateTo({
url: './new-page'
})
}
})
页面 index/index
的 js 代码如上所示。如果此时已经跳转到了一个新页面 pack/index
,然后才调用到上面的 wxNavAction
方法,跳转的新页面路径将是 pack/new-page
;而如果调用的是 routerNavAction
方法,跳转的新页面路径仍然是 index/new-page
。
换而言之, this.pageRouter
获得的路由器对象具有更好的基路径稳定性。通常情况下,使用 this.pageRouter.navigateTo
代替 wx.navigateTo
是更优的。
this.pageRouter
和 this.router
在页面中将获得同样的页面路由器对象,但如果在自定义组件中调用, this.pageRouter
将相对于自定义组件所在的页面来进行路由跳转,而 this.router
相对于自定义组件自身的路径
5.小程序语法
1.数据绑定
WXML 中的动态数据均来自对应 Page 的 data,数据绑定使用 Mustache 语法(双大括号)将变量包起来。
Page({
data: {
message: 'Hello MINA!',
id:2,
condition:true,
array:[]
}
})
1.简单绑定(需要在双引号之内)
<view> {{ message }} </view>
<view>{{a}}+{{b}}</view>
2.组件之间的属性(需要在双引号之内)
<view id="item-{{id}}"> </view>
3.控制属性(需要在双引号之内)
<view wx:if="{{condition}}"> </view>
4.关键字(需要在双引号之内)
<checkbox checked="{{false}}"> </checkbox>
//特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。运算
5.数组运算
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
6.对象
<template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
//data为template的配置项
2.列表渲染
wx:for渲染列表
<block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
在组件上使用 wx:for
控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index
,数组当前项的变量名默认为 item
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
使用 wx:for-item
可以指定数组当前元素的变量名,使用 wx:for-index
可以指定数组当前下标的变量名。
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
注意:当 wx:for
的值为字符串时,会将字符串解析成字符串数组。花括号和引号之间如果有空格,将最终被解析成为字符串
3.条件渲染
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
<view hidden={{false}}>显示</view>
<view hidden={{true}}>隐藏</view>
hidden
就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。一般来说,wx:if
有更高的切换消耗而 hidden
有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden
更好,如果在运行时条件不大可能改变则 wx:if
较好。
3.事件绑定
在wxml文件中:
<text>{{num}}</text>
<view>{{val}}</view>
<!-- 给小程序的input输入框绑定事件使用bindinput -->
<!-- 其中value:"{{val}}"代表的是val绑定input框的初始内容,实现双向绑定则用:model:value="{{val}}" -->
<!-- 绑定点击事件则用bindtap:"handler",而且不能在函数内直接传参,需要在标签内使用data-自定义名称="param",再在事件处理函数中使用e.currentTarget.dataset.num来换取参数值 -->
输入:<input value="{{val}}" bindinput="input"/>
<button bindtap="add" data-num="{{1}}">val++</button>
<button bindtap="reduce" data-num="{{-1}}">val--</button>
在js文件中:
// pages/study/study.js
Page({
/**
* 页面的初始数据
*/
data: {
num:0,
val:0
},
// 输入框执行函数
input(e){
console.log(e)
this.setData({
num:e.detail.value,
val:e.detail.value
})
},
add(e){
this.setData({
val:this.data.val+=e.currentTarget.dataset.num
})
},
reduce(e){
this.setData({
val:this.data.val+=e.currentTarget.dataset.num
})
}
})
tip:在vscode中编辑微信小程序的less
1.在vscode中打开问微信小程序文件夹,下载easy-less,然后再在vscode的setting.json里面配置
"less.compile":{
"outExt":".wxss"
}
4.常用组件
1.view
类似于div
hover-class属性后跟样式属性,表示按下该元素时的效果
详细属性可去官网
<view hover-class="none" style="flex-direction:row;">
<view class="flex-item demo-text-1"></view>
<view class="flex-item demo-text-2"></view>
<view class="flex-item demo-text-3"></view>
</view>
2.text组件
文本标签,只能嵌套text,添加长按文字可以复制(只有该标签有这个功能),可以对回车 空格进行编码
<text user-select>文本是否可选</text>
3.image
特点:默认width:320px;height:240px;
1.src属性是指定图片的路径
2.mode属性设置图片高宽的适配方式,属性值:scaleToFill默认值,不保持纵横比缩放;aspectFit保持宽高比,确保图片的长边显示出来 页面轮播图常用;aspectFill保持纵横比缩放图片,只保证图片短边能显示出来
3.lazy-load:boolean会自己实现懒加载
<image src="http://..."></image>
4.swiper
特点:默认height:150px;width:100%
轮播图一般显示图片时需要计算swiper的高度=clac(swiper的宽度(750rpx)*原图的宽度/原图的宽度)
swiper和swiper-item必须是同时使用
属性:
indicator-dots | boolean | false | 否 | 是否显示面板指示点 | 1.0.0 | |||||||||||||
indicator-color | color | rgba(0, 0, 0, .3) | 否 | 指示点颜色 | 1.1.0 | |||||||||||||
indicator-active-color | color | #000000 | 否 | 当前选中的指示点颜色 | 1.1.0 | |||||||||||||
autoplay | boolean | false | 否 | 是否自动切换 | 1.0.0 | |||||||||||||
current | number | 0 | 否 | 当前所在滑块的 index | 1.0.0 | |||||||||||||
interval | number | 5000 | 否 | 自动切换时间间隔 | 1.0.0 | |||||||||||||
duration | number | 500 | 否 | 滑动动画时长 | 1.0.0 | |||||||||||||
circular | boolean | false | 否 | 是否采用衔接滑动 | 1.0.0 | |||||||||||||
vertical | boolean | false | 否 | 滑动方向是否为纵向 | 1.0.0 | |||||||||||||
previous-margin | string | "0px" | 否 | 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值 | 1.9.0 | |||||||||||||
next-margin | string | "0px" | 否 | 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值 | 1.9.0 | |||||||||||||
snap-to-edge | boolean | false | 否 | 当 swiper-item 的个数大于等于 2,关闭 circular 并且开启 previous-margin 或 next-margin 的时候,可以指定这个边距是否应用到第一个、最后一个元素 | 2.12.1 | |||||||||||||
display-multiple-items | number | 1 | 否 | 同时显示的滑块数量 | 1.9.0 | |||||||||||||
easing-function | string | "default" | 否 | 指定 swiper 切换缓动动画类型 | 2.6.5 | |||||||||||||
| ||||||||||||||||||
bindchange | eventhandle | 否 | current 改变时会触发 change 事件,event.detail = {current, source} | 1.0.0 | ||||||||||||||
bindtransition | eventhandle | 否 | swiper-item 的位置发生改变时会触发 transition 事件,event.detail = {dx: dx, dy: dy} | 2.4.3 | ||||||||||||||
bindanimationfinish | eventhandle | 否 | 动画结束时会触发 animationfinish 事件,event.detail 同上 | 1 |
<swiper>
<swiper-item></swiper-item>
</swiper>
5.navigator页面导航
利用src属性指定跳转的位置
target要跳转到当前小程序还是其他的小程序页面self默认值表示自己,miniProgramer其他小程序页面
open-type设置跳转的方式navigator(默认值)不能跳到tabbar页面
<view>
<!-- navigate方式可以返回上一页 -->
<navigator open-type="navigate" url="../logs/logs"></navigator>
<!-- redirect不能返回上一页 -->
<navigator open-type="redirect" url="../logs/logs"></navigator>
<!-- reLaunch不能返回上一页,因为之前打开的页面全都关闭了 -->
<navigator open-type="reLaunch" url="../logs/logs"></navigator>
<!-- navigateBack返回上一页,上一页必须是navigate -->
<navigator open-type="navigateBack" url="../logs/logs"></navigator>
</view>
API导航
目标页面如果是tabbar页面
wx.switchTab({
url: 'url',
})
目标页面不是tabbar页面
// 可以返回上一个页面
wx.navigateTo({
url: 'url',
})
// 关闭上一个页面,不可以返回上一个页面
wx.redirectTo({
url: 'url',
})
// 关闭之前所有的历史页面,不可以返回
wx.reLaunch({
url: 'url',
})
导航传参
注意:目标页面是tabbar时,页面是不接收参数的
1.在目标页面路径地址后面通过query即?号拼接字符串
组件传参
<navigator open-type="navigate" url="../logs/logs?query='12'&name='张三'"></navigator>
API传参
wx.navigateTo({
url: '../logs/logs.js?query="121"',
})
接收参数:在目标页面中的生命周期钩子函数onLoad中通过系统参数获取
onLoad(options){
//options对象中包含页面传递的参数
},
6.rich-text富文本标签
可以将html字符串解析为页面结构,通过nodes属性指定渲染的变量
<rich-text nodes="{{html}}"></rich-text>
7.block组件
作用:可以给多视图组件提供一个包裹,并不会渲染到页面结构中,不能使用class,style等属性,但可以使用模板语法
<block wx:for{{ array}}>
<view>{{item}}</view>
</block>
8.icon
作用:渲染小图标 type指定类型,size指定大小
<icon type="success" size="80"></icon>
9.scroll-view
设置横向或者纵向滑块
<scroll-view class="scroll" scroll-y>
<view>12</view>
<view>121</view>
<view>1112</view>
</scroll-view>
<scroll-view class="scrollx" scroll-x>
<view>13</view>
<view>131</view>
<view>1113</view>
</scroll-view>
5.表单组件
1.input输入框
<input type="text" class="input" placeholder="请输入" placeholder-style="padding-left:10rpx;color:orangered" />
2.radio-group,radio单选框
<view>
<!--单选框 color:设置单选框的背景色,默认绿色。disabled:禁用
checked默认勾选 -->
<radio-group bindchange="sexChange">
<radio value="1" color="#c00000" >男</radio>
<radio value="0" color="#c00000" checked >女</radio>
</radio-group>
</view>
3.复选框checkbox-group,checkbox
<view>
<!-- 复选框 color:设置复选框选中的背景色,默认绿色。disabled:禁用
checked默认勾选 -->
<checkbox-group>
<checkbox value="运动">运动</checkbox>
<checkbox value="绘画">绘画</checkbox>
<checkbox value="唱歌">唱歌</checkbox>
<checkbox value="跳舞">跳舞</checkbox>
</checkbox-group>
</view>
4.switch开关选择器
<view>
<!-- 开关选择器 color:设置开关选择器选中的背景色,默认绿色。disabled:禁用
checked默认勾选 -->
<switch color="red"></switch>
</view>
5.form表单和button
<!-- form表单可以联合button来使用提交和重置功能 表单中的组件的值需要添加name属性才能被表单提交事件接收到-->
<form action="" bindsubmit="submit">
<input type="text" class="input" placeholder="请输入" placeholder-style="padding-left:10rpx;color:orangered" />
<view>
<!--单选框 color:设置单选框的背景色,默认绿色。disabled:禁用
checked默认勾选 -->
<radio-group bindchange="sexChange">
<radio value="1" color="#c00000" >男</radio>
<radio value="0" color="#c00000" checked >女</radio>
</radio-group>
</view>
<view>
<!-- 复选框 color:设置复选框选中的背景色,默认绿色。disabled:禁用
checked默认勾选 -->
<checkbox-group>
<checkbox value="运动">运动</checkbox>
<checkbox value="绘画">绘画</checkbox>
<checkbox value="唱歌">唱歌</checkbox>
<checkbox value="跳舞">跳舞</checkbox>
</checkbox-group>
</view>
<button form-type="submit" type="primary" size="mini">提交</button>
<button type="warn" form-type="reset" size="mini">重置</button>
</form>
6.picker选择器组件
<!-- mode:设置选择日期的模式,属性值: date表示日期选择器,time时间选择器,region代表地域选择器。bindchange="handler":时间改变触发
注意:picker组件必须通过bindchange来绑定事件
-->
<picker mode="date">请选择日期</picker>。
<picker mode="time">请选择时间</picker>
<picker mode="region">请选择地区</picker>
<!-- 自定义选择器,range来指定选择器的内容范围,range-key:指定使用数组元素对象中的那一个属性作为选项 -->
<picker mode="selector" range="{{list}}">自定义选择器</picker>
map组件
需要设置map组件的经纬度
longitude:设置中心点的经度,
latitude:中心点的维度
scale:设置地图的缩放级别
rotate:旋转
show-compass:显示指南针
enable-satellite:开启卫星地图
//<map name="" longitude="地图中心点的经度数值型" latitude="地图中心点的维度数值型"></map>
<map longitude="108.941891" latitude="34.332377"></map>
6.模板
将页面中的公共部分提取出来进行复用
1.第一种方式
缺点:不能像模版内部传递数据
定义模板:一般放在templates目录下的.wxml文件
<view class="box">
模板定义公共部分
</view>
引入模板
<!-- 只能引入模板,但不能引入样式文件 样式在页面的wxss中,或者在全局的app.wxss中引入@import "../../template/header/header.wxss";-->
<include src="../../template/header/header" />
2.第二种方式
1.定义一个模板,定义一个后缀名为.wxml的文件,模板必须在template组件的内部,且在内部可以接收wxss样式,以及出递过来的值
<!-- 用name属性标记模板 -->
<template name="header">
<view class="box">
模板定义公共部分
</view>
<view>
<!-- 页面传递过来的值,必须是变量名,且和页面定义的变量一致 -->
页面值第一个{{msg}}+++第二个值是数组{{list}}
</view>
</template>
2.引入模板
<import src="../../template/header/header"></import>
3.使用模板
<!-- 使用模板,此时使用的是is属性 可以多次使用-->
<!-- 利用data来设置传递的参数,且可以用逗号分隔来传递多个参数,参数只能在页面的js文件中定义的变量 -->
<template is="header" data="{{msg,list}}"></template>
<template is="header"></template>
<template is="header"></template>
6.wxss的使用
1.rpx
就是将设备宽度平分为750等份,750rpx就是屏幕的总宽度。且rpx是响应式的,无论设备屏幕多大多小都是750rpx
2.样式引入
@import 'wxss文件路径'
wxss语法和css3大体差不多,但是小程序中没有*{}通配符选择器
7.wxs脚本语法
- wxs就是嵌入到.wxml中的脚本,可以在视图中调用wxs中的方法,对视图中即将渲染的数据进行预处理
- 由于wxml文件中无法调用js中的自定义方法,也无法调用外部js中提供的自定义方法,故提供了wsx来弥补这个遗憾
- wxs中的脚本必须遵循common.js规范
- wxs中不支持ES6新特性
1.第一种使用方式
直接在.wxml文件中添加<wxs></wxs>标签,在标签内部进行编写。
<view>
<!-- 调用wxs中自定义的方法 ,str是js文件中定义的文件-->
{{tools.toUpper(str)}}
</view>
<wxs module="tools">
module.exports={
// 定义方法
toUpper:function(str){
return str.toUpperCase();
}
}
</wxs>
2.第二种方式
在项目根目录中创建一个wxs目录,并创建.wxs文件
在.wxs文件中
module.exports={
toLower:function(num){
return num.toLowerCase()
}
}
在页面的.wxml文件中
<!-- 使用模板 -->
<view>
{{tool.toLower(str)}}
</view>
<!-- 引入外部.wxs文件 -->
<wxs src="../../wxs/tools.wxs" module="tool"></wxs>
8.自定义组件
一般在一个组件功能被多次使用时,使用自定义组件。
1.创建组件,在指定的文件夹下,右击创建component即可
应用组件:在使用的页面文件夹下的.json文件下配置:
"usingComponents": {
"Tabs":"../../component..."
}
若在app.json文件下则注册为全局组件,及所有页面都可以使用
自定义组件属性:
Component({
/**
存放组件的自定义属性列表
*/
//properties和data指向同一个对象,所以this.properties===this.data,该属性下的值可用于父组件向子组件传值,
*/
properties: {
aa:{//设置自定义属性,类型为Strung,value为默认值
type:String,
value:""
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
2.父组件向子组件传值
可使用子组件下的perperties下定义的属性,
Component({
properties: {
getnum:{
type:String,
default:''
}
},
})
父组件中
<Child getnum="{{msg}}">
//msg负组件中定义的变量,getnum是子组件中定义的自定义属性
</Child>
2.子组件向父组件传值
可使用this.triggerEvent("父组件自定义事件的名称","要传递的参数"),父组件自定义事件是要绑定在子组件的标签上的,且在自定义事件名前面加bind组成自定义事件
子组件的.js文件
fun(){
this.setData({
num:this.data.num+1,
bb:this.data.bb+2
})
this.triggerEvent('sendNum',this.data.num)
}
父组件的wxml文件
<MyComponent bindsendNum="handler" aa="{{121}}"></MyComponent>
通过'bind自定义事件名称'绑定自定义事件
<view>子组件向父组件传递的值{{temp}}</view>
父组件的.js文件
methods: {
handler(e){
this.setData({
temp:e.detail
})
}
}
3.自定义组件的监听器,observers
Component({
observers:{
msg(newval){//监听单个值
console.log(newval)
},
'val,num':function(newVal,newNum){//监听多个值
}
}
}
4.插槽
1.默认插槽
在页面组件中
<Child getnum="{{msg}}">
<view>传递的插槽,slot标签在哪里,就显示在那个位置</view>
</Child>
在组件中
<!--components/child/child.wxml-->
<text>接收父组件传递的值:{{getnum}}</text>
<!-- 插槽:接收外部调用者传递的视图结构 -->
<slot></slot>
2.具名插槽-多插槽
需要在组件js文件下开启多插槽功能
Component({
options:{
multipleSlots:true//开启多插槽
}
})
在自定义组件中
<slot name="header"></slot>
<text>接收父组件传递的值:{{getnum}}</text>
<!-- 插槽:接收外部调用者传递的视图结构 -->
<slot name="footer"></slot>
在调用自定义组件的页面中
<Child getnum="{{msg}}">
<view slot="header">header</view>
<view slot="footer">footer</view>
</Child>
六.小程序API
API概述
API(应用程序接口)是一些预先定义好的函数或者接口,目的是为了应用程序与开发人员基于某种软件或硬件得以访问一组例程的能力。小程序开发框架提供丰富的微信原生 API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。详细介绍请参考 API 文档
本地存储
存储数据
采用的json格式的key-value形式存储
// 同步方法
wx.setStorageSync('key', data)
// data为JSON格式
// 异步方法
wx.setStorage({
key:'数据名称',
value:'数据内容JSON格式',
success:res=>{
//成功回调
}
})
// 支持Promise的写法
wx.setStorage({
key:'数据名称',
value:'数据内容JSON格式'
}).then(res=>{
console.log(res)
})
获取数据
// 同步方法
wx.getStorageSync('key')
// data为JSON格式
// 异步方法
wx.setStorage({
key:'数据名称',
success:res=>{
//成功回调
}
})
// 支持Promise的写法
wx.setStorage({
key:'数据名称',
}).then(res=>{
console.log(res)
})
删除数据
// 同步方法
wx.removeStorageSync('key')
// 异步方法、
wx.removeStorage({
key:'数据名称',
success:res=>{
//成功回调
}
})
// Promise写法
wx.removeStorage({
key:'key'
}).then(res=>{
})
清除数据
//同步方法
wx.clearStorageSync()
//异步方法
wx.clearStorage({
success:res=>{
}
})
// 支持promise写法
wx.clearStorage().then(res=>{
})
网络请求
小程序中不存在跨域的概念
小程序对数据接口的要求(正式环境)
- 数据接口服务器必须备案
- 数据接口服务器必须启用https协议
开发阶段
- 在小程序开发者工具中的详情中的本地设置,勾选不校验安全域名
wx.request语法
- 不支持promise写法
get请求
wx.request({
url: 'url',
methods:'GET',//请求方式
header:{
//请求头
},
success:res=>{
// 成功处理函数
},
fail:err=>{
//失败处理函数
}
})
post请求
wx.request({
url: 'url',
methods:'POST',//请求方式
header:{
//请求头
},
success:res=>{
// 成功处理函数
},
fail:err=>{
//失败处理函数
}
})
封装成Promise格式
export default function(options){
const baseUrl="自己服务器域名或ip地址"
if(options.url.slice(0,4)==='http'){
baseUrl=url
}else{
baseUrl+=options.url
}
return new Promise(function(resolve,reject){
wx.request({
url: baseUrl,
methods:options.methods||"GET",
header:options.header||{},
success:resolve,
fail:reject
})
})
}
界面交互
wx.showToast
在页面中显示消息提示框
wx.showToast({
title: '提示内容',
icon:'success',//可选值:success(默认值),none,fail,loading
duration:1500,//持续时间
success:res=>{},//成功回调
fail:res=>{}//失败回调
})
wx.showLoading
不会自动关闭,需要使用wx.hideLoading()
wx.showLoading({
title:"加载中",
success:res=>{}
})
wx.hideLoading({
success:res=>{}
})
wx.setNavigationBarTitle()
设置当前页面标题,一般不会放在onLoad生命周期中
wx.setNavigationBarTitle({
title:"当前页面的标题",
success:res=>{}
})
wx.showModal
一般使用在给用户提示是否确认的提升框
wx.showModal({
title:"提示",
content:"请确认当前操作",
showCancel:true
})
授权API
wx.getSetting检测授权状态
如果某个接口没有授权,需要向用户申请授权否则无法使用
wx.getSetting({
success:res=>{
console.log(res)
}
wx.chooseAddress获取用户地址
wx.chooseAddress({
success: (result) => {
console.log(result)
},
fail:err=>{
console.log(err)
}
})
wx.getUserInfo获取用户信息
wx.getUserInfo({
success: (result) => {
console.log(result)
},
fail:err=>{
console.log(err)
}
})
wx.authorize授权
setAuth(){
wx.getSetting({
withSubscriptions: true,
success:res=>{
if(!res.authSetting['scope.record']){
// 申请授权
wx.authorize({
scope: 'scope.record',
success:res=>{
console.log(res)
wx.startRecord({
success: (result) => {
console.log(result)
},
fail:err=>{
console.log(err)
}
})
}
})
}else{
// 已经拥有此功能可以直接使用
wx.startRecord({
success: (result) => {
console.log(res)
},
})
}
}
})
},
wx.getUserProfile获取用户个人信息
这个API不会重新申请授权,他会自己申请,低版本需要做兼容性处理
wx.getUserProfile({
desc: 'desc',
success:res=>{
console.log(res)
}
})
获取用户手机号
目前该接口针对非个人开发者,且完成了认证的小程序开放
wx.login微信登录
主要获取个人微信的授权码code
在wxml中
<button open-type="getPhoneNumber" bindgetphonenumber="getTelPhone">获取用户手机号码</button>
在js文件中
// 获取用户电话号码
getTelPhone(e){
const {iv,encryptedData}=e.detail
// 1.通过事件对象获取iv(加密向量),encryptedData(手机号加密数据)
console.log(e)
wx.login({
// 2.通过wx.login()获取code凭证码
success:event=>{
const {code}=event
// 使用测试号的信息,个人小程序无法获取用户手机号码
// appid:xsaxwx
// secret:9000uwu
// 3.通过请求后端数据接口精心解密
wx.request({
url: 'http://localhost:3000/v1/getPhone',
methods:"POST",
data:{
appid:'wxdjijdq21',
secret:"900isojxsknxjks",
iv,
encryptedData,
code:code
},
success:res=>{
console.log(res)
}
})
}
})
},