1.小程序项目的基本组成结构
pages存放所有小程序页面
utils存放工具性质的模块(例如:格式化时间的自定义模块)
app.js小程序项目的入口文件
app.json小程序项目的全局配置文件
app.wxss小程序项目的全局样式文件
project.config.json项目的配置文件
sitemap.json配置小程序及其页面是否允许被微信索引
1.页面
小程序页面放入pages目录中,以单独的文件夹存在
.js 页面脚本文件,存放页面的数据、事件处理函数
.json 页面的配置文件,配置窗口的外观、表现
.wxml 页面的模板结构文件
.wxss 页面的样式表文件
2.JSON配置文件
JSON是一种数据格式,总是以配置文件的形式出现
app.json
pages:记录当前小程序所有页面的路径
window:全局定义小程序所有页面的背景色,文字颜色
style:全局定义小程序组件所使用的样式版本
sitemapLocation:用来指明sitemap.json的位置
project.config.json
记录我们对小程序开发工具所做的个性化配置
setting 编译相关的配置
projectname 项目名称
appid 小程序的账号ID
sitemap.json
配置小程序是否允许微信索引
用户的搜索关键字和页面的索引匹配成功的时候,小程序的页面将可能展示在搜索结果中
页面的.json配置文件
页面中的配置项会覆盖app.json的window中相同的配置项
新建小程序页面
在app.json->pages中新增页面的存放路径
修改项目首页
调整app.json->pages数组中页面路径的先后顺序,小程序会将排在第一的页面当成首页进行渲染
3.WXML模板
小程序框架设计的一套标签语言,用来构建小程序页面的结构,类似HTML
4.WXSS样式
用于描述WXML的组件样式,类似网页开发中的CSS
5..js文件
处理用户的操作
2.组件
1.view
类似HTML中的div,普通视图区域
2.scroll-view
可滚动的视图区域
wxml
<!--pages/list/list.wxml-->
<scroll-view class="container1" scroll-y>
<view>
A
</view>
<view>
B
</view>
<view>
C
</view>
</scroll-view>
wxss
/* pages/list/list.wxss */
.container1 view{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
}
.container1 view:nth-child(1){
background-color:lightgreen;
}
.container1 view:nth-child(2){
background-color: lightskyblue;
}
.container1 view:nth-child(3){
background-color: lightpink;
}
.container1{
border: 1px solid red;
width: 100px;
height: 120px;
}
3.swiper
轮播图容器组件
wxml
<!--pages/list/list.wxml-->
<swiper class="swiper-container" indicator-dots indicator-color="white" indicator-active-color="gray" autoplay interval="3000" circular>
<swiper-item>
<view class="item">
A
</view>
</swiper-item>
<swiper-item>
<view class="item">
B
</view>
</swiper-item>
<swiper-item>
<view class="item">
C
</view>
</swiper-item>
</swiper>
wxss
/* pages/list/list.wxss */
.swiper-container{
height: 150px;
}
.item{
height: 100%;
line-height: 150px;
text-align: center;
}
swiper-item:nth-child(1) .item{
background-color: lightgreen;
}
swiper-item:nth-child(2) .item{
background-color: lightblue;
}
swiper-item:nth-child(3) .item{
background-color: lightpink;
}
4.text
文本组件,类似于HTML中的span标签,是一个行内元素
text组件的user-select="true"属性,实现文本长按选中
rich-text:富文本组件,支持把HTML字符渲染为WXML结构
<view>
lajfoasj<text user-select="true">12344566</text>
</view>
<rich-text nodes="<h1 style='color:red;'>标题</h1>"></rich-text>
5.button
通过open-type属性可以调用微信提供的功能(客服、转发、获取用户授权、获取用户信息)
<!-- 通过type属性指定按钮颜色类型 -->
<button>普通按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<!-- size="mini"小尺寸按钮 -->
<button size="mini">普通按钮</button>
<button type="primary" size="mini">主色调按钮</button>
<button type="warn" size="mini">警告按钮</button>
<!-- plain镂空按钮(无背景色,有边框线) -->
<button size="mini" plain>普通按钮</button>
<button type="primary" size="mini" plain>主色调按钮</button>
<button type="warn" size="mini" plain>警告按钮</button>
6.image
图片组件
7.navigator
页面导航组件,类似HTML中的a链接
3.API
4.模板与配置
1.数据绑定
在页面对应的 .js文件中,把数据定义到data对象中
用插值表达式{{}}将data中数据绑定到页面渲染
<view>
{{info}}
</view>
<image src="{{imsrc}}"></image>
<view>
{{randomNum1 >=5?'数字大于或等于5':'数字小于5'}}
</view>
data: {
info:'hello world',
imsrc:'',
randomNum1:Math.random()*10
},
2.事件绑定
事件是渲染层到逻辑层的通讯方式
1.常用事件
2.事件对象的属性
3.target和currentTarget的区别
4.bindtap的语法格式
tap事件响应用户的触摸行为,类似HTML中onclick鼠标点击
通过bindtap绑定触摸事件,后面为事件名
<button type="primary" bindtap="btn">按钮</button>
.js定义事件对应处理函数
// 定义按钮的事件处理函数
btn(e){
console.log(e)
},
5.事件处理函数中为data的数据赋值
this.setData(dataObjecet)方法
btn1(){
this.setData({
count:this.data.count+1
})
},
6.事件传参
为组件提供data-*传参,*代表参数名
<button type="primary" bindtap="btn1" data-info="{{2}}">事件传参</button>
info被解析成参数的名字,数值2解析为参数的值
event.target.dataset.参数名获取到具体参数的值
btn2(e){
this.setData({
count:this.data.count+e.target.dataset.info
})
},
7.bindinput语法格式
bindinput为文本框绑定输入事件
<input bindinput="input1"></input>
input1(e){
console.log(e.detail.value)
},
8.文本框和data之间的数据同步
定义数据
Page({
/**
* 页面的初始数据
*/
data: {
msg:'你好',
},
渲染结构
<input value="{{msg}}"bindinput="input1"></input>
美化样式
input{
border: 10px black;
margin: 5px;
padding: 5px;
border-radius: 3px;
}
绑定input事件处理函数
input1(e){
console.log(e.detail.value)
this.setData({
msg:e.detail.value
})
},
3.条件渲染
1.wx:if
wx:elif
wx:else
<view wx:if="{{type === 1}}">
男
</view>
<view wx:elif="{{type === 2}}">
女
</view>
<view wx:else>
保密
</view>
2.结合<block>使用wx:if
一次性控制多个组件的展示与隐藏,只是一个包裹性质的容器,不会在页面起渲染
<block wx:if="{{true}}">
<view>view1</view>
<view>view2</view>
</block>
3.hidden
<view hidden="{{flag}}">
隐藏
</view>
4.列表渲染
索引用index,循环项用item
<view wx:for="{{arr1}}">
索引是:{{index}},item项是:{{item}}
</view>
wx:for-index可以指定索引的变量名
wx:for-itm可以指定当前项变量名
<view wx:for="{{arr1}}" wx:for-index="idx" wx:for-item="itemName"></view>
wx:key的使用
提高渲染效率
userList:[
{id:1,name:'sf'},
{id:2,name:'dgdg'},
{id:3,name:'fnu'}
]
<view wx:for="{{userList}}" wx:key="id">{{item.name}}</view>
5.wxss
rpx把所有设备的屏幕,在宽度上等分为750份,即当前屏幕的总宽度为750rpx
@import后跟需要导入的外联样式表的相对路径,用;表示结束
@import "common.wxss";
全局样式:app.wxss
局部样式:页面.wxss
局部和全局样式冲突时,局部样式会覆盖全局样式
6.全局配置
app.json中
常用配置:
1.pages 小程序所有页面的存放路径
2.window 全局设置小程序窗口的外观
3.tabBar 小程序底部的tabBar效果
4.style 是否使用新版的组件样式
window
导航栏标题:app.json->window->navigationBarTitleText
导航栏背景色:app.json->window->navigationBarBackgroundColor(只支持#开头十六进制的颜色)
导航栏标题颜色:app.json->window->navigationBarTextStyle(只有black和white可选)
开启下拉刷新:app.json->window->enablePullDownRefresh设为true
下拉刷新时窗口的背景色:app.json->window->backgroundColor(只能十六进制颜色)
下拉刷新时loading的样式:app.json->window->backgroundTextStyle(light和dark)
设置上拉触底的距离:例如向下滑,滚动条距离底部还有多少距离自动刷新下面的页面
app.json->window->onReachBottomDistance(默认为50px)
tabBar
tabBar的页面必须放在pages中前部分
用于实现多页面的快速切换
顶部和底部tabBar
tabBar只能配置最少2个,最多5个tab标签
渲染顶部tabBar时,不显示icon,只显示文本
标红必须有
"pages":[
"pages/home/home",
"pages/message/message",
"pages/contact/contact",
"pages/list/list",
"pages/index/index",
"pages/logs/logs"
]
"tabBar": {
"list": [{
"pagePath": "pages/home/home",
"text": "home",
"iconPath": "/images/home.png",
"selectedIconPath": "/images/home-active.png"
},
{
"pagePath": "pages/message/message",
"text": "message",
"iconPath": "/images/message.png",
"selectedIconPath": "/images/message-active.png"
},
{
"pagePath": "pages/contact/contact",
"text": "contact",
"iconPath": "/images/contact.png",
"selectedIconPath": "/images/contact-active.png"
}]
}
7.页面配置
页面.json
{
"usingComponents": {},
"navigationBarBackgroundColor": "#ff0000",
"navigationBarTextStyle": "black"
}
8.数据请求
1.网络请求的限制
1.只能请求HTTPS类型的接口
2.必须将接口的域名添加到信任列表中
2.配置request合法域名
微信小程序管理后台->开发->开发设置->服务器域名->修改request合法域名
3.发起GET请求
wx.request()
// 发起GET请求
getInfo(){
wx.request({
url: 'https://www.escook.cn/api/get',
method:'GET',
data:{
name:'lb',
age:20
},
//成功之后的回调函数
success:(res)=>{
console.log(res.data)
}
})
},
4.发起POST请求
//发起POST请求
postInfo(){
wx.request({
url: 'https://www.escook.cn/api/post',
method:"POST",
data:{
name:'lbb',
name:3
},
success:(res)=>{
console.log(res.data)
}
})
},
5.在页面刚加载时请求数据
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getInfo()
this.postInfo()
},
6.跳过request合法域名校验
仅限于在开发与测试阶段使用
5.视图与逻辑
1.页面导航
1.声明式导航
1.导航到(配置)tabBar页面
<navigator>组件
url:必须以/开头
open-type:跳转方式 必须为switchTab
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator>
2.导航到非tabBar页面
url:必须以/开头
open-type:跳转方式 必须为navigate
导航到非tabBar页面时,open-type="navigator"属性可以省略
<navigator url="/pages/info/info" open-type="navigate">导航到info页面</navigator>
3.后退导航
open-type:跳转方式 必须为navigateBack
delta必须是数字,表示要后退的层级
delta可以不写,默认值为1
<navigator open-type="navigateBack" delta="1">后退</navigator>
2.编程式导航
1.导航到tabBar页面
调用wx.switchTab(Object object)方法,Object参数对象属性列表如下
<button bindtap="gotoMessage">跳转到message页面</button>
gotoMessage(){
wx.switchTab({
url: '/pages/message/message',
})
},
2.导航到非tabBar页面
调用wx.navigateTo(Object object)方法,Object参数对象属性列表如下
<button bindtap="gotoInfo">跳转到info页面</button>
gotoInfo(){
wx.navigateTo({
url: '/pages/info/info',
})
},
3.后退导航
调用wx.navigateBack(Object object)方法,Object参数对象属性列表如下
<button bindtap="gotoBack">后退</button>
gotoBack(){
wx.navigateBack()
},
3.导航传参
路径后面携带参数
1.声明式导航传参
参数与路径之间使用?分隔
参数见与参数值用=相连
不同参数用&分隔
<navigator url="/pages/info/info?name=zs&age=20">跳转到info带参</navigator>
2.编程式导航传参
<button bindtap="getInfo2">跳转到info带参2</button>
getInfo2(){
wx.navigateTo({
url: '/pages/info/info?name=ls&gender=男',
})
},
3.在onLoad中接收导航参数
通过声明式传参或编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取
onLoad(options) {
console.log(options)
this.setData({
query:options
})
},
获取之后再传入data中
2.页面事件
1.下拉刷新
在页面的.json配置文件中,将enablePullDownRefresh设置为true
下拉背景颜色和格式上面讲过
.js文件中,通过onPullDownRefresh()函数监听当前页面下拉刷新事件
onPullDownRefresh() {
console.log('触发下拉刷新')
this.setData({
count:1
})
},
下拉刷新自动关闭:wx.stopPullDownRefresh()
2.上拉触底
滑倒一定程度,加载更多数据
.js中,onReachBottom()函数监听
onReachBottom() {
console.log('触发上拉触底事件')
},
.json中,onReachBottomDistance属性配置触发上拉触底事件时,滚动条距底部距离,默认为50px
添加loading效果
//展示loading效果
wx.showLoading({
title: '数据加载中...'
})
complete:()=>{
//隐藏loading效果
wx.hideLoading()
}
节流处理
3.生命周期
生命周期函数会自动按次序执行
小程序的应用生命周期函数App({})在app.js中声明
页面生命周期函数Page({}),页面的.js文件
4.WXS脚本
WeiXin Script 脚本语言
更多被当作过滤器进行使用
内嵌wxs脚本
编写在wxml文件中的<wxs>标签内,每个<wxs>标签,必须提供module属性,指定当前wxs模块名称
<view>{{m1.toUpper(username)}}</view>
<wxs module="m1">
module.exports.toUpper=function(str){
return str.toUpperCase()
}
</wxs>
外联wxs脚本
可以编写在以.wxs为后缀名的文件内
在utils中定义.wxs
function toLower1(str){
return str.toLowerCase()
}
//向外共享成员
module.exports={
toLower:toLower1
}
使用外联wxs脚本
为<wxs>添加module和src属性
module:模块名称 src:脚本路径(必须相对路径)
6.自定义组件
1.创建和使用
创建组件
局部引用
只能在当前被引用的页面内使用
页面的.json文件中引用组件
键值对 名字:路径
.json
"usingComponents": {
"my-test1":"/components/test/test"
}
.wxml
<my-test1></my-test1>
全局引用
每个小程序页面可使用
app.json
2.样式
组件样式隔离
自定义组件的样式支队当前组件生效
app.wxss中的全局样式对组件无效
只有class选择起会有样式隔离效果,所以一般都使用class
修改组件样式隔离
有时希望外界可以控制组件内部
.js文件中
Component({
options:{
styleIsolation:'isolated'
},
isolated:启用样式隔离 apply-shared:页面wxss样式影响自定义组件
shared:互相影响
3.数据、方法和属性
properties属性(组件的对外属性,用来接收外界传递到组件中的数据)
.js文件
properties: {
//第一种:简化方式
//max:Number
//第二种:完整的定义方式
max:{
type:Number,
value:10 //默认值为10
}
},
.wxml 可以进行赋初值
<my-test1 max="9"></my-test1>
小程序组件中,properties属性和data数据本质用法相同,没有区别,它们都是可读可写的
但人为规定他们使用在如下方面
data:存储组建的私有数据
properties:存储外界传递到组件中的数据
4.自定义组件的数据监听器
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作
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
})
}
}
可以使用通配符**来监听对象中所有属性的变化
有个RGB例子
自定义组件的纯数据字段:不用于页面渲染的data字段
5.自定义组件的生命周期函数
created:组件刚被创建好,此时不能调用setData,只应用给组件的this添加一些自定义的属性字段
attached:组件完全初始化完毕进入页面节点树后,这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
detached:组件离开页面节点树后,此时适合做一些清理性质的工作
lifetimes节点
生命周期函数在lifetimes字段内进行声明
lifetimes:{
created(){
console.log('created')
},
attached(){
console.log('attached')
}
}
6.组件所在页面的生命周期函数
组件所在页面的生命周期函数,需要定义在pageLifetimes节点中
7.自定义组件的插槽
插槽:在自定义组件的微信wxml中,提供一个<slot>节点(插槽),用于承载组件使用者提供的wxml结构
启用单个插槽
组件wxml
<view>
<view>这里是组件的内容结构</view>
<slot></slot>
</view>
页面wxml
<my-test4>
<view>这是通过插槽填充的内容</view>
</my-test4>
启用多个插槽
在组件.js文件中
options:{
multipleSlots:true
}
组件.wxml
<view>
<slot name="before"></slot>
<view>这里是组件的内容结构</view>
<slot name="after"></slot>
</view>
页面.wxml
<my-test4>
<view slot="before">这是通过插槽填充slot name="before"的内容</view>
<view slot="after">这是通过插槽填充slot name="after"的内容</view>
</my-test4>
8.组件通信
父子组件之间通信
属性绑定:父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据
事件绑定:子组件向父组件传递数据,可以传递任意数据
组件实例:父类使用this.selectComponent()获取子组件实例对象,这样可以直接访问子组件任意数据和方法
9.自定义组件的behaviors
用于实现组件间代码共享的特性,每个bahavior可以包含一组属性、数据、生命周期函数和方法,组件引用它时,它的属性、数据和方法会被合并到组件中
组件可以引用多个behavior,behavior也可以相互引用
创建
导入
require()方法导入,挂载后即可访问behavior
behavior中所有可用结点
10.Vant Webapp
小程序UI组件库
看官方文档
使用:在app.json的usingComponents节点中引入需要的组件,即可在wxml中直接使用组件
定制主题:文档 更改官方标准图案的颜色
11.小程序API的Promise化
安装包 npm install --save miniprogram-api-promise@1.0.4
需要先删除再重新构件npm
使用在app.js
import {promisifyAll} from 'miniprogram-api-promise'
const wxp = wx.p ={}
//将wx身上所有基于回调函数的异步API进行promise化,再挂载到wxp上
promisifyAll(wx,wxp)
调用promise化后的api
页面.wxml
<van-button type="danger" bindtap="getInfo">按钮</van-button>
页面.js
async getInfo(){
//重命名data:res
const {data:res} = await wx.p.request({
method:'GET',
url:'https://applet-base-api-t.itheima.net/api/get',
data:{
name:'zs',
age:20
}
})
console.log(res)
}
12.全局数据共享
为了解决组件之间数据共享的问题
两个包:npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1安装
mobx-miniprogram:创建store实例对象
mobx-miniprogram-bindlings:把store中的共享数据或方法,绑定到组件或页面中使用
创建Store实例
//此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
}),
updateNum2:action(function(step){
this.numB+=step
})
})
在页面中使用Store中的成员
在组件中使用Store中的成员
13.分包
将一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时需进行加载
分包后,小程序:1主包+多个分包
主包:项目启动页面或TabBar页面以及所有分包都需要用到的一些公共资源
小程序主包+所有分包总大小不超过16M,单个包大小不超过2M
使用分包
在app.json的subpackages节点中声明分包的结构
"pages": [
"pages/home/home",
"pages/message/message",
"pages/contact/contact"
],
"subPackages": [
{
"root":"pkgA",
"pages":[
"pages/cat/cat",
"pages/dog/dog"
]
},
{
"root":"pkgB",
"pages":[
"pages/apple/apple"
]
}
],
独立分包
本质同为分包,但可以独立于主包和其他分包单独运行
独立分包有结点"independent":true
独立分包和普通分包以及主包之间相互隔绝,不能相互引用彼此的资源
分包预下载
进入小程序某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包也买你时的启动速度
app.json中 preloadRule节点定义