前言
针对js前端开发者而言开发一个移动app, (非webapp)
目前主要技术主要有:dclound数字天堂的uni-app和H5+app,weex, react
小程序优点
1.开发成本相比原生开发低
2.小程序的流畅度介于h5和原生app之间
3.基于微信用户庞大的群体 提高了曝光机会 和 产品推广
4.非常灵活 场景入口非常多, 小程序二维码, 搜一搜,发现小程序 .......
小程序缺点
1.小程序代码 采用一个主包形式最多2M,采用主包+分包形式代码量最多8M
2.小程序官方是不能直接分享朋友圈,但是可以转换思路, 保存截图到相册,用图片形式让用户自己去分享
3.小程序没有用户体系 用户留存是一个问题
开发第一步申请到小程序的 AppID (用未被绑定的微信开放平台和微信公众平台注册的邮箱)
注册地址:https://mp.weixin.qq.com/cgi-bin/wx 或者从微信公众平台进入找到
开发第二步下载微信开发者工具
下载地址: https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
开发第三步填好appid账号进入后生成项目结构(不需要你配置啥)
微信原生提供的开发框架MINA框架(wxml wxss js ~ html css js)
注: wxml 是组件 html是标签
小程序主要分为 视图层 和 逻辑层
项目结构(项目结构可能会变, 但是基本的结构不会)
---pages(各个页面的目录)
-----pages1(页面一)
----page1.js(js代码在这)
----page1.wxml(页面布局)
----page1.wxss(css文件)
-----pages2(页面二)
......
---utils(util方法)
---app.js(入口文件,维护着小程序App的生命周期以及globalData,类似main.js)
---app.json(小程序Pages的清单文件)
---app.wxss(全局样式)
---project.config.json(项目配置文件)
//对应的app.json文件
{
"pages": [
"pages/start/start",
"pages/index/index",
"pages/index/sellRent",
"pages/mine/brokterInfo",
"pages/location/location",
"pages/h5Pages/h5Pages"
],
"window": {
"backgroundTextStyle": "drak",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "世华易居",
"navigationStyle": "custom",
"navigationBarTextStyle": "#fff",
"backgroundColor": "#fff"
},
"tabBar": {
"color": "#666",
"selectedColor": "#ff4343",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "images/home-off.jpg",
"selectedIconPath": "images/home-on.jpg",
"text": "主页"
},
{
"pagePath": "pages/see/seeone",
"iconPath": "images/see-off.jpg",
"selectedIconPath": "images/see-on.jpg",
"text": "约看"
},
{
"pagePath": "pages/mine/mine",
"iconPath": "images/my-off.jpg",
"selectedIconPath": "images/my-on.jpg",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 2000,
"connectSocket": 1000,
"uploadFile": 1000,
"downloadFile": 1000
}
}
分包加载
├── app.js
├── app.json
├── app.wxss
├── packageA
│ └── pages
│ ├── cat
│ └── dog
├── packageB
│ └── pages
│ ├── apple
│ └── banana
├── pages
│ ├── index
│ └── logs
└── utils
│
//对应的app.json文件
{
"pages":[
"pages/index",
"pages/logs"
],
"subPackages": [
{
"root": "packageA",
"pages": [
"pages/cat",
"pages/dog"
]
}, {
"root": "packageB",
"pages": [
"pages/apple",
"pages/banana"
]
}
]
}
打包原则
声明 subPackages 后,将按 subPackages 配置路径进行打包,subPackages 配置路径外的目录将被打包到 app(主包) 中
app(主包)也可以有自己的 pages(即最外层的 pages 字段)
subPackage 的根目录不能是另外一个 subPackage 内的子目录
首页的 TAB 页面必须在 app(主包)内
引用原则
packageA 无法 require packageB JS 文件,但可以 require app、自己 package 内的 JS 文件
packageA 无法 import packageB 的 template,但可以 require app、自己 package 内的 template
packageA 无法使用 packageB 的资源,但可以使用 app、自己 package 内的资源
低版本兼容
由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另外一份是整包的兼容代码。 新客户端用分包,老客户端还是用的整包,完整包会把各个 subpackage 里面的路径放到 pages 中。
常用wxml组件名称
<view></view> ~div
<image></image> ~img
<web-view></web-view> ~frame
<swiper>
<swiper-item> </swiper-item>
</swiper>
<text></text> ~span
<block></block> 类似vue的template包裹标签 本身不渲染节点
小程序的js钩子(生命周期)
//app.js
onLaunch(全局只触发一次)这个是在app.js定义的
//每个页面的js的
page({
data: {},
onLoad(){}, // 注册页面实例加载页面后 ,执行一次,第二次再进来该页面不触发
onHide(){}, // 例如从A页跳转到B页, A页的onHide触发,B页的onShow触发
onShow(){}, // 例如从B页跳转到A页, B页的onHide触发,A页的onShow触发
onUnload(){} // 页面卸载前触发,wx.redirectTo或者wx.navigateBack()返回上一页触发
})
路由/导航/跳转
wx.navigateTo ~ <navigator to="redirect"/> 打开新页面
wx.redirectTo 页面重定向
wx.navigateBack 页面返回 (类似vue的this.$router.go()方法)
wx.reLaunch 应用重启
wx.switchTab 底部tab菜单切换
注意事项:
wx.navigateTo 最多叠加5层跳转 不会将旧页面出栈,会将新页面入栈
wx.redirectTo 会将栈顶的旧页面出栈,再将需要跳转到的页面入栈(栈内元素个数不变)
wx.navigateBack 则是将页面栈最后一个元素出栈,因此倒数第二个元素会成为最后一个元素,即变成当前页面;也可以连续出栈好几个元素(大于栈内元素的个数则返回首页)返回栈中的某个页面。
举个栗子:
某场景中有A、B、C、D 四个页面,A 为首页,小程序启动时,这时栈中有一个A,从A用wx.navigateTo跳到B,再wx.navigateTo跳到C, 这时栈中有ABC,然后这时你用wx.redirectTo跳到D, 这时C页从栈中被移除, 此时栈中是ABD,你再通过wx.navigateBack返回 , 是直接到B, C已经不存在了...
微信内置 getCurrentPages()直接获取到这些页面构成的数组
登录流程

小程序调用wx.login()获取临时登录凭证code ----->传给我们自己的后台
---->我们的后台去跟微信服务器进行交互,拿到openid和session_key---->最后后台回传给小程序开发者
App({
onLaunch: function() {// 这是最开始 初始化app应用先走的钩子, 然后才走pages的onload钩子
wx.login({
success: function(res) {
if (res.code) {
//发起网络请求(请求我们自己的服务器,将code上传)
wx.request({
url: 'https://test.com/onLogin',
data: {code: res.code},
success:(result)=>{
console.log(result)
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
});
}
})
wx.login()调用时机就很重要 (自己根据场景处理,有些应用是必须先登录的,有些没必要,可以放到后面真正业务的时候再登录判断)
微信给我们提供了一个方法wx.checkSession用来检查用户当前session_key是否有效,判断小程序是否需要重新登录
wx.checkSession({
success: function(){
//session_key 未过期,并且在本生命周期一直有效
},
fail: function(){
// session_key 已经失效,需要重新执行登录流程
wx.login() //重新登录
....
}
})
事件
//事件名称
bindtouchstart="xxx"
bindtouchend="xxx"
bindlongtap="xxx" //长按事件
bindtap="xxx" //会冒泡的点击事件
catchtap="xxx" //阻止冒泡点击事件
//几个事件间执行的次序
单击 touchstart → touchend → tap
双击 touchstart → touchend → tap → touchstart → touchend → tap
长按 touchstart → longtap → touchend → tap
//事件传參
<button bindtap='submit' data-name="测试">测试</button>
submit: function(e){ //在响应方法里我们这么取参数
console.log(e.target.dataset.name)
事件上不能像vue事件直接传递参数,不允许,
只能data-,
}
小程序中不存在双向绑定,只能单向绑定,
刷新数据也只能this.setData({ key: value}), vue中的赋值 this.data = xxx 无效
this.setData也是最影响性能的,减少频繁操作,
数据量少的, 合并进行统一setData,
数据量大的,切分2~3数据进行setData
一些小技巧
减少ios的卡顿 : -webkit-overflow-scrolling: touch;
网友评论