申请开发账号(注册)
安装小程序开发工具(微信开发者工具)
获取小程序的appid:登录微信公众平台-开发-开发设置
页面以单独文件夹存放在pages目录中
每个页个基本文件组成,.js/.wxss/.wxml/.json
//页面的的.json配置文件(覆盖全局配置文件
该文件用来配置小程序页面是否允许被微信索引。
如不被索引可以设置rules->action->disallow
//若需关闭索引提示,可以在project.config.json中的setting中配置字段checkSiteMap为false
//app.json 整个项目的配置 对所有页面生效
app.json({
//页面路径 存在先后顺序
"pages":[
"pages/home/home"
//重点:若需要添加页面,在pages下添加
],
"window":{
/*导航栏区域*/
"navigationBarBackgroundColor": "#ff0000", //导航栏的颜色,默认为#000000(黑色)仅支持十六进制颜色
"navigationBarTextStyle": "white", //导航栏的文字颜色,只支持black(黑色或white(白色),默认为white
"navigationBarTitleText": "小程序 Demo" , //导航栏的标题文本
/*背景区域(默认不可见,下拉才显示*/
"backgroundColor":"#efefef" , //窗口的背景色 十六进制
"backgroundTextStyle":"light" , //下拉loading的样式,仅支持dark/light
"enablePullDownRefresh":false, //是否开启全局下拉刷新 true/false
"onReachBottomDistance":50 //上拉触底事件的距离,单位px
},
"tabBar":{
"list":[ //必填项
{
"pages":"pages/index/index", //页面路径(必填
"text":"index" , //tab文字(必填
"iconPath":"", //未选中时图片路径.
"selectedIconPath":"", //选中时的图片路径
}
],
"position":"bottom" //tabBar位置,仅支持bottom/top
"backgroundColor":"", //背景色 仅支持black/white
"borderStyle":"" , //tabBar上边框的颜色
"color":"" , //tab上文字的默认(未选中)颜色
"selectedColr":"" //tab上的文字选中时的颜色
}
"style":"v2",
"sitemapLocation":"sitemap.json"
})
//页面.json
{
"usingComponents": {},
"navigationBarBackgroundColor": "#ff0000", //导航栏颜色
"navigationBarTextStyle": "black", //导航栏标题颜色
"navigationBarTitleText": "String", //导航栏标题文本
"backgroundColor": "#ffffff", //下拉窗口背景色
"backgroundTextStyle": "dark", //下拉loading的样式,仅支持dark/light
"enablePullDownRefresh": true, //是否开启下拉刷新
"onReachBottomDistance":50 //上拉触底距离
}
WeUI ui框架
类似 行内文本 属性: selectable或 user-select 长按复制
富文本组件 nodes属性 支持把html字符串渲染为wxml结构
例如:
类似 块标签
滚动组件
图片标签 类似 默认宽约300px 高度约240px
属性: mode aspectFill 等比 只保证短边完全显示
aspectFilt 等比 只保证长边完全显示
widthFix 等比 高度自适应
heightFix 等比 宽度自适应
轮播组件
属性:indicator-dots boolean 是否显示轮播点
autoplay boolean 自动轮播
indicator-color color 指示点颜色
interval number 自动轮播时间间隔
circular boolean 是否采用衔接滑动
子组件
属性:type primary/warn
size mini
plain 镂空
4.wxss样式
WXSS 样式 app.wxss 全局样式 局部页面的.wxss仅对当前页面生效
height:100% 屏幕高度
width:750rpx 屏幕宽度 (rpx单位 小程序的适配 今后直接用rpx书写)
建议采用flex布局 display:flex;
支持部分css选择器
.class和#id
element
并集选择器和后代选择器
::after和::before伪类选择器
@import 可以用于导入样式文件
比如在根目录下创建common文件夹中创建common.wxss
@import '/common/common.wxss';
5.小程序js
MVVM模式
//{{}} 插值表达式 类似vue
全局数据
//app.js中
App({
globaData:{ //全局数据属性 页面可以共享
now:(new Date()).toLocaleString()
}
})
用法:
//在页面.js中
1.const app = getApp() //用于页面获取App实例对象
2.Page({
data:{
now:app.gobalData.now //拿到全局配置对象的globalData属性
}
})
//普通的.js文件
例如utils中的,用来封装公共的方法
6.API
1.时间监听API 以on开头,例如wx.onWindowResize监听窗口尺寸变化
2.同步API 特点:① 以Sync结尾的API
② 同步API的执行结果,可以通过函数返回值直接获取,如果出错报异常
3.异步API
例如: wx.requset() 网络请求 通过success回调接收数据
7.WXS
(主要用于小程序过滤器,配合Mustache语法使用)
例如 :{{m1.toUpper(username)}}
类似javaScript 单独的语言
1.有自己的数据类型:
number 数值类型 string 字符串 boolean 布尔值
object 对象类型 function 函数类型 arrary数组 date 日期类型 regexp正则
2.不支持类似ES6及以上的语法形式
不支持let const 解构赋值 展开运算符 箭头函数 对象属性简写 ...
3.遵循CommonJs规范
module对象
require()函数
module.exports对象
1.内嵌式wxs脚本 类似js代码可以写在html中的
{{m1.toUpper(username)}}
module.exports.toUpper=function(str){
return str.toUpperCase(str)
}
2.外联wxs脚本
function toLower(str){
return str.toLowerCase()
}
module.exports={
toLower:toLower
}
-----------------------------------
{{m2.toLower(country)}}
8.实际使用
1.动态绑定属性
Page({
data:{
imgSrc:"http://xxxxxxx.png"
}
})
<image src="{{imgSrc}}">image>
2.事件绑定
常用事件
类型 绑定方式
tap bindtap或bind:tap 手指触摸后马上离开
input bindinput或bind:input 文本框的输入事件
change bindchange或bind:change 状态改变时触发
//当事件回调,收到一个event对象,主要有target和detail
3.修改数据
Page({
data:{
count:1
},
//修改count的值
changeCount(){
//修改需要使用this.setData()
this.setData({
count:this.data.count+1
})
}
})
4.事件传参
事件传参需要通过data-*="{{xx}}" 来定义 *为参数的名字 xx为值
info会被解析为参数的名字
数值2会被解析为参数的值
btnHandler(e){
//通过 dataset 可以访问到具体参数的值
console.log(e.target.dataset.info)
}
5.条件渲染
1.wx:if(类似vue中的v-if 动态创建元素)
<view wx:if="{{type===1}}">男view>
<view wx:elif="{{type===2}}">女view>
<view wx:else>保密view>
可以配合block标签做多个组件展示与隐藏(block标签只起到包裹作用)
<block wx:if="{{true}}">
<view>view1view>
<view>view2view>
block>
2.hidden(类似vue中的v-show 动态切换样式 适合频繁切换使用)
<view hidden="{{flag}}">条件为true隐藏元素,否则显示view>
6.列表渲染
1.wx:for 默认情况下,当前循环项索引用index表示,当前循环项用item表示
<view wx:for="{{arr1}}">
索引是{{index}},item是{{item}}
view>
手动修改索引名称与当前项名称(了解即可
<view wx:for="{{arr1}}" wx:for-index="i" wx:for-item="itemName">
索引是{{i}},item是{{itemName}}
view>
2wx:key(类似vue中的:key
<view wx:for="{{userList}}" wx:key="id">
{{item.name}}
view>
7.tabBar使用
//app.json中使用
{
"pages": [
//tabBar页面必须放到最前面
"pages/home/home",
"pages/message/message",
"pages/set/set",
"pages/index/index",
],
"tabBar": {
"selectedColr":"#2b4b6b" , //被选中得tab文本颜色
"list": [{
"pagePath": "pages/home/home", //必填 页面路径
"text": "home", //必填 tab名称
"iconPath": "/images/icon/home.png", //默认状态下得图标
"selectedIconPath": "/images/icon/active.png" //被选中时图标
},
{
"pagePath": "pages/message/message",
"text": "message",
"iconPath": "/images/icon/message.png",
"selectedIconPath": "/images/icon/active.png"
},
{
"pagePath": "pages/set/set",
"text": "set",
"iconPath": "/images/icon/set.png",
"selectedIconPath": "/images/icon/active.png"
}
],
"backgroundColor": "#fff"
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents"
}
8.网络接口请求
注意:
只能请求HTTPS类型接口
必须将接口域名添加到信任列表中
配置域名:
微信公众平台-开发管理-开发设置-配置域名
发起请求
wx.request({
url:"",
method:"GET",
data:{
name:'zs',
age:23
},
success:(res)=>{
console.log(res)
}
})
------------------------------
跳过request合法域名校验
在小程序开噶工具-详情-本地设置-勾选不校验合法域名
9.页面导航
1.声明式导航 传参:通过query路径拼接方式
导航到tabBar页面
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面navigator>
utl:跳转地址 必须以/开头
open-type:跳转方式 必须switchTab
导航到非tabBar页面
<navigator url="/pages/info/info" open-type="navigate">导航到info页面navigator>
utl:跳转地址 必须以/开头
open-type:跳转方式 必须navigate 该属性可以省略
后退导航
<navigator open-type="navigateBack">后退navigator>
open-type 属性值: navigateBack
delta number 后退层级 默认值为1
2.编程式导航 传参通过query路径拼接
<button bindtap="gotoMessage">跳转到消息页面button>
跳转到tabBar页面
gotoMessage(){
wx.switchTab({
url:"/pages/message/message"
})
}
跳转到非tabBar页面
gotoMessage(){
wx.navigateTo({
url:"/pages/message/message"
})
}
后退导航
<button bindtap="goBack">跳转到消息页面button>
goBack(){
wx.navigateBack({
detail:1 //默认值为1 number
})
}
在页面的onLoad事件中可以获取传递的参数
onLoad:function(options){
//options 就是传递过来的参数
console.log(options)
this.setData({
query:options
})//赋值到data中供页面使用
}
10.下拉刷新事件
全局开启下拉刷新
app.json中的window节点,将 "enablePullDownRefresh": true
局部开启下拉刷新(推荐)
页面.json中开启
"enablePullDownRefresh": true
"backgroundColor": "#ffffff", //下拉窗口背景色
"backgroundTextStyle": "dark", //下拉loading的样式,仅支持
//监听下拉刷新事件
onPullDownRefresh: function () {
//手动关闭下拉刷新
wx.stopPullDownRefresh()
},
11.上拉触底
一般用于加载更多数据(分页)
页面.json配置中 通过onReachBottomDistance属性可以配置上拉触底距离
//监听上拉触底
onReachBottom: function () {
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] //赋值
})
}
})
},
节流处理:
12.提示框
wx.showLoading({title:'数据加载中...'}) //展示loading
wx.hideLoading() //隐藏loading
示例:
getColors(){
//展示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 无论成功还是失败都会执行得回调
complete:()=>{
wx.hideLoading() //隐藏loading
}
})
}
13.自定义编译模式
点击小程序开发工具上方的编译左侧,添加编译模式
14.生命周期
分为两类
1.应用生命周期(小程序从启动->运行->销毁的过程)
应用生命周期函数
//在app.js中
App({
//小程序初始化完成时,全局只触发一次
onLaunch:function(options){},
//小程序启动,或从后台进入前台显示时触发
onShow:function(options){},
//小程序从前台进入后台时触发
onHide:function(){},
})
2.页面生命周期(页面的加载->渲染->销毁的过程)
页面生命周期函数
//在页面的.js中
Page({
onLoad:function(options){}, //监听页面加载,一个页面只调用一次
onShow:function(){}, //监听页面显示
onReady:function(){}, //监听页面初次渲染完成,一个页面只调用一次
onHide:function(){}, //监听页面隐藏
onUnload:function(){}, //监听页面卸载,一个页面只调用一次
})
15.动态设置页面标题、背景色
//动态配置标题
wx.setNavigationBarTitle({
title: this.data.query.title //获取传递的参数
})
16.自定义组件
1.创建与引用自定义组件
//1.创建
根目录下创建components文件夹,在componets文件夹下创建单独文件夹作为子组件,右击新建components命名
//2.引用组件
局部引用组件
在页面的.json文件夹中,引入组件
{
"usingComponents":{
"my-test1":"/components/test1/test1"
}
}
在页面的.wxml文件中,使用组件
<my-test1><my-test1>
------------------------------
全局引用组件
//在app.json文件中引入组件
{
"usingComponents":{
"my-test2":"/components/test2/test2"
}
}
在页面的.wxml文件中使用组件
<my-test2><my-test2>
2.修改样式隔离选项
//在组件的.js中新增如下配置
Components({
options:{
stylesolation:'isolated', // 启用样式隔离 默认值
//apply-shared 页面样式影响组件,组件不影响页面
//shared 组件和页面互相影响
}
})
//或在组件的.json文件中新增如下配置
{
"stylesolation":"isolated"
}
3.properties属性(类似vue中的props)
Componets({
properties: {
//第一种 简化方式
// max: Number
//第二种 完整定义方式
max:{
type:Number,
value:10
}
},
})
<my-test max="10"><my-test>
//注:properties与data全等
4.数据监听器
Components({
observers:{
'字段A,字段B':function(字段A的新值,字段B的新值){
//do something
}
})
//监听对象
observers:{
//监听对象某个属性
'rgb.r,rgb.g,rgb.b': function (r,g,b) {
this.setData({
fullColor: `${r},${g},${b}`
})
},
//**通配符可以监听对象的所有属性
'rgb.**': function (rgb) {
this.setData({
fullColor: `${rgb.r},${rgb.g},${rgb.b}`
})
}
}
5.纯数据字段(可以提升性能
Components:({
options:{
//指定所有_开头的数据字段为纯数据字段
pureDataPattern:/^_/
},
data:{
a:true, //普通数据字段
_a:true //纯数据字段
}
})
6.组件的生命周期
created //组件实例刚被创建时执行
attached //组件实例进入页面节点树时执行
ready //组件视图布局完成后执行
moved //组件实例被移动到节点树另一个位置时执行
detached //组件实例被从页面节点树移除时执行
error //组件方法抛出错误时执行
建议写在lifetimes对象中(优先级最高)
7.组件所在页面的生命周期
Component({
//需要定义在pageLifetimes节点中
pageLifetimes:{
show:function(){}, //页面被展示触发
hide:function(){}, //页面被隐藏触发
resize:function(size){} //页面尺寸变化触发
}
})
8.插槽
1.单个插槽
<view>
<view>这里是组件的内部view>
<slot>slot>
view>
<my-test3>
<view>这里是插槽填充内容view>
my-test3>
2.多个插槽
//在自定义组件的.js中
Component({
options:{
multipleSlots:true //启用多个插槽
},
)}
//自定义组件
<view>
<view>这里是组件的内部view>
<slot name="before">slot>
<slot name="after">slot>
view>
//组件的使用者
<my-test3>
<view slot="before">这里是插槽填充内容beforeview>
<view slot="after">这里是插槽填充内容afterview>
my-test3>
9.组件通信
1.父子传值
Component({
properties: {
count: Number
},
)}
2.子组件触发父组件自定义事件
//父组件.js中
Page({
data: {
count: 0
},
syncCount(e){
this.setData({
count:e.detail.value //通过e.detail获取到子组件传过来的数据
})
},
})
//父组件wxml中
<my-test4 count="{{count}}" bind:sync="syncCount"></my-test4>
// components/test4/test4.js
Component({
properties: {
//j
count:{
type:Number,
value:5
}
},
methods: {
addCount(){
this.setData({
count:this.properties.count+1
})
//触发父组件的自定义事件,传参 this.triggerEvent('自定义事件',{/*参数对象*/})
this.triggerEvent('sync',{value:this.properties.count})
}
}
})
3.获取组件实例(类似vue的ref
//父组件html中
//class或者id选择器
//父组件.js中
Page({
getChild(){
//可以通过this.selectComponent('id或class选择器')获取到子组件
const child=this.selectComponent('.customA')
// child.setData({
// count:child.properties.count+1
// })
child.addCount() //调用子组件得事件
},
})
10.behaviors (类似vue中得mixins)
//每个behavior可以包含一组属性、数据、生命周期函数和方法。组件引用时,他的属性、数据和方法会被合并到组件中。
//1.根目录中创建behaviors文件夹/my-behavior.js
//module.exports将behavior实例对象共享出去
module.exports=Behavior({
//属性节点
properties:{},
//私有数据节点
data:{username:'zs'},
methods:{},
//其他节点...
})
//2.导入并使用behavior
const myBehavior=require("../../behaviors/my-behavior")
Components({
//3.将导入得behavior实例对象 挂载到behaviors数组节点中 即可生效
behaviors:[myBehavior],
})
//总结:
同名字段得覆盖和组合规则:
data:如果是对象类型,进行合并
其余情况组件 > 父behavior > 子behavior
11. npm
//限制:
1.不支持依赖于Node.js内置库的包
2.不支持依赖于浏览器内置对象的包
3.不支持依赖于C++插件的包
vant Weapp 小程序ui库(有赞)
//步骤:
npm init -y
npm i @vant/weapp -S --production
将 app.json 中的"style": "v2"删除
开发者工具右侧详情--->本地--->npm模块勾选
project.config.json中
{
...
"setting": {
...
"packNpmManually": true, //构建npm出问题可以改为false,将下方的删除重新构建npm
"packNpmRelationList": [
{
"packageJsonPath": "./package.json",
"miniprogramNpmDistDir": "./miniprogram/"
}
]
}
}
12.css变量
html{
--color:red; /*--变量名定义一个css变量*/
}
div{
color:var(--color) /*通过var()使用该变量 */
}
/*
在app.wxss中定义全局css变量
例如:对使用vant Weapp定制全局主题样式
page{
--button-danger-background-color:#c00000;
--button-danger-border-color:#d600000;
}
*/
13. API Promise化
//解决回调地狱问题
1.安装插件
cnpm i --save miniprogram-api-promise@1.0.4
2.在小程序入口app.js中,只需调用一次promisifyAll()方法 即可实现API的Promise化
import {promisifyAll} from 'miniprogram-api-promise'
const wxp=wx.p={}
//promisify all wx's api
promisifyAll(wx,wxp)
//调用接口
//微信开发者工具中-->本地设置-->增强编译(否则会报微信小程序 ReferenceError: regeneratorRuntime is not defined)
async getUserInfo() {
try{
const {data: res} = await wx.p.request({
method: 'GET',
url: 'https://www.escook.cn/api/get',
data: {
name: 'zs',
age: 20
}
})
console.log(res)
}catch(e){
console.log(e)
}
14. Mobx数据共享(类似vuex)
//1.安装 mobx-miniprogram 和 mobx-miniprogram-bindings
npm install --save mobx-miniprogram mobx-miniprogram-bindings
//2.创建Mobx Store
根目中创建store文件夹->创建store.js
//在这个JS文件中,专门用来创建Store的实例对象
import {observable,action} from 'mobx-miniprogram'
export const store = observable({
//数据字段
numA: 1,
numB: 2,
//计算属性(需要加get)
get sum() {
return this.numA + this.numB
},
//actions 方法,用来修改store中的数据
updateNum1: action(function (step) {
this.numA += step
}),
})
//3.1页面使用
//页面的.wxml结构
{{numA}}+{{numB}}={{sum}}
//data-参数="{{值}}" 传参
//页面的.js中
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Page({
//页面
bindHandler(e){
this.updateNum1(Number(e.target.step))//调用actions方法
},
onLoad:function(){ //生命周期-监听页面加载
this.storeBindings=createStoreBindings(this,{
store,
fields:['numA','numB','sum'],//按需取需要的字段
actions:['updateNum1']//按需取actions方法
})
},
onUnload: function () {//生命周期-监听页面写在
this.storeBindings.destroyStoreBindings() //调用方法卸载
},
})
//3.2自定义组件调用
//组件的.wxml中
{{numA}}+{{numB}}={{sum}}
//data-参数="{{值}}" 传参
//组件的.js中
import {storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import{store} from '../../store/store'
Component({
behaviors:[storeBindingsBehavior],//通过storeBindingsBehavior实现自动绑定
storeBindings:{
store, //指定要绑定的store
fileds:{//指定要绑定的字段数据
numA:()=>store.numA, //绑定字段的第1种方式
numB:(store)=>store.numB, //绑定字段的第2种方式
sum:'sum', //绑定字段的第3种方式
},
actions:{//指定要绑定的方法
updateNum2:'updateNum2'
}
},
methods: {
//调用方法
bindHandler(e){
this.updateNum2(Number(e.target.dataset.step))
}
}
})
9.常用事件
小程序的[常见事件](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html)有下面这些。
tap:触摸后马上离开。
longpress:触摸后,超过 350ms 再离开。如果指定了该事件的回调函数并触发了该事件, tap事件将不被触发。
touchstart:触摸开始。
touchmove:触摸后移动。
touchcancel:触摸动作被打断,如来电提醒,弹窗等。
touchend:触摸结束。
10.踩坑
1.小程序页面栈最多10层
2.require的路径不支持绝对路径
//解决:在App绑定require,Page里获取app,直接app.require引入
3.小程序中使用web-view打开pdf,iOS可以正常打开,Andriod打开位空白
//解决:使用wx.downloadFile和wx.openDoucment
wx.downloadFile({
url: 'https://.../XXX.pdf', //要预览的 PDF 的地址
success: function (res) {
if (res.statusCode === 200) { //成功
var Path = res.tempFilePath //返回的文件临时地址,用于后面打开本地预览所用
wx.openDocument({
fileType: 'pdf', // 文件类型
filePath: Path, //要打开的文件路径
success: function (res) {
console.log('打开 PDF 成功');
}
})
}
},
fail: function (err) {
console.log(err); //失败
}
})
常用的库
miniprogram-api-promise 扩展小程序api支持promise
安装:npm install --save miniprogram-api-promise
使用:在小程序入口(app.js)调用一次promisifyAll,只需要调用一次。 示例:
import { promisifyAll, promisify } from 'miniprogram-api-promise';
const wxp = {}
// promisify all wx's api
promisifyAll(wx, wxp)
// 使用
wxp.login().then(res => {
// do something
})
wx-promise-pro扩展小程序api支持promise
安装:npm i wx-promise-pro -S
使用:在小程序入口(app.js)调用一次promisifyAll,只需要调用一次。 示例:
import { promisifyAll, promisify } from 'wx-promise-pro'
// promisify all wx‘s api
promisifyAll()
// 使用
wxp.login().then(res => {
// do something
})