1.1 注册账号、下载工具、创建小程序
https://mp.weixin.qq.com/
需要记录 AppID
创建第一个小程序
1.2 发布小程序
小程序开发者工具点击“上传” - 提交到服务器上的开发版本- 在服务器后台点击 “提交审核” - 审核版本-审核需要一周左右的时间
需要支付 ,需要预留2周时间部署,
1.3 成员管理
需要设置项目成员,可以完成多人开发一个小程序
1.4 配置 客服人员
1.5 开发-开发管理-开发设置
a. 记录一下 AppID
自己保存一下 AppSecret(小程序秘钥)
每一次只能重新生成
b. 可以设置 ip白名单 ,
c. 可以设置上传的加密的秘钥
d. 重要:需要设置 服务器域名
request合法域名 *** 获取数据的合法域名
socket合法域名 *
uploadFile合法域名 *
downloadFile合法域名 *
注意:只能设置 https 或 wss域名 ,需要有 ssl加密层
1.6 设置 - 第三方设置 - 插件管理
所有的第三方插件可以在这里安装
pages 页面
index 首页页面 有4个文件
logs 日志页面
utils 公共的js 文件 时间戳转日期时间,封装获取数据
app.js 小程序的主入口文件
app.json 小程序的主文件的配置文件
app.wxss 主文件的样式
project.config.json 项目的配置文件
sitemap.json 站点配置文件
js
wxml 相当于 html
wxss 相当于 css
json 配置
在 app.json 中会自动默认生成该页的路由
如:
{
"pages": [
"pages/index/index",
"pages/logs/logs",
"pages/about/about"
],
view - div
text - span
image - img
block - template 不会解析成任何标签,一般用于 if for
App.json
"pages": [
"pages/index/index",
"pages/logs/logs",
"pages/about/about"
],
"tabBar":{
"color":"#666",
"selectedColor": "#445356",
"list":[
{
"pagePath":"pages/index/index",
"text":"首页",
"iconPath":"images/n-1-a.png",
"selectedIconPath": "images/n-1.png"
},
{
"pagePath":"pages/logs/logs",
"text":"日志",
"iconPath":"images/n-2-a.png",
"selectedIconPath": "images/n-2.png"
},
{
"pagePath":"pages/about/about",
"text":"关于",
"iconPath":"images/n-4-a.png",
"selectedIconPath": "images/n-4.png"
}
]
},
注意:底部导航 只能有 2-5项,否则会报错
小图标只能使用 本地图片
6.1 全局页面配置
pages:路由
tabBar:底部导航
window: 窗口
backgroundTextStyle 当需要下拉刷新时,需要配置为 dark
navigationBarTitleText 小程序的名称
"networkTimeout": {
"request": 10000, 获取数据的过期时间
"downloadFile": 10000 下载文件的过期时间
},
"debug": true 要不要显示提示信息
6.2 某个页的页面配置
"navigationBarTitleText" 页面标题
"usingComponents" 配置使用的组件的名称和地址
"enablePullDownRefresh" true 开启下拉刷新
1.网页开发渲染线程和脚本线程是互斥的 ;小程序中,二者是分开的,分别运行在不同的线程中, DOM API、JSCore
2.小程序没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API
3.执行环境不同,网页 在浏览器运行;小程序在小程序的服务器运行
4.标签不一样 ,小程序 view text image block…
5.获取的系统权限不一样,小程序可以获取 手机通讯录、摄像头、照片…
6.开发成本不同 ,小程序开发成本更低
1.app 需要下载安装,占用手机内存;小程序不需要安装、用完即走
2.推广渠道不一样,小程序依托的微信的基础用户
3.小程序开发成本低,app开发成本很高
4.app速度比小程快、app可以调用更多的手机底层api
小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。
10.1 变量
在 wxml 中 需要使用 {{}}来渲染
更改 data中的数据 需要使用
this.setData({data中的数据名:要赋值的新值})
微信小程序是单向数据流,直接赋值不会触发页面更新渲染
和react一样
10.2 列表渲染 for
a.基础for
日志内容:{{item.content}}
日志时间:{{item.time}}
b.wx:for 循环中 可以使用 key
可以使用 数据中的 id号
日志内容:{{item.content}}
日志时间:{{item.time}}
可以使用下标
日志内容:{{item.content}}
日志时间:{{item.time}}
还可以使用 *this
日志内容:{{item.content}}
日志时间:{{item.time}}
注意:
循环的时候,默认 item代表一行,index 代表这一行的下标
循环时需要使用 key ,否则会报错,key作用 唯一标识一行,提高性能
c.嵌套循环
wx:for-item 为item起别名
wx:for-index 为index起别名
d.使用循环时,可以在 block中写循环,block不需要解析为任何标签,减少标签层级
10.3 判断条件
数据小于20
数据大于20
数据等于20
注意:也可以使用 在 block标签中
11.1 wxss 有rpx的单位,可以适应所有的手机屏幕
ui作图需要使用 iphone678 ,
作图如果是2倍图 ,宽度 750px,
ui图和 rpx的比例是1:1 的比例,
在小程序上建议使用 rpx
11.2 app.wxss 全局样式,
页面名称.wxss 样式只在本业页起作用
11.3 @import “样式文件名.wxss ” 引入样式
11.4 内联样式的写法:
style="color:{{color}}"
12.1 需要配置 语序跨域的域名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-movvjQfj-1635585528828)(E:\2021-07-26\09-wechat\day01\note\images\配置.bmp)]
文档-api-网络-发起请求
wx.request
onLoad: function (options) {
wx.request({
url: 'https://www.51houniao.com/product/product/getProductRecommendUser',
data:{
desc: false,
orderBy: "top",
pageNow: 1,
pageSize: 20,
seller_user_id: "4bc4027c645343f09a964b5c2e9f875b"
},
method:"post",
//请求成功
success:(res)=>{
console.log(res);
this.setData({tuijianArr:res.data})
}
})
},
在 onLoad 的钩子函数中获取数据
输出:
//模块输出
module.exports = {
request:pagedata.request
}
引入:
//引入封装好的request
const fetch = require("../../utils/http");
16.1 导入老项目,导入时 可以使用 测试号,需要在 开发者工具-详情-本地设置-不校验合法域名 画上对号
16.2 老项目 ,本地设置中的调试基础库需要降低版本,否则会报错
17.1 普通的事件
wxml
js
//测试函数
testFun:function(){
console.log("函数运行了");
this.setData({num:this.data.num+1})
},
17.2 需要传递参数
wxml 传递参数 data-key=“value”
js 中 使用 ev.currentTarget.dataset.** 接收参数
testFun1:function(ev){
console.log(ev.currentTarget.dataset.name);
},
17.3 input框怎样接收wxml传过来的数据
wxml
js 中接收需要写成 ev.detail.value
addFun:function(ev){
console.log(ev);
this.setData({heroname:ev.detail.value})
},
17.4 事件绑定分为 冒泡的事件绑定 bind*** ,阻止冒泡的事件绑定catch***
17.5 小程序事件
类型 | 触发条件 | 最低版本 |
---|---|---|
touchstart | 手指触摸动作开始 | |
touchmove | 手指触摸后移动 | |
touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 | |
touchend | 手指触摸动作结束 | |
tap | 手指触摸后马上离开 | |
longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 | 1.5.0 |
longtap | 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) | |
transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 | |
animationstart | 会在一个 WXSS animation 动画开始时触发 | |
animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 | |
animationend | 会在一个 WXSS animation 动画完成时触发 | |
touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 | 1.9.90 |
bindinput 表单输入时触发的事件
submit 提交事件
scroll 滚动事件
18.1 页面钩子函数
onLoad 页面加载 ***
onReady 页面初次渲染完成 ***
onShow 显示***
onHide 隐藏***
onUnload 页面卸载***
onPullDownRefresh 下拉刷新的钩子函数 *
onReachBottom 上拉加载更多*
onShareAppMessage 分享时触发的钩子函数*
/**
* 生命周期函数--监听页面加载 只能执行一次
*/
onLoad: function (options) {
console.log('onLoad');
},
/**
* 生命周期函数--监听页面初次渲染完成 只能执行一次
*/
onReady: function () {
console.log('onReady');
},
/**
* 生命周期函数--监听页面显示 执行多次
*/
onShow: function () {
console.log('onShow');
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
console.log('onHide');
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
console.log('onUnload');
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
App.js 中的钩子函数
属性 类型 默认值 必填 说明 最低版本
onLaunch function 否 生命周期回调——监听小程序初始化。 ***
onShow function 否 生命周期回调——监听小程序启动或切前台。
onHide function 否 生命周期回调——监听小程序切后台。
onError function 否 错误监听函数。 ***
onPageNotFound
路由方式 | 触发时机 | 路由前页面 | 路由后页面 |
---|---|---|---|
初始化 | 小程序打开的第一个页面 | onLoad, onShow | |
打开新页面 | 调用 API wx.navigateTo 使用组件 `` | onHide | onLoad, onShow |
页面重定向 | 调用 API wx.redirectTo 使用组件 `` | onUnload | onLoad, onShow |
页面返回 | 调用 API wx.navigateBack 使用组件`` 用户按左上角返回按钮 | onUnload | onShow |
Tab 切换 | 调用 API wx.switchTab 使用组件 `` 用户切换 Tab | 各种情况请参考下表 | |
重启动 | 调用 API wx.reLaunch 使用组件 `` | onUnload | onLoad, onShow |
19.1 跳转 tabbar页面 使用 ,注意: 不能传递参数
跳转到的页面 show ,其他页面 hide
wx.switchTab
或
跳转首页
19.2 navigateTo 跳转
不能跳转 tabbar
跳转到的页面有返回按钮,页面实质显示和隐藏,不会卸载或重新加载
navigateTo的页面 可以使用 navigateBack 返回
19.3 redirectTo 跳转
不能跳转 tabbar,跳转页面没有返回按钮,页面 在跳转时会卸载,再回来时需要重新加载
19.4 reLaunch 跳转
可以跳转任何页面,还可以传参,性能比 前面的几种稍差
20.1 路由跳转时传参
A:传递参数
goAdd:function(){
wx.navigateTo({
url: '/pages/add/add?id='+this.data.userid,
})
},
B:接收参数 使用 onLoad 里面的 参数 options
onLoad: function (options) {
console.log(options.id);
},
20.2 模块化传参
A:输出:
//模块输出
module.exports = {
request:pagedata.request
}
B:引入:
//引入封装好的request
const fetch = require("../../utils/http");
20.3 使用 globalData 传递参数
在 App.js 中定义
globalData: {
userInfo: null,
heroArr:[
'葫芦娃','大黄蜂','托塔李天王'
]
}
在其他页面使用
//引入 App.js
const app = getApp();
//使用 app中定义的全局变量
app.globalData.***
20.4 可以使用缓存 ***
A: 设置缓存信息
//调用 同步设置缓存信息
wx.setStorageSync('userSto', this.data.user)
B: 获取缓存信息
wx.getStorageSync('userSto')
小程序的缓存和网页的缓存的区别: **
21.1 基础模板
创建 模板文件
templates/listtuijian/listtuijian.wxml
我是模板内容
使用 模板
21.2 模板传参
创建 模板文件
templates/listitem/listitem.wxml
{{item.proTitle}}
使用 模板
21.3 include 可以将目标文件除了
外的整个代码引入,相当于是拷贝到 include
位置
body
header
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML
,可以构建出页面的结构。
wxs 是在 wxml的页面中 使用 js内容
创建一个wxs
pages/list/listwxs.wxs
var msg = "hello wxs";
module.exports.msg = msg;
pages/list/list.wxml 里面使用
{{lw.msg}}
小程序默认是单向数据流,支持的写法是
用于双向绑定的表达式有如下限制:
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />
都是非法的;
<input model:value="{{ a.b }}" />
这样的表达式目前暂不支持。
const query = wx.createSelectorQuery();
query.select('#myjiedian').boundingClientRect(function(res){
console.log(res);//宽高、离上下左右的距离
})
query.exec();
wxml
动画
wxss
.con{width: 100px; height: 100px; border:2px solid blue;}
js
changeview:function(){
this.animate("#con",[
{opacity:1.0,rotate:0,backgroundColor:'#ff0000'},
{opacity:0.5,rotate:45,backgroundColor:'#00ff00'}
],3000,function(){
console.log("动画结束了");
})
},
可以:
静态初始渲染缓存
若想启用初始渲染缓存,最简单的方法是在页面的 json
文件中添加配置项 "initialRenderingCache": "static"
:
{
"initialRenderingCache": "static"
}
这样,小程序启动可以分为两种情况,一种是冷启动,一种是热启动。
通常,只有当小程序进入后台一定时间,或者系统资源占用过高,才会被销毁。具体而言包括以下几种情形:
28.1 基础自定义组件
a.创建组件
components/logcom/logcom.js
// components/logcom/logcom.js
Component({
/**
* 组件的属性列表,接收从父组件传过来的值
*/
properties: {
},
/**
* 组件的初始数据,组件自己的data数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
components/logcom/logcom.json
{
"component": true,
"usingComponents": {}
}
components/logcom/logcom.wxml
我是一个新定义的子组件
components/logcom/logcom.wxss
b.在 log页面使用新建好的组件
pages/log/log.json
{
"navigationBarTitleText": "查看启动日志",
"usingComponents": {
"logcom":"/components/logcom/logcom"
}
}
pages/log/log.wxml
注意:组件名称是驼峰式,在wxml中使用时需要转为 中划线的写法
在自定义组件中可以使用其他的自定义组件
自定义组件和页面所在的项目根目录目录名不能以 wx- 为前缀 ,否则会报错
28.2 组件传参 父传子 ***
新建组件
components/log/logtest.js
// components/logtest/logtest.js
Component({
/**
* 组件的属性列表
*/
properties: {
username:{
type:String
},
hero:{
type:Array
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
components/log/logtest.json
{
"component": true,
"usingComponents": {}
}
components/log/logtest.wxml
带参数的组件{{username}}
英雄列表
{{item}}
在 log的页面中使用
pages/log/log.json
{
"navigationBarTitleText": "查看启动日志",
"usingComponents": {
"logcom":"/components/logcom/logcom",
"logtest":"/components/logtest/logtest"
}
}
pages/log/log.wxml
28.3 小程序的组件的子传父
在子组件中
components/log/logcom.wxml
components/log/logcom.js
// components/logcom/logcom.js
Component({
/**
* 组件的属性列表,接收从父组件传过来的值
*/
properties: {
},
/**
* 组件的初始数据,组件自己的data数据
*/
data: {
num:20
},
/**
* 组件的方法列表
*/
methods: {
changeNum:function(){
var myEventDetail = {num:this.data.num};//将要传给父组件的参数
var myEventOption = {};//触发事件时的配置项
//自动触发子组件的自定义事件
this.triggerEvent("myevent",myEventDetail,myEventOption);
}
}
})
父组件中:
pages/logs/logs.wxml
pages/logs/logs.js
parentFun:function(data){
console.log("父组件接收的值",data.detail.num);
},
总结: 子组件 触发一个 自定义的事件,在父组件中给这个自定义事件绑定一个函数,在函数中接收从父组件传过来的值。
28.4 组件中的插槽
父组件
天涯何处无芳草
子组件
如果需要使用具名插槽,
Component({
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
properties: { /* ... */ },
methods: { /* ... */ }
})
28.5 自定义组件的生命周期
Component({
lifetimes: {
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
},
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
// ...
})
生命周期 | 参数 | 描述 | 最低版本 |
---|---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 | 1.6.3 |
attached | 无 | 在组件实例进入页面节点树时执行 | 1.6.3 |
ready | 无 | 在组件在视图层布局完成后执行 | 1.6.3 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 | 1.6.3 |
detached | 无 | 在组件实例被从页面节点树移除时执行 | 1.6.3 |
error | Object Error |
每当组件方法抛出错误时执行 | 2.4.1 |
28.6 behaviors 类似于vue 的 mixin ,或者是 react 高阶组件
behaviors
是用于组件间代码共享的特性,类似于一些编程语言中的 “mixins” 或 “traits”。
每个 behavior
可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。
先定义behaviors的文件
module.exports = Behavior({
data:{
name:"hello mr"
},
methods:{
beFun:function(){
console.log("behavior 运行了");
}
},
attached:function(){
console.log("behavior 钩子运行了");
}
})
使用时,先引入,再配置
...
//引入 behavior
+ const myBehavior = require("./myBehavior.js");
//引入 App.js
const app = getApp();
Page({
+ behaviors: [myBehavior],
data: {
logs: [],
userid:10,
username:"lili",
hero:["黄花菜","唯我独尊","中华神龙"]
},
....
将插件在服务端查找和配置
后台 -设置-第三方服务 - 插件管理,添加插件,
引入插件
App.json
"plugins": {
"DimensionalShow": {
"version": "1.0.2",
"provider": "wx0f253bdf656bfa08"
}
}
使用的页面配置插件组件
页面的 js和 wxml中 粘贴相应的内容
包的大小不能超过2M,最多可以有10个分包,小程序的总大小不能超过20M
在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。
在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。
subpackages
后,将按 subpackages
配置路径进行打包,subpackages
配置路径外的目录将被打包到 app(主包) 中subpackage
的根目录不能是另外一个 subpackage
内的子目录tabBar
页面必须在 app(主包)内packageA
无法 require packageB
JS 文件,但可以 require app
、自己 package 内的 JS 文件;使用 分包异步化 时不受此条限制
packageA
无法 import packageB
的 template,但可以 require app
、自己 package 内的 template
packageA
无法使用 packageB
的资源,但可以使用 app
、自己 package 内的资源
独立分包
分包预下载
分包异步化
1.在小程序端 ,调用 wx.login 获取 code ***
2.使用 wx.request 调用 你自己公司的 服务器的登录接口,并且传递 code。 ***
3.在公司的后台 会验证 APPID、 秘钥 、code、openid , 如果登录成功,调用 公司后台的服务器数据库,表示登录成功了,给前台返回登录成功的数据。
4.前台需要将 返回的登录成功的数据保存到 缓存 ***
5.获取其他数据时,将 登录的状态带过去就可以了
6.登录后,一般都会需要获取用户信息, 使用小程序wx.getUserProfile 这个API 获取用户数据
7.如果电商网站,有可能需要你填写手机号码,自动触发后台接口,将你的微信id 和手机号码进行关联
8.第一次进入 登录时,其实在后台是注册操作;其余的每一次都是登录操作
32.1 申请小程序支付
调用前需在小程序微信公众平台 -功能-微信支付入口申请接入微信支付
32.2 关联商户号
商户号的id 秘钥 用于加密的文件
32.3 服务端 需要配置 签名生成、签名验证、敏感信息加/解密、媒体文件上传等基础功能,验证 商户号是否能够正常支付
32.4 支付流程:
a.确认一下登录状态,如果已经登录,保存登录信息
b.使用 wx.request 调用后台接口,将token 、openid 传给后台
c.在服务端 配置 **签名生成、签名验证、敏感信息加/解密 ,生成 时间戳、随机串、签名信息。返回给小程序端。
d.客户端调用 后台接口,生成订单,订单号、总价、商品信息。
e.调用 wx.requestPayment().拉起微信支付,支付成功,返回成功的信息,页面跳转到 代发货页;支付失败,返回失败的提示。页面跳转到 未支付订单页面。
注意:支付失败的原因:有可能,签名出错、支付时确认订单失败,支付的参数异常、支付超时。。。
33.1 减少首屏渲染时间
分页处理,触底加载下一页
页面缓存
初始渲染缓存
减少使用 图片,
33.2 减少包的大小
使用 组件、使用模板、将公共的内容封装 、模块化 、使用 behavior
使用网络图片,减少使用本地图
上传前将注释和没有必要的代码清除
33.3 减少使用 data 和 setData
33.4 给小程序进行分包加载,还可以使用 分包预加载、独立分包
33.5 使用 为骨架屏,当网速比较慢时,先显示出框架
33.6 可以考虑使用防抖节流 比如:文本框和滚动事件
首先,需要在你的html页面中引用一个js文件。
然后为你的按钮标签注册一个点击事件:
$(".kaiqi").click(function(){
wx.miniProgram.redirectTo({url: ‘/pages/indexTwo/indexTwo’})
});
这里的redirectTo跟小程序中的wx.redirectTo()跳转页面是一样的,会关闭当前页跳转到页面。
你也可以替换成navigateTo,跳转页面不会关闭当前页。
h5的域名需要在小程序后台配置允许
必须是认证过的用户才可以使用
3.小程序跳转到另一个小程序
wx.navigateBackMiniProgram({
appId:'',
path: '/pages/index/index',
envVersion: 'trial',
extraData: {
openId: '123' //需要传递给目标小程序的数据,目标小程序可在 App.onLaunch,App.onShow 中获取到这份数据
},
答: 一、必须要在小程序后台使用管理员添加业务域名;
二、h5页面跳转至小程序的脚本必须是1.3.1以上;
三、微信分享只可以都是小程序的主名称了,如果要自定义分享的内容,需小程序版本在1.7.1以上;
四、h5的支付不可以是微信公众号的appid,必须是小程序的appid,而且用户的openid也必须是用户和小程序的。
推荐使用 uni-app
原生
①数据的大小限制,超过范围会直接导致整个小程序崩溃,除非重启小程序;
②小程序不可以直接渲染文章内容这类型的html文本,显示需借助插件
注:插件渲染会导致页面加载变慢,建议在后台对文章内容的html进行过滤,后台直接处理批量替换p标签div标签为view标签。然后其他的标签让插件来做。