微信小程序开发框架
1.基本概念:
微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验,更准确的说法是, **小程序可以视为只能用微信打开和浏览的网站,**
小程序和网页的技术模型是一样的,用到的 JavaScript 语言和 CSS 样式也是一样的,只是网页的 HTML 标签被稍微修改成了 WXML 标签,所以,小程序页面本质上就是网页。
2.项目结构:
|- app.json 小程序静态配置(页面,导航...)
|- app.js 小程序初始化
|- pages 页面目录
|- home
|- home.wxml 微信页面
|- home.js 页面实例(生命周期,初始化数据...)
3.配置:
.json 后缀的 JSON 配置文件
.wxml 后缀的 WXML 模板文件
.wxss 后缀的 WXSS 样式文件
.js 后缀的 JS 脚本逻辑文件
4.生命周期:
Page({
/** 页面初始化数据 */
data: {},
/** 监听页面加载 */
onLoad(options) {},
/** 监听页面初次渲染完成 */
onReady() {},
/** 监听页面显示 */
onShow() {},
/** 监听页面隐藏 */
onHide() {},
/** 监听页面卸载 */
onUnload() {},
/** 监听用户下拉动作 */
onPullDownRefresh() {},
/** 页面上拉触底事件的处理函数 */
onReachBottom() {},
/** 用户点击右上角分享 */
onShareAppMessage() {}
})
微信小程序组件
-
视图容器:
名称 功能 常用 备注 image 图片视图 ✅ view 视图容器 ✅ page-container 页面容器 ✅ 小程序如果在页面内进行复杂的界面设计(如在页面内弹出半屏的弹窗、在页面内加载一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件 swiper 滑动视图容器 ✅ 轮播图 scroll-view 可滚动视图容器 ✅ root-portal 脱离文档流 movable-area 可移动区域 ✅ -
基础内容:
名称 功能 常用 icon 图标组件 ✅ progress 进度条 ✅ rich-text 富文本 ✅ selection 局部文本选区 text 文本 ✅ -
表单组件:
名称 功能 button 按钮 checkbox 多选项目 checkbox-group 多项选择器,内部由多个checkbox组成 editor 富文本编辑器,可以对图片、文字进行编辑 form 表单 input 输入框 keyboard-accessory 设置 input / textarea 聚焦时键盘上方 cover-view / cover-image 工具栏视图 label 用来改进表单组件的可用性 picker 从底部弹起的滚动选择器 picker-view 嵌入页面的滚动选择器 picker-view-column 滚动选择器子项 radio 单选项目 radio-group 单项选择器,内部由多个 radio 组成 slider 滑动选择器 switch 开关选择器 textarea 多行输入框 -
导航:
** 名称** 功能 functional-page-navigator 仅在插件中有效,用于跳转到插件功能页 navigator 页面链接 -
媒体组件:
** 名称** 功能 audio 音频 camera 系统相机 channel-live 小程序内嵌视频号直播组件,展示视频号直播状态和封面,并无弹窗跳转至视频号 channel-video 小程序内嵌视频号视频组件,支持在小程序中播放视频号视频,并无弹窗跳转至视频号 image 图片 live-player 实时音视频播放(v2.9.1 起支持同层渲染) live-pusher 实时音视频录制(v2.9.1 起支持同层渲染) video 视频(v2.4.0 起支持同层渲染) voip-room 多人音视频对话
微信小程序指南
微信小程序路由
/** 保留当前页面,跳转到某个页面 */
wx.navigateTo({
url: '/pages/target/target'
})
/** 关闭当前页面,跳转到某个页面 */
wx.redirectTo({
url: '/pages/target/target'
})
/** 跳转到 tabBar 页面 并关闭其他非tabBar页面 */
wx.switchTab({
url: '/pages/tabBarPage/tabBarPage'
})
/** 关闭所有页面,打开到某个页面 */
wx.reLaunch({
url: '/pages/target/target'
});
/** 传递参数 */
wx.navigateTo({
url: '/pages/target/target?name=John&age=30'
})
目标页面接收参数
Page({
onLoad: function(options) {
console.log(options.name)
console.log(options.age)
}
})
模块化module.exports
在微信小程序中,可以使用 module.exports 和 require 来实现模块化开发,通过模块化,可以将代码拆分成多个文件,方便管理和复用如:
假设我们有一个工具函数模块 `utils.js`可以将其定义为一个独立的模块:
/**
@file utils.js
*/
function formatTime(date) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':');
}
function formatNumber(n) {
n = n.toString();
return n[1] ? n : '0' + n;
}
/** 导出模块 */
module.exports = {
formatTime: formatTime
};
使用模块:
/** 在需要使用该模块的页面或其他模块中,可以通过 require 引入: */
const utils = require('../../utils/utils.js');
Page({
onLoad: function() {
const currentTime = utils.formatTime(new Date());
console.log(currentTime); // 输出格式化后的当前时间
}
});
-
数据绑定 (数据绑定/双向绑定)
- 列表渲染
<view wx:for="{{array}}"> {{item}} </view>
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
- 条件渲染
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
Page({
data: {
view: 'MINA'
}
})
-
WXML template 模版
在微信小程序中,WXML 模板(template)可以用于定义可复用的代码片段。通过使用模板,可以提高代码的复用性和可维护性。模板类似于函数,可以在不同的地方调用,并传递不同的参数。
/**
* @file index.wxml
* name 属性为模板命名
*/
<template name="itemTemplate">
<view class="item">
<text>{{name}}</text>
<text>{{value}}</text>
</view>
</template>
/**
* 使用模版
* is属性指定模板名称
*/
<import src="path/to/template.wxml" />
<view wx:for="{{items}}" wx:key="name">
<template is="itemTemplate" data="{{...item}}" />
</view>
Page({
data: {
items: [
{ name: 'Item 1', value: 'Value 1' },
{ name: 'Item 2', value: 'Value 2' },
{ name: 'Item 3', value: 'Value 3' }
]
}
});
- WXSS
官方文档:developers.weixin.qq.com/miniprogram…
获取界面上的节点信息
在微信小程序中,可以使用 wx.createSelectorQuery 来获取界面上的节点信息。wx.createSelectorQuery 提供了一种方式,可以在页面中选择节点并获取其布局位置和其他信息
/** 获取单个节点 */
<view id="myView" class="my-view">Hello, WeChat Mini Program!</view>
/** 获取多个节点 */
<view class="my-view">View 1</view>
<view class="my-view">View 2</view>
<view class="my-view">View 3</view>
<button bindtap="getNodeInfo">Get Node Info</button>
Page({
getNodeInfo: function() {
const query = wx.createSelectorQuery();
query.select('#myView').boundingClientRect(function(rect) {
console.log(rect);
// rect 包含节点的布局信息
// rect.width, rect.height, rect.top, rect.left, rect.right, rect.bottom
}).exec();
}
});
Page({
getNodesInfo: function() {
const query = wx.createSelectorQuery();
query.selectAll('.my-view').boundingClientRect(function(rects) {
console.log(rects);
// rects 是一个数组,包含每个节点的布局信息
rects.forEach(function(rect) {
console.log(rect);
// rect.width, rect.height, rect.top, rect.left, rect.right, rect.bottom
});
}).exec();
}
});
组件间的通信
目录:
引入子组件:
{
"usingComponents": {
"my-component": "/components/my-component/my-component"
}
}
父组件可以通过属性(props)向子组件传递数据:
/** 父组件 pagespages/index */
<child-component
/** 传递变量 */
message="Hello from parent!"
/** 传递事件 */
bind:customEvent="handleCustomEvent"
/>
Page({
data: {
message: 'Hello from parent!'
},
handleCustomEvent: function(e) {
/** 获取全局状态 */
const app = getApp();
/** ======== */
console.log(e.detail);
}
});
子组件:
/** 子组件 components/child-component */
/** .json */
{
"component": true
}
/** .wxml */
<view>{{message}}</view>
<button bindtap="sendEvent">Send Event</button>
/** .js */
const sharedBehavior = require('../../behaviors/shared-behavior.js');
Component({
/** 可以实现组件间的代码复用和通信 */
behaviors: [sharedBehavior],
/** 子组件私有变量 */
data: {},
/** 接收参数 */
properties: {
message: {
type: String,
value: ''
}
},
/** 子组件生命周期 */
lifetimes: {
/** 组件实例进入页面节点树时触发 */
attached: () => {},
/** 组件实例刚刚被创建时触发 */
created:() => {},
/** 组件布局完成后触发 */
ready:() => {},
/** 组件实例被移动到节点树的另一个位置时触发 */
moved:() => {},
/** 组件实例被从页面节点树移除时触发 */
detached:() => {},
},
methods: {
sendEvent: function() {
/** 访问父组件传递的参数 */
const parentText = this.data.text;
/** 调用父组件事件 */
this.triggerEvent('customEvent', { message: 'Hello from child!' });
}
}
});
behavior管理状态:
/** shared-behavior.js */
module.exports = Behavior({
data: {
sharedData: 'Hello from behavior!'
},
methods: {
sharedMethod: function() {
console.log('This is a shared method');
}
}
});
插槽solt
/** 子组件 */
<view class="container">
<slot name="header"></slot>
<slot name="content"></slot>
<slot name="footer"></slot>
</view>
/** 父组件 */
<view>
<my-component>
<view slot="header">Header content from parent</view>
<view slot="content">Main content from parent</view>
<view slot="footer">Footer content from parent</view>
</my-component>
</view>