小程序
作者:互联网
小程序基础
小程序构成
项目结构
pages # 用来存放页面
utils # 用来存放工具类
app.js # 小程序的入口
app.json # 小程序的配置文件
app.wxss # 小程序的全局样式
project.config.json # 小程序的项目配置
sitemap.json # 是否允许被微信索引
页面组成
# 每个页面由四个文件组成
.js # 页面的数据 处理函数
.json # 页面的配置
.wxml # 页面结构
.wxss # 页面样式
WXML和HTML
标签不同
HTML(div, sapn, img,a)
WXML(view,text,image,navigator)
属性节点不同
<a href="#"></a>
<navigator url="/pages/home/home"></navigator>
提供类似vue的模板
- 数据绑定
- 列表渲染
- 条件渲染
WXSS 和 CSS
新增rpx尺寸单位
- 在不同大小的小程序上会自动进行计算
提供全局的样式和局部样式
- 全局 app.wxss
- 局部 页面文件的 .wxss
仅支持部分选择器
- .class 和 #id
- element
- 并集选择器 后代选择器
- :: after 和 :: before
通讯模式
渲染层和逻辑层之间的通信
- 由微信客户端进行转发
逻辑层和第三方服务器之间的通讯
- 由微信客户端进行转发
小程序组件
view
<!--类似div-->
<view></view>
scroll-view滑动
横向滑动
<scroll-view class="main" scroll-x>
<view>1</view>
<view>2</view>
<view>3</view>
</scroll-view>
.main{
height: 100rpx;
width: 100rpx;
white-space: nowrap;
}
.main view{
display: inline-block;
height: 100rpx;
width: 100rpx;
background: rgb(35, 190, 21);
}
竖向滑动
<scroll-view class="main" scroll-y>
<view>1</view>
<view>2</view>
<view>3</view>
</scroll-view>
.main{
height: 100rpx;
width: 100rpx;
/* white-space: nowrap; */
}
.main view{
/* display: inline-block; */
height: 100rpx;
width: 100rpx;
background: rgb(35, 190, 21);
}
swiper和swiper-item 轮播图
<swiper>
<swiper-item>A</swiper-item>
<swiper-item>B</swiper-item>
<swiper-item>C</swiper-item>
</swiper>
# 属性
indicator-dots # 是否显示点 默认false
indicator-color # 指示点的颜色
indicator-active-color # 选中点的指示颜色
autopay # 是否自动切换
interval # 时间间隔
circular # 是否衔接滑动
text 文本
<!--selectable 长摁选中-->
<text selectable>1393939393</text>
rich-text 将渲染html字符串
<rich-text nodes="<h1>qwe</h1>"></rich-text>
小程序API
监听事件API
以on开头,来监听某些事件的触发
wx 类似window
wx.onWindowResize(function) 监听窗口是否变化
同步API
以sync结尾的API
执行的结果可以通过函数返回直接获取
异步API
需要通过success ,fail , complete接收调用的结果
WXML
数据绑定
.js里定义数据
Page({
/**
* 页面的初始数据
*/
data: {
name: 'giao',
age: 18
},
})
.wxml 直接用
<view>{{name}}</view>
<view>{{age}}</view>
事件绑定
渲染层到逻辑层的通讯方式
可以将用户在渲染层的行为通过微信客户端反馈到逻辑层
常用
tap # 触摸(类似点击)
input # 输入框事件
change # 状态改变
事件对象的属性列表
触发回调函数的时候, 会收到事件对象event
type # 事件类型
target # 触发事件的组件
currentTarget # 当前事件所绑定的组件
detail # 额外的信息
bindtap 触摸事件
Page({
/**
* 页面的初始数据
*/
data: {
count: 0
},
/**
* 触摸函数
*/
countAdd(e){
// 通过e.target.dataset 获取参数
console.log(e.target.dataset);
// 修改data的值
this.setData({
count: this.data.count + 1
})
},
/**
* 输入框改变
*/
onInputFn(e){
console.log(e.detail.value);
this.setData({
msg: e.detail.value
})
},
})
<!-- bindtap不能传值 需要通过 data-名字 -->
<button bindtap="countAdd" data-num="{{1}}">+1</button>
<input value="{{msg}}" bindinput="onInputFn" type="text" />
条件渲染
<view wx:if="{{sex === 1}}">男</view>
<view wx:elif="{{sex === 2}}">女</view>
<view wx:else>妖</view>
包裹性质的组件 ,不会在页面渲染, 可以控制多个组件显示隐藏
<block wx:if="{{false}}">
<view>block包裹</view>
<view>block包裹</view>
</block>
hidden
隐藏元素
<view hidden="{{true}}">block包裹</view>
wx:if和hidden
- wx:if 是动态销毁
- hidden 是隐藏
列表渲染
<!-- wx:key 不用{{}} -->
<view wx:for="{{arr}}" wx:key="item">
{{item}}
</view>
小程序配置
全局配置
app.json
pages # 所有小程序页面的存路径
window # 全局设置小程序窗口的外观
tabBar # 设置小程序底部的tabBar
style # 是否启用组件样式
windiw
"window":{
// 下拉刷新时 loading样式
"backgroundTextStyle":"dark",
// 导航栏背景
"navigationBarBackgroundColor": "#345333",
// 导航栏内容
"navigationBarTitleText": "健康宝",
// 导航栏字体颜色
"navigationBarTextStyle":"white",
// 开启下拉刷新
"enablePullDownRefresh" : true,
// 下拉刷新时 背景
"backgroundColor": "#efefef",
// 上拉触底 滚动条距离底部50px 加载数据
"onReachBottomDistance": 50
},
tabBar
用于实现多页面切换, 渲染顶部的时候不显示icon
最少渲染两个, 做多渲染5个
"tabBar": {
// 背景颜色
"backgroundColor": "#fff234",
// 字体颜色
"color": "#fff",
// 边框颜色 black white
"borderStyle": "black",
// 配置内容图标
"list":[
{
// 路径
"pagePath": "pages/nav/nav",
// 内容
"text": "nav",
// 图标
"iconPath": "/img/tabs/home.png",
// 选中图标
"selectedIconPath": "/img/tabs/home-active.png"
},
{},
{}
]
},
页面配置
会覆盖全局配置, 跟 window一致
小程序数据请求
出于安全考虑, 小程序官方对数据接口的请求做出来两个限制
- 只能请求https类型的接口
- 必须将接口的域名添加到信任列表
wx.request({
url:'url',
method: 'get',
success: (res)=> {
console.log(res);
}
})
wx.request({
url:'url',
method: 'post',
data:{},
success: (res)=> {
console.log(res);
}
})
视图与逻辑
声明式导航
页面上声明一个
导航组件, 点击跳转
<!--
声明式跳转
url="/..."
open-type="switchTab" 跳转配置tabBar
-->
<navigator url="/pages/msg/msg" open-type="switchTab">配置tabBar</navigator>
<!--
声明式跳转
url="/..."
open-type="navigate" (可选) 跳转配置没tabBar
-->
<navigator url="/pages/info/info" open-type="navigate">配置没tabBar</navigator>
<!--
返回
open-type="navigateBack"
delta="1" (为一时可以不写) 返回页面数
-->
<navigator open-type="navigateBack" delta="1">返回</navigator>
传参
<!--
传参
参数与路径之间使用?分隔
参数键与参数值 用等号
不同参数&
-->
<navigator url="/pages/info/info?name=zs&age=18" open-type="navigate">配置没tabBar</navigator>
编程式导航
调用小程序的导航API, 实现跳转
wx.switchTab({
// 路径
url:'',
// 成功
success: () =>{},
// 失败
fail: ()=>{},
// 成功失败都会执行
complete: ()=>{}
})
/**
* 编程式导航
* 跳转tabBar
*/
onNavigator(){
wx.switchTab({
url:"/pages/msg/msg"
})
},
/**
* 编程式导航
* 跳转非tabBar
*/
onNavigatorTo(){
wx.navigateTo({
url: '/pages/info/info'
})
},
/**
* 返回
*/
onBack(){
wx.navigateBack({
// 可选不写就是1
delta: 1,
})
},
<!-- 编程式跳转 -->
<button type="primary" bindtap="onNavigator">编程式跳转tabBar</button>
<button type="primary" bindtap="onNavigatorTo">编程式跳转非tabBar</button>
<!--返回-->
<button type="primary" bindtap="onBack">返回</button>
传参
/**
* 编程式导航
* 跳转非tabBar
*/
onNavigatorTo(){
wx.navigateTo({
url: '/pages/info/info?name=zs&age=18'
})
},
接收参数
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 传递的参数
console.log(options);
this.setData({
query: options
})
},
下拉刷新
全局 app.json window节点 enablePullDownRefresh: ture
局部 .json enablePullDownRefresh: true
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
count: 0
})
// 关闭下拉刷新
wx.stopPullDownRefresh({
success: (res) => {
console.log(res);
},
})
},
上拉触底
"onReachBottomDistance": 50 距离底部50
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.getColor()
},
loading显示隐藏
wx.showLoading({
title: '加载',
})
wx.hideLoading()
生命周期
应用生命周期
特指小程序从启动 运行 销毁的过程
页面生命周期
特指小程序, 每个页面的加载 渲染 销毁
/**
* 生命周期函数--监听页面加载
* 只调用一次
* options 当前页面获取的传参
*/
onl oad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
* 可以进行交互
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
* 进入前台
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
* 切入后台
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
* navigateBack
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
wxs
数据类型
number 数值类型
string 字符串
Boolean 布尔
object 对象
function 函数
array 数组
date 日期
regexp 正则
语法
只支持普通函数 var定义 类似Es5 , 遵循commonJs
<view>{{n1.giao('giao')}}</view>
<wxs module="n1">
module.exports.giao = function(str){
return str + 123
}
</wxs>
可以写成wxs文件
<wxs src="" module=""></wxs>
自定义组件
创建组件
创建components文件夹
创建text文件夹 右键 点击新建Component
引用组件
局部引用
只能在当前页面被引用
.json下添加
{
"usingComponents": {
"text-01" : "/components/text/text"
}
}
// 调用 <text-01></text-01>
全局引用
可以再每个页面使用
app.json下添加
{
"usingComponents": {
"text-01" : "/components/text/text"
}
}
// 调用 <text-01></text-01>
组件和页面的区别
- json 需要声明
"component": true,
- js 中调用 Component()
- 事件处理函数定义到methods
组件样式隔离
组件与页面之间互不影响
只有class会有样式隔离 , 不要使用Id , 属性, 标签选择器
修改样式隔离选项
"styleIsolation": "isolated"
// isolated 启用样式隔离
// apply-shared 页面能影响组件 , 组件影响不了页面
// shared 互相影响
数据方法属性
Component({
/**
* 组件的属性列表
* 用来接收外界传的属性
*/
properties: {
max: {
type: Number, //类型
value: 10 // 默认值
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
this.setData({
// 可以用setData修改 properties属性
max: this.properties.max + 1
})
数据监听器
Component({
observers: {
//如果监听的数据太多 可以 obj.**
'字段1,字段2.name':function(字段1,字段2){}
}
})
纯数据字段
options:{
// 正则 匹配上之后就是纯数据字段
pureDataPattern: /^_/
},
_data: true // 只能用于纯数据处理,不能用来渲染
组件声明周期
created # 组件刚创建 (不能调用setData)
attached # 组件进入页面节点树(可以发请求, 初始化数据)
ready # 在视图层布局完后执行
moved # 实例被移动到另一个节点树
detached # 组件被移出
Component({
// 调用生命周期函数
lifetimes: {
attached(){},
detached(){}
}
})
组件在页面的声明周期
show # 组件在页面被展示时
hide # 组件在页面被隐藏时
resize # 组件页面尺寸发生变化
Component({
// 调用页面生命周期函数
pageLifetimes: {
show: function(){},
hide: function(){},
resize: function(size){},
}
})
插槽
<!--组件添加-->
<slot></slot>
<!--页面调用-->
<text-01>
// 插槽内容
123
</text-01>
开启多个插槽
options:{
// 开启多个插槽
multipleSlots: true
},
<slot name="before"></slot>
<slot name="after"></slot>
<text-01>
<text slot="before">before</text>
<text slot="after">after</text>
</text-01>
通讯
属性绑定(父传子)
父向子传值, 只能传递普通类型的数据
<text-01 count="{{count}}"></text-01>
properties: {
count: Number
},
<view>{{count}}</view>
事件绑定(子传父)
// 父页面
// <text-01 bind:giao="countAdd"></text-01>
// 在子js , 调用父函数
this.triggerEvent('giao',{value:this.properties.count})
获取组件实例
可以获取组件的属性方法
<button bindtap="getText">获取text</button>
const child = this.selectComponent('.text')
child.setData({
count: child.properties.count + 1
})
behaviors
实现组件间代码共享, 可以包含属性, 数据, 生命周期函数和方法
Behaviors/index.js
module.exports = Behavior({
//节点属性
properties:{},
// 私有属性
data: {
age:18
},
// 方法
methods:{}
})
import Behavior from '../../Behaviors/index'
Component({
behaviors: [Behavior],
})
npm包
Vant Weapp
小程序项目 直接安装 npm i @vant/weapp@1.3.3 -S --production
然后 点工具 构建npm
修改 project.config.json
{
...
"setting": {
...
"packNpmManually": true,
"packNpmRelationList": [
{
"packageJsonPath": "./package.json",
"miniprogramNpmDistDir": "./"
}
]
}
}
app.json 引入组件
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
<van-button type="primary">测试按钮</van-button>
API Promise化
官方提供的API都是基于回调函数实现的, 容易造成回调地狱
miniprogram-api-promise
npm i --save miniprogram-api-promise@1.0.4
注意: 每一次安装完包都要构建npm
import {promisifyAll} from 'miniprogram-api-promise'
const wxp = wx.p = {}
// 把wx放到wxp上 , 在任何页面都可以 wx.p.request()
promisifyAll(wx,wxp)
async getPromise(){
const res = await wx.p.request({
url: 'url',
method: 'get',
})
console.log(res);
},
Mobx
mobx-miniprogram # 创建store
mobx-miniprogram-bindings # 把store 绑定到组件
npm i mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
store/index.js
import {action, observable} from 'mobx-miniprogram'
// observable 返回值就是store实例
export const store = observable({
count1: 1,
count2: 2,
// get 计算属性
get sum(){
return this.count1 + this.count2
},
// action 修改store值 不能用箭头函数
updateCount: action(function (num) {
this.count1 = this.count1 + num
})
})
页面使用
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/index'
Page({
countAdd(e){
this.updateCount(e.target.dataset.num)
},
/**
* 生命周期函数--监听页面加载
*/
onl oad: function (options) {
// createStoreBindings 可以将store数据绑定到页面
this.storeBingings = createStoreBindings(this,{
store,
// 字段和计算属性
fields: ['count1','count2','sum'],
// 方法
actions: ['updateCount']
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
this.storeBingings.detroyStoreBindings()
},
})
<text>{{count1}}+{{count2}}={{sum}}</text>
<button type="primary" bindtap="countAdd" data-num="{{1}}">+1</button>
<button bindtap="countAdd" data-num="{{-1}}">-1</button>
组件使用
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../../store/index'
Component({
behaviors: [storeBindingsBehavior],
storeBindings:{
store,
fields:{
count1: 'count1',
count2: 'count2',
sum: 'sum'
},
actions:{
updateCount: 'updateCount'
}
},
methods:{
countAdd(e){
this.updateCount(e.target.dataset.num)
}
}
})
<text>{{count1}}+{{count2}}={{sum}}</text>
<button type="primary" bindtap="countAdd" data-num="{{1}}">+1</button>
<button bindtap="countAdd" data-num="{{-1}}">-1</button>
分包
什么是分包
把完整的小程序项目 , 按照需求划分成不同的子包 用户使用时按需加载
- 可以优化小程序首次启动的下载时间
- 多团队共同开发, 解耦协作
分包后项目构成
- 主包: 启动页面 + tabBer页面 , 一些公共资源
- 分包: 只包含和当前分包有关的页面资源
小程序启动时, 默认会下载主包并启动主包页面, 当用户进入分包的某个页面, 客户端会把对应分包下载下来, 进行展示
**注意: ** 整个小程序不能超过16M, 单包不能超过2M
使用分包
小程序会按 subpackages 的配置进行分包, subpackages 之外的目录将被打包到主包中
// 进行分包声明
"subpackages":[
{
"root": "text1", //第一个分包目录
"pages": [ // 分包下的页面
"pages/info/info"
]
},
{
"root": "text2",
"pages": [
"pages/info/info"
]
}
],
- 主包无法引用分包的私有资源
- 分包之间不能引用私有资源
- 分包可以引用公共资源
独立分包
普通分包依赖主包
独立分包独立运行 , 不能引用公共资源
// 进行分包声明
"subpackages":[
{
"root": "text1", //第一个分包目录
"pages": [ // 分包下的页面
"pages/info/info"
],
"independent": true // 声明独立分包
}
],
分包预下载
进入指定页面, 下载需要用的分包
预下载大小限额2M
"preloadRule": {
"pages/message/message":{
// 在指定网络模式进行预下载
"network": "all",
// root名 下载哪些包
"packages": ["text1"]
}
},
自定义TabBar
配置信息 custom: true 是否开启自定义tabbar
app.json
{
"tabBar": {
"custom": true,
// list 要保留 低版本兼容
"list": [{
"pagePath": "page/component/index",
"text": "组件"
}, {
"pagePath": "page/API/index",
"text": "接口"
}]
},
"usingComponents": {}
}
跟根目录添加custom-tab-bar 文件 新建Component
编写代码即可
标签:text,程序,json,分包,组件,页面,wx 来源: https://www.cnblogs.com/rain-sparse/p/16380520.html