Article directory
1. Basic project configuration
1. Project composition
2. Common configuration file analysis
project.config.json
: Project configuration file, such as project name, appid, etc.; configuration detailssitemap.json
: Mini program search related; configuration detailsapp.json:
Global configurationpage.json
:Page configuration;app.js
Sharable global property values
3. Five major global configurations of app.json
pages:
Page path list- Used to specify which pages the mini program consists of. Each item corresponds to the path (including file name) information of a page.
- All pages in the mini program must be registered in pages.
window:
Global default window display- The user specifies how the window is displayed, which also contains many other attributes.
tabBar:
Display of the top tab bar- Detailed configuration reference
{
"pages": [
"pages/home/home"
],
"window": {
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#f6f866",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"tabBar": {
"color": "#777",
"selectedColor": "#1cb9ce",
"list": [{
"pagePath": "pages/home/home",
"text": "主页面”},
{
"pagePath": "pages/day02/day02",
"text": "home"
}
]
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
4. Page configuration in a single page
-
Can be specified directly
新建page 并回车,自动添加到pages中
or directly in pages
-
At the same time, each mini program page can also use
.json
files to configure the window performance of this page.- The configuration items in the page will overwrite
app.json 的 window
the same configuration items in the current page. - Please refer to the official website for specific configuration.
- The configuration items in the page will overwrite
{
"usingComponents": {
},
"navigationBarTitleText": "主页面",
"backgroundTextStyle": "dark", 背景文字颜色
"enablePullDownRefresh": true, 允许下拉刷新
"backgroundColor":"#f70", 背景颜色
"onReachBottomDistance": 100 距离底部多少触发事件
}
// 下拉刷新, 获取最新的数据
onPullDownRefresh() {
console.log('监听下拉刷新');
// 停止下拉刷新
setTimeout(() => {
// 异步请求
wx.stopPullDownRefresh({
success: (res) => {
console.log('停止', res)
},
})
}, 1000)
},
// 监听页面滚动到底部
onReachBottom() {
console.log('滚动到底部多少距离时加载更多~~ 100px');
this.setData({
listCounter: this.data.listCounter + 30
})
}
5. App function
- App() instances can be shared globally (singleton objects), so some shared data can be placed here;
- App function parameters
Function one :
- Determine whether it is opened in a group chat session, opened in the mini program list, opened with a WeChat scan, or opened in another mini program
scene
The options parameters and judgment values in the onLaunch and onShow life cycle callback functions- Document reference
Function 2: Define global App data
app.js
// app实例可以共享全局数据
globalData: {
userInfo: null,
token: 'Afjwt-12mandak-45'
}
home.js
onLoad() {
const {
globalData
} = getApp() // 全局的app实例
console.log(globalData.token);
// 拿到token发送网络请求-页面初始化
this.setData({
globalData
})
},
Function three: life cycle function
- In the life cycle function, complete the initialization operations after the application starts
- Complete the login operation and obtain the token
- Complete the login operation and obtain the token
6.tabBar configuration
最少 2 个、最多 5 个 tab
Only tabs can be configured in tabBar- When rendering the top tabBar, the icon is not displayed, only the text is displayed.
- For more configurations, please refer to the official website
{
"pages": [
"pages/hone/hone",
"pages/Profile/Profile",
"pages/experience/experience",
"pages/skill/skill",
"pages/index/index",
"pages/logs/logs"
],
"tabBar":{
"color": "#777",
"selectedColor": "#1cb9ce",
"list":[
{
"pagePath": "pages/hone/hone","text":"简历信息","iconPath": "/pages/img/icon08.png","selectedIconPath": "/pages/img/icon08.png"},
{
"pagePath": "pages/skill/skill","text":"个人技能","iconPath": "/pages/img/icon04.png","selectedIconPath": "/pages/img/icon04.png"},
{
"pagePath": "pages/experience/experience","text":"项目经历","iconPath": "/pages/img/icon02.png","selectedIconPath": "/pages/img/icon02.png"},
{
"pagePath": "pages/Profile/Profile","text":"自我评价","iconPath": "/pages/img/icon06.png","selectedIconPath": "/pages/img/icon06.png"}
]
},
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
2. Basic syntax, events, units
1. Grammar
Refer to the official website for basic grammar explanation
- text rendering
{
{
msg}}可以执行简单的js表达式
{
{
2+3}}
{
{
msg.length}}
- Conditional rendering
wx:if=""
wx:elif=""
wx:else
hidden // true 隐藏
- List rendering
- wx:key has different writing methods for different array types.
- Ordinary array
wx:key="*this"
- Array object
wx:key="字符串"
represents the unique attribute of the object
- Ordinary array
// 默认item就是数据 ,index是下标
wx:for="{
{list}}"
wx:key="index"
{
{
item}}
{
{
index}}
- Custom list rendering
定义item与index的名称
wx:for="{
{list}}}"
wx:for-item="myitem"
wx:for-index="myidx"
{
{
myidx}}
{
{
myitem}}
2. Event
Format: <element bind event name="callback">
- Example:
<view bindtap="fn1"></view>
<switch bindchange="fn2"></switch>
- Binding events in the mini program is achieved through the bind and capture keywords. Such as bindtap and capture-bind:tap,
- bind is event bubbling
外传
, and capture is event capturing里传
. capture-bind can only be used in colon form. - If you want to prevent events from bubbling or catching, you can pass
catch来绑定事件
. Such as catchtap, capture-catch:tap.
bindInput 表单输入时
bindconfirm 表单输入确认
bindtap 点击时候
-
Event parameters
- Custom parameters
data-*
注意点
:<view bindtap="handleTap(100)"></view>
The applet will think that the event function name is "handleTap(100)", then it will look for the function "handleTap(100)" instead of "handleTap"
- Custom parameters
-
mask parameter
-
form binding
<input value="{
{s1}}" bindinput="inputHd">
// js.js
inputHd(e){
this.setData({
s1:e.detail.value}) // 表单的值获取:e.detail.value
}
- event object properties
Attributes | type | illustrate |
---|---|---|
type | String | event type |
timeStamp | Integer | The number of milliseconds that elapsed between the page being opened and the event being triggered. |
target | Object | A collection of some property values of the component that triggered the event |
currentTarget | Object | A collection of some attribute values of the current component |
detail | Object | additional information |
touches | Array | Touch event, array of touch point information currently staying on the screen |
changedTouches | Array | Touch event, array of currently changed touch point information |
- target and currentTarget event object properties
Attributes | type | illustrate |
---|---|---|
id | String | The id of the current component |
dataset | Object | A collection of custom attributes starting with data- on the current component |
- the difference
taget
You cannot get the dataset data by clicking inter, butcurrentTarget
you can get it.
3. Unit
- rpx (responsive pixel): can be adapted according to the screen width. The specified screen width is 750rpx. For example, on iPhone6, the screen width is 375px and there are 750 physical pixels in total, then 750rpx = 375px = 750 physical pixels, 1rpx = 0.5px = 1 physical pixel.
- Please refer to the official website for details
3. Data responsive modification
- WXML templates and WXSS styles work in the rendering layer, and JS scripts work in the logic layer.
- The rendering layer and logic layer of the mini program are managed by two threads respectively, and the communication between the two threads will be relayed through the WeChat client.
- Data modification must be called,
this.setData
the same as react - setData optimization
4. Built-in components
1. button
open-type
Properties in the button component- open-type users obtain some special permissions and can bind some special events
- Obtain user information from old versions
<button type="primary" bindgetuserinfo="getUserInfo" size="mini" open-type="getUserInfo">getUserInfo</button>
getUserInfo(e) {
// 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
},
- The new version obtains user avatar and other information
<button bindtap="getUserProfile"> 获取头像昵称 </button>
getUserProfile(e) {
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
// 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
},
2. image
- The image component has a default width of 320px and a height of 240px.
- image supports lazy loading
- The mode configuration is as follows
model | value | illustrate |
---|---|---|
Zoom | scaleToFill | Scale the image without maintaining the aspect ratio, so that the width and height of the image are completely stretched to fill the image element |
Zoom | aspectFit | Scale the image while maintaining the aspect ratio until one side of the image touches the border. |
Zoom | aspectFill | Scale the image while maintaining the aspect ratio until the image completely fills the borders. |
Zoom | widthFix | The width remains unchanged and the height changes automatically, keeping the aspect ratio of the original image unchanged. |
- wx.chooseMedia gets local image display
<button bindtap="hyImageUpload">选择图片上传</button>
<!-- 选择本地图片 -->
<image src="{
{imageUrl}}"></image>
hyImageUpload(){
wx.chooseMedia({
camera: 'image',
}).then(res=>{
this.setData({
imageUrl:res.tempFiles[0].tempFilePath
})
})
}
3. input
- Support two-way binding
<input type="text" model:value=" {
{message}}"/>
4. Common properties of components
- Public attributes: refer to the official website
-
attribute name type describe annotation id String The unique identifier of the component Keep the entire page unique class String Component style class Style classes defined in the corresponding WXSS style String Inline styles for components Inline styles that can be set dynamically hidden Boolean Whether the component is displayed All components are displayed by default data-* Any Custom properties When an event is triggered on the component, it will be sent to the event handler function. bind* / catch* EventHandler Component events See events for details
-
5. WXS usage
- WXS (WeiXin Script) is a script language for small programs. Combined with WXML, the structure of the page can be constructed.
- It cannot be called directly in WXML
Page/Component中定义的函数
. - But in some cases, you can use functions to process data in WXML (similar to filters in Vue). In this case, WXS is used.
- Must use es5 syntax
//
<wxs module="format">
function joinTgether(num) {
return '¥' + num
}
// 必须模块化导出
module.exports={
joinTgether:joinTgether
}
</wxs>
<block wx:for="{
{wxs}}" wx:key="*this">
<button size="mini" type="warn">{
{
item}}-{
{
format.joinTgether(item)}}</button>
</block>
- Module extraction
utils
must be placed in the file ending in .wxs
<button>模块抽离wxs</button>
<wxs module="format" src="/utils_wxs/format.wxs"></wxs>
<block wx:for="{
{wxs}}" wx:key="*this">
<button size="mini" type="warn">{
{
item}}-{
{
format.joinTgether(item)}}</button>
</block>
- Each module has its own independent scope. That is, variables and functions defined in a module are private by default and are not visible to other modules;
- If a module wants to expose its internal private variables and functions to the outside world, it can only be
module.exports
achieved through; - For other uses, please refer to the official website
6. Components
6.1 Registration and use of global and local components
- Split the page into small, reusable components, which makes organization and management easier and more scalable.
.json
Make custom component declarations in files (set the component field to true to set this set of files as custom components) :
xx.json
Import in the file you need to use
{
"usingComponents": {
"sel-info": "/components/selection-info/sel-info"
}
}
- The project root directory name where the custom components and pages are located cannot
以“wx-”为
be prefixed, otherwise an error will be reported. - When a global component
app.json的usingComponents
declares a component, all pages and components can directly use the component.
6.2 Component style
-
The impact of styles within components on external styles
- Conclusion 1: The class style in the component only takes effect on the nodes in the wxml component, and does not take effect on the Page page that references the component.
- Conclusion 2: ID selectors, attribute selectors, and label selectors cannot be used within components.
-
The impact of external styles on styles within components
- Conclusion 1: The style of the external class will only take effect on the external wxml class, and will not take effect within the component.
- Conclusion 2: The use of id selectors and attribute selectors externally will not affect the internal components
- Conclusion 3: Using tag selectors externally will have an impact on the components
-
How to make classes affect each other
- In
Component对象
, you can pass in一个options
attributes, where there is an (isolated) attribute in the options attributestyleIsolation
. - styleIsolation has three values:
isolated
Indicates that style isolation is enabled. Within and outside custom components, styles specified using class will not affect each other (default value);apply-shared
Indicates that the wxss style of the page will affect the custom component, but the style specified in the custom component wxss will not affect the page;shared
Indicates that the wxss style of the page will affect the custom component, and the style specified in the custom component wxss will also affect the page and other settings.
- In
options: {
// styleIsolation:"isolated" // 默认值
styleIsolation: "apply-shared"
},
6.3 Communication between components
- Documentation Reference
Component Passing Data -properties
- Define subcomponents
<view style="width: 100%;height:80px;background-color: blueviolet;">
<button>{
{
title}}</button>
<view style="background-color: brown;margin-top: 10px; color: cornsilk;"> {
{
content}}</view>
</view>
- Subcomponent receives data and defaults the value
properties: {
title: {
type: String,
value: '默认标题'
},content:{
type:String,
value:'默认内容'
}
},
- Parent component uses child component and passes value
<props-data />
<view class="styl">
<props-data title="通信" content='组件通信-传递参数-动态数据' />
</view>
<props-data title="z组件传参" content='组件通信-传递参数-动态数据' />
Component transfer style-externalClasses
- In the Component object, define
externalClasses
properties - Use the class in the externalClasses attribute in wxml within the component
- Pass it in the page
入对应的class
, and set the style for this class. The
custom event
page directly calls the component method, which is equivalent to ref in vue.- This.selectComponent can be called in the parent component to obtain the instance object of the child component.
- When calling, you need to pass in a matching selector selector.
6.4 Use of a single slot
-
The component slots are also to make the components we encapsulate more scalable.
注意slot 不支持默认值
You can use the brother selector to solve this problem
- Reserved slots for subcomponents
<view class="myslot">
<view class="header">header</view>
<!-- 小程序插槽不支持默认值 -->
<view class="content">
<slot></slot>
</view>
<view class="default">兄弟选择器解决默认值</view>
<view class="footer">footer</view>
</view>
- Parent component passing structure
<my-slot>
<button>按钮</button>
</my-slot>
<my-slot>
<button size="mini" type="primary">default样式</button>
</my-slot>
<my-slot>
</my-slot>
- Brother selector solves default value problem
.default{
display: none;
}
.content:empty + .default{
display: block;
}
6.5 Use of multiple slots
- Reserved slots for subcomponents
<view class="slot">
<view class="t">
<text >上插槽</text> :
<slot name="t"></slot>
</view>
<view class="c">
<text>中间插槽</text> :
<slot name="c"></slot>
</view>
<view class="b">
<text>下插槽</text> :
<slot name="b"></slot>
</view>
</view>
- Allows multiple slots to be defined
Component({
// 允许定义多个插槽
options: {
multipleSlots: true
},
})
- Parent component passing structure
<more-slot>
<text slot="t">上插入</text>
<text slot="c">中间插入</text>
<text slot="b">下插入</text>
</more-slot>
6.6 Contamination
- Behaviors are features used for code sharing between components
类似于Vue中的 “mixins”
.- Each behavior can contain a set of properties, data, life cycle functions and methods;
- When a component references it, its properties, data and methods will be merged into the component, and the life cycle function will also be called at the corresponding time;
- Each component can
引用多个 behavior ,behavior 也可以引用其它 behavior
; - Document reference
- Write a mixin
export const counterMinxin = Behavior({
data: {
counter: 100
},
methods: {
add() {
// 加一修改 ,不应该使用++,这会导致counter在修改this..data.counter也在修改
this.setData({
counter: this.data.counter + 1
})
}
}
})
- use
import {
counterMinxin } from "../../behaviors/counter"
Component({
behaviors: [counterMinxin],
})
6.7 Component life cycle
- The life cycle of the component
lifetimes
is declared in the field - Component Lifecycle Documentation Reference
Component({
behaviors: [counterMinxin],
lifetimes:{
created(){
console.log('组件被创建');
},
attached(){
console.log('组件添加到dom树中');
},
detached(){
console.log('组件被删除');
}
}
})
6.8 Data listening
7. Life cycle
7.1. Application life cycle
Application life cycle hook function
Attributes | illustrate |
---|---|
onLaunch | Life cycle callback - monitor the initialization of the applet. |
onShow | Life cycle callback - listen for the applet to start or switch to the foreground. |
onHide | Life cycle callback - monitor the applet to switch to the background. |
onError | Error listening function. |
- parameter object
- Generally placed in the first parameter of the life cycle hook function.
onLaunch
The parameter object of the hook function is
- Generally placed in the first parameter of the life cycle hook function.
7.2 Page life cycle
Attributes | illustrate |
---|---|
onLoad | Life cycle callback—listen for page loading |
onShow | Life cycle callback—monitoring page display |
onReady | Life cycle callback—listen to the completion of the initial rendering of the page |
onHide | Life cycle callback—listening for page hiding |
onUnload | Life cycle callback—listen for page unloading |
onPullDownRefresh | Monitor user pull-down actions |
onReachBottom | Handling function for page pull-down event |
onShareAppMessage | The user clicks on the upper right corner to repost |
onShareTimeline | User clicks on the upper right corner to forward to Moments |
onAddToFavorites | The user clicks on the upper right corner to collect |
onPageScroll | Handling function for page scroll trigger events |
onResize | Triggered when the page size changes. For details, see Responding to Display Area Changes |
// 1. 页面路径
pages/index/index?id=10086&name='admin'
// 2. onLoad 获取参数
onLoad(query){
}
7.3. Component life cycle
Attributes | illustrate |
---|---|
created | 组件生命周期函数 - 在组件实例刚刚被创建时执行,注意此时不能调用 setData ) |
attached | 组件生命周期函数 - 在组件实例进入页面节点树时执行) |
ready | 组件生命周期函数 - 在组件布局完成后执行) |
moved | 组件生命周期函数 - 在组件实例被移动到节点树另一个位置时执行) |
detached | 组件生命周期函数 - 在组件实例被从页面节点树移除时执行) |
八 . API解析
8.1网络请求
- 网络请求:
wx.request(Object object)
- 官网参考
wx.request({
url: "api",
data: {
page: 1
},
success: res => {
console.log(res);
},
fail: err => {
}
})
- 封装
//0. 封装成函数
export function hyRequest(options) {
return new Promise((resolve, reject) => {
wx.request({
...options,
success: res => {
resolve(res.data)
},
fail: reject
})
})
}
//0. 类的方法封装
class hyService {
request(options) {
return new Promise((resolve, reject) => {
wx.request({
...options,
success: res => {
resolve(res.data)
},
fail: reject
})
})
}
get(options) {
return this.request({
...options, method: 'GET'})
}
post(options) {
return this.request({
...options,
method: 'POST'
})
}
}
export const serviceResponse = new hyService()
// 1. 导入
import {
hyRequest} from '../../service/request'
// 2. 使用封装调用api
hyRequest({
url:"http://123.207.32.32:1888/api/city/all"}).then(res=>{
console.log(res);
})
8.2 展示弹窗效果
8.3 获取设备|位置信息
- 获取当前设备的信息,用于手机信息或者进行一些适配工作
wx.getSystemInfo(Object object)
- 官网参考
- 获取用户的位置信息,以方便给用户提供相关的服务
wx.getLocation(Object object)
reqInfo() {
// 获取设备信息
// 我们需要经常获取当前设备的信息,用于手机信息或者进行一些适配工作
wx.getSystemInfo({
success: arr => {
console.log(arr);
}
}),
wx.getLocation({
success:err=>{
console.log(err);
}
})
}
注意获取位置信息需要相关权限
- 配置参考
"permission": {
"scope.userLocation": {
"desc": "位置信息将用于小程序位置接口的效果展示"
}
}
8.4 Storage存储
- 同步存取数据的方法:
- wx.setStorageSync(string key, any data)
- wx.getStorageSync(string key)
- wx.removeStorageSync(string key)
- wx.clearStorageSync()
- 异步存储数据的方法:
- wx.setStorage(Object object)
- wx.getStorage(Object object)
- wx.removeStorage(Object object)
- wx.clearStorage(Object object)
- 具体使用参考
8.5 页面跳转
- 通过navigator组件 和 通过wx的API跳转
- 路由跳转参考配置
页面跳转 -navigateTo
注意
跳转的页面是tarBar内的页面,需要使用wx.switchTab({})
navigateTo() {
// 跳转的页面是tarBar内的页面,需要使用wx.switchTab({})
wx.navigateTo({
// url: '/navPage/navigateTo/index',
// 传参
url: '/navPage/navigateTo/index?name=admin',
})
}
- 接受页面跳转的参数
Page({
// options接受路径参数
onLoad(options) {
console.log(options);
},
})
8.6 回退页面传参
- 主页面
Page({
navigateTo() {
// 方式二
wx.navigateTo({
url: '/navPage/navigateTo/index?name=admin',
events: {
backEvent(data) {
console.log('接受跳转的参数', data);
}
}
})
}
})
- 跳转的页面
Page({
up() {
wx.navigateBack()
// // 传递数据给上一级
// const pages = getCurrentPages()
// //读取最后一个页面,的实例
// const prePage = pages[pages.length - 2]
// // 设置上一个页面的数据
// prePage.setData({
// message: 'admin'
// })
// console.log(pages);
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('backEvent', {
name: 'admin',
pad: 'password'
})
},
// 回退过多可以直接在onLoad里面设置
onUnload() {
const pages = getCurrentPages()
const prePage = pages[pages.length - 2]
prePage.setData({
message: 'admin',
username: 'password'
})
},
})
九 .登录流程
- Configuration reference
openid : unique user identification
session_key : is the key for encrypting and signing user data . In order to ensure the data security of the application, the developer server should not send the session key to the applet, nor should it provide this key to the outside world.
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
const code = res.code
wx.request({
url: 'url',
data: {
code
},
method: 'POST',
success: res => {
const token = res.data.token
wx.setStorageSync('token', token)
}
})
}
})
},
})
- Reference article
10. Subpackage pre-download
- The mini program requires that the compressed package size cannot be larger than 2M, otherwise it cannot be compiled and released;
- In actual projects, when the size is larger than 2M, it needs to be published and uploaded through the subcontracting mechanism;
- Subcontracting the mini program can optimize the download time for the first launch of the mini program, because the main package size is smaller after subcontracting, which effectively improves the user experience;
- Divide the small program into different sub-packages and package them into different sub-packages during construction. Users can load them on demand when using them, which improves program performance;
- Reference for specific subcontracting instructions
- Subpackage pre-download is
app.json 增加 preloadRule
controlled by configuring
"subPackages": [
{
"root": "pagesMember",
"pages": [
{
"path": "setting/setting",
"style": {
"navigationBarTitleText": "设置"
}
}
]
}
],
// 预下载
"preloadRule": {
"pages/my/my": {
// 进入my主页 自动预下载pagesMember包
"network": "all",
"packages": [
"pagesMember"
]
}
}
注意
Pages in the same package share a common pre-download size limit of 2M. The limit will be verified when packaging in the tool.