一.细节
1.小程序包含一个描述整体程序的 app 和多个描述各自页面的 page
2.小程序框架分为视图层和逻辑层
逻辑层是由JavaScript编写。
视图层由 WXML 与 WXSS 编写,由组件来进行展示。组件(Component)是视图的基本组成单元。
将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。
二.小知识点
1.App()
函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。
都是在app.js文件中
2.
Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。
(1).初始化数据:data
data 将会以 JSON 的形式由逻辑层传至渲染层,所以其数据必须是可以转成 JSON 的格式:字符串,数字,布尔值,对象,数组。
<img src="https://img-blog.csdn.net/20170426170416617 alt="" />
(2).生命周期函数
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 页面创建时执行 一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数
},
onShow: function() {
// 页面出现在前台时执行
},
onReady: function() {
// 页面首次渲染完毕时执行 只会调用一次,页面渲染完成,可以和视图层进行交互
},
onHide: function() {
// 页面从前台变为后台时执行
},
onUnload: function() {
// 页面销毁时执行
},
onPullDownRefresh: function() {
// 触发下拉刷新时执行
},
onReachBottom: function() {
// 页面触底时执行
},
onShareAppMessage: function () {
// 页面被用户分享时执行
},
onPageScroll: function() {
// 页面滚动时执行
},
onResize: function() {
// 页面尺寸变化时执行
},
onTabItemTap(item) {
// tab 点击时执行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件响应函数
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
// 自由数据
customData: {
hi: 'MINA'
}
})
(3).事件处理函数:bindtap
<view bindtap="viewTap"> click me </view>
(4)data修改
data: {
text: 'init data',
num: 0,
array: [{ text: '1init data' }],
object: {
text: 'init data'
}
},
修改:
this.setData({
num: this.data.num+1 // 1
})
// 直接修改数组
this.setData({
'array[0].text': 'changed data'
})
// 直接修改对象
this.setData({
'object.text': 'changed data'
});
3.实现动态显示和隐藏某个控件
<view class="{{open?'display_show':'display_none'}}">列表1</view>
data:{
open:false
},
showitem:function(){
this.setData({
open:!this.data.open
})
}
.display_show{
display: block;
}
.display_none{
display: none;
}
4.通过 data-*
和 e.target.dateset
传递参数
<view class="phone_personal">{{firstPerson}}</view>
<view class="select_one" bindtap="mySelect" data-me="吃">吃</view>
this.setData({
firstPerson:e.target.dataset.me,
})
这时:firstPerson=吃
5.弹性盒字:display:flex;
<view class="phone_one" bindtap="clickPerson">
<view class="phone_personal">{{firstPerson}}</view>
<image src="../../image/i.png" class="personal_image {{selectArea ? 'rotateRight' :''}}"></image>
</view>
在父级:display:flex;
justify-content:space-between;
这样子集就会并列。justify-content:space-between;这样子集就会分别在在俩头
6.获取自身的样式e.detail.width,e.detail.height
<image class="image-style" src="../uploads/2.jpg" style="width:{{imgwidth}}px;height:{{imgheight}}px;"bindload="imageLoad" ></image>
var app = getApp()
Page({
data: {
imgwidth:0,
imgheight:0,
},
imageLoad: function(e) {
var _this=this;
var $width=e.detail.width, //获取图片真实宽度
$height=e.detail.height,
ratio=$width/$height; //图片的真实宽高比例
var viewWidth=this.data.screenWidth, //设置图片显示宽度,
viewHeight=parseInt(viewWidth/ratio); //计算的高度值
_this.setData({
imgwidth:viewWidth,
imgheight:viewHeight
})
}
7.如何定义全局数据 和js模块化
在app.js的App({})中定义的数据或函数都是全局的,在页面中可以通过var app = getApp(); app.function/key的方式调用(不过我们没有必要再app.js中定义全局函数)
(1)设置全局变量
App({
globalData:{
userInfo:null,
test:"test"
}
})
获取变量值
var test = getApp().globalData.test;
console.log(test)
B.模块化
可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports
或者 exports
才能对外暴露接口。
exports
是 module.exports
的一个引用,因此在模块里边随意更改 exports
的指向会造成未知的错误。所以更推荐开发者采用 module.exports
来暴露模块接口,除非你已经清晰知道这两者的关系。
8. 遮罩层(蒙层)弹出的时候,不应该让遮罩层底下的内容能滚动,
view class="container" catchtouchmove="ture"></view>在遮罩层view加 catchtouchmove="ture"
9.登录后,获取code(一个code只能用一次)
10.路由和层级
A.路由
1.navigateTo, redirectTo 只能打开非 tabBar 页面。
2.switchTab 只能打开 tabBar 页面。
3.reLaunch 可以打开任意页面。
4.页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
5.调用页面路由带的参数可以在目标页面的onLoad中获取。
B.层级:getCurrentPages();
获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。
- 不要尝试修改页面栈,会导致路由以及页面状态错误。
- 不要在
App.onLaunch
的时候调用getCurrentPages()
,此时page
还没有生成。
目前小程序的层级只有10级,从A-跳转到B,只有10个页面
查看页面当前的层级
let pages = getCurrentPages();
console.log('当前层级有:', pages);
//返回第几级层级
wx.navigateBack({
delta: 7
});
小案例:A->B->C->E->F A->G->B->C->E->F
有2种情况下操作流程一路到 E页面,E是支付页面,F页面是详情页面。此时F页面,顶部的返回按钮 ,想返回到A首页,
这边有俩种情况,支付成功,支付失败
Page({
data: {
isNavigate: 0,
},
onShow: function () {
//返回到首页
this.setData({
isNavigate: ++this.data.isNavigate
})
/*
刚进入这个页面时isNavigate是2,支付成功后进入时 是3, 如果跳转到F页面,在返回的时候,是4 ,所以这个时候判断返回到首页A上。
*
*/
if (this.data.isNavigate == 4) {
//wx.getStorageSync('applyTypeInfo') 可以判断是否多做G .wx.getStorageSync('applyTypeInfo') == 2 则是多走了
if (wx.getStorageSync('applyTypeInfo') == 2) {
wx.navigateBack({
delta: 6
});
} else {
wx.navigateBack({
delta: 5
});
}
} else if (this.data.isNavigate == 3) {
wx.navigateTo({
url: '/pages/F/index'
});
}
},
payFn: function () {
wx.requestPayment({
'timeStamp': dataInfo.timeStamp, //时间戳,从 1970 年 1 月 1 日 00:00:00 至今的秒数,即当前的时间
'nonceStr': dataInfo.nonceStr, //随机字符串,长度为32个字符以下
'package': dataInfo.package, //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=***
'signType': dataInfo.signType, //MD5 签名算法
'paySign': dataInfo.sign, //签名
'success': function (data) {
console.log('成功', data)
},
'fail': function (data) {
//关闭支付的窗口时 进入页面是isNavigate 是2 ,失败的时候 3,F返回到首页时执行 onshow 时,就是4
console.log('失败', data)
let _this = this;
//针对主动关闭
wx.getSystemInfo({
success: function (systenRes) {
// console.log("操作系统信息:", systenRes)
if (!(systenRes.system.indexOf('Android') > -1)) { //android系统
//返回到首页
mythis.setData({
isNavigate: ++mythis.data.isNavigate
})
console.log('ios', mythis.data.isNavigate)
if (mythis.data.isNavigate == 4) {
if (wx.getStorageSync('applyTypeInfo') == 2) {
wx.navigateBack({
delta: 6
});
} else {
wx.navigateBack({
delta: 5
});
}
} else if (mythis.data.isNavigate == 3) {
wx.navigateTo({
url: '/pages/F/index'
});
}
}
}
})
}
})
}
})
// 安卓成功和失败都会执行onshow,然后跳到F页面 而ios 失败的时候,不走onshow,直接跳转F页面,只有成功的时候走onshow
11.web-view 业务域名
<web-view src='https://www.baidu.com'></web-view>
web-view 是需要配置,授权域名才可以 访问
开发的时候 在开发者工具上 勾选这个选项的话,可以访问,查看,
但是小程序上线就必须配置域名,否则不能访问。
注意:
A.域名下test.html 页面iframe 嵌套其他人的网页, 然后在小程序里面web-view 访问test.html ,配置这个test.html 的域名。你说可以访问 iframe 嵌套其他人的网页吗
这个是不行的。
B.是不能支付的
C.验证成功后txt文件就可以删除。
如果下次点击修改,验证过的域名,可以不需要再验证
D.一个域名只能绑定20个小程序
12.小程序顶部导航栏标题不居中
小程序默认在andriod中居左,ios中居中,解决方法:自定义导航栏
取消默认的导航栏
1. 全局设置app.json
"window": {
"navigationStyle": "custom"
},
2. 在单页面设置user页面中 user.json
{
"usingComponents": {},
"navigationStyle": "custom"
}
13.new Date('2019-01-01 11:11:11) 这个在ios是不兼容的,
可以通过以下方式
14.获取界面上的节点信息
wx.createSelectorQuery()可以用于获取节点属性、样式、在界面上的位置等信息
const query = wx.createSelectorQuery()
query.select('#the-id').boundingClientRect()
query.selectViewport().scrollOffset()
query.exec(function(res){
res[0].top // #the-id节点的上边界坐标
res[1].scrollTop // 显示区域的竖直滚动位置
})
15.表单
A、input
①confirm-type
仅在type='text'时生效,这个是作用是 键盘中右下角按钮的文字改变(confirm-type的最终表现与手机输入法本身的实现有关,部分安卓系统输入法和第三方输入法可能不支持或不完全支持)
②input 组件是一个原生组件,字体是系统字体,所以无法设置 font-family
③adjust-position="true" 输入框默认属性 这个键盘不会覆盖输入框
④
16.小程序的导航栏颜色可以设置,但是字体颜色只能是 black
/ white,然后默认的是安卓居左,ios居右。
17.
navigateTo 跳转页面
A跳转B,在B中还可以执行A的中方法
A页面:
<view>
<button bindtap="selectCard" data-action="queryList">
立即预约
</button>
<button bindtap="selectCard" data-action="orderList">
查询列表
</button>
</view>
const app = getApp();
Page({
data: {
},
onLoad: function () {
},
selectCard: function (e) {
let _this = this;
let action = e.currentTarget.dataset.action;
wx.navigateTo({
url: `/pages/B/B?action=${action}`,
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function (data) {
console.log(data,'传递参数')
},
nextAction: function (data) {
switch (data.action) {
case "queryList":
_this.queryList()
break;
case "orderList":
_this.orderList()
break;
}
}
}
})
},
orderList:function(e){
console.log('立即预约 页面')
wx.navigateTo({
url: '/pages/chat/chat'
})
},
queryList:function(){
console.log('查询列表 页面')
wx.navigateTo({
url: '/pages/index/index'
})
}
})
B页面
<view>
<view wx:for="{{dataList}}" wx:key="id">
<view data-item="{{item}}" bindtap="onTap">{{item.name}}</view>
</view>
</view>
const app = getApp();
Page({
data: {
dataList: [
{
"id": 1,
"name": "姓名:小样"
},
{
"id": 2,
"name": "姓名:王玉山"
}
],
action:""
},
onLoad: function (options) {
console.log(options)
this.setData({
action: options.action
})
},
onTap:function(row){
console.log('点击')
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('nextAction', {
action: this.data.action
});
}
})
三.注意点小程序误区
1.小程序不是Html5。小程序是微信全新定义的规范,是基于xml+js的,不支持也不兼容HTML,兼容受限的部分css写法。
小程序和腾讯X5引擎也没关系。X5是QQ浏览器团队的,是基于HTML的,但小程序是微信团队自研的
2.小程序不是b/s。微信宣传的一个重点,是触手可得,不用安装。但小程序并不是b/s的在线页面,它是c/s架构的。
3.小程序体验好并且小程序并非只适合低频或长尾应用
4.小程序不是应用商店,是OS(操作系统)
四、分享功能
(一)分享当前页面的小程序给微信好友或是群
1..小程序右上角自带的分享功能
在js:onLoad里面执行wx.showShareMenu();
2.<button open-type='share'>分享</button> 这个是分享给微信好友(真机调试)
五、在线客服、拨打客服
1.拨打客服
<button bindtap="callFn">拨打电话</button>
callFn(){
wx.makePhoneCall({
phoneNumber: '18911111132' //客服电话
})
},
2.在线客服
<button open-type="contact">进入客服会话</button>
点击按钮会进入这个页面,小程序后台可以设置客服人员。获取数据消息消息推送
五.编辑器
根据官网整理的小案例
1.xwml
<!-- <view class="text">标题: <input class="input" placeholder="input here" name="url"/></view> -->
<view class="toolbar" catchtouchend="format" style="top: {{isIOS ? keyboardHeight : 0}}px">
<!-- 图片 -->
<i class="iconfont icon-charutupian" catchtouchend="insertImage"></i>
<!-- h2 -->
<i class="iconfont icon-format-header-2 {{formats.header === 2 ? 'ql-active' : ''}}" data-name="header" data-value="{{2}}"></i>
<!-- h3 -->
<i class="iconfont icon-format-header-3 {{formats.header === 3 ? 'ql-active' : ''}}" data-name="header" data-value="{{3}}"></i>
<!-- 加粗 -->
<i class="iconfont icon-zitijiacu {{formats.bold ? 'ql-active' : ''}}" data-name="bold"></i>
<!-- 倾斜i -->
<i class="iconfont icon-zitixieti {{formats.italic ? 'ql-active' : ''}}" data-name="italic"></i>
<!-- 加底线 -->
<i class="iconfont icon-zitixiahuaxian {{formats.underline ? 'ql-active' : ''}}" data-name="underline"></i>
<!-- 加复选框 -->
<i class="iconfont icon--checklist" data-name="list" data-value="check"></i>
<!-- 1、2排序 -->
<i class="iconfont icon-youxupailie {{formats.list === 'ordered' ? 'ql-active' : ''}}" data-name="list" data-value="ordered"></i>
<!-- 点的排序 -->
<i class="iconfont icon-wuxupailie {{formats.list === 'bullet' ? 'ql-active' : ''}}" data-name="list" data-value="bullet"></i>
<!-- 删除 -->
<i class="iconfont icon-shanchu {{formats.clear ? 'ql-active' : ''}}" data-name="clear" bindtap="clear"></i>
<!-- 消除文本样式 -->
<i class="iconfont icon-clearedformat {{formats.removeFormat ? 'ql-active' : ''}}" data-name="removeFormat" bindtap="removeFormat"></i>
<!-- 加入今天的日期 -->
<i class="iconfont icon-date {{formats.insertDate ? 'ql-active' : ''}}" data-name="insertDate" bindtap="insertDate"></i>
<!-- 加风割线 -->
<i class="iconfont icon-fengexian {{formats.insertDivider ? 'ql-active' : ''}}" data-name="insertDivider" bindtap="insertDivider"></i>
</view>
<view class="container" style="height:300px;top:50px;">
<editor id="editor" class="ql-container" placeholder="{{placeholder}}" bindstatuschange="onStatusChange" bindready="onEditorReady">
</editor>
</view>
<button bindtap="getData" class="button" type="primary" style="margin-top:350px">提交</button>
2.js
Page({
data: {
formats: {},
readOnly: false,
placeholder: '开始输入...',
editorHeight: 300,
keyboardHeight: 0,
isIOS: false
},
readOnlyChange() {
this.setData({
readOnly: !this.data.readOnly
})
},
onLoad() {
const platform = wx.getSystemInfoSync().platform
const isIOS = platform === 'ios'
this.setData({ isIOS })
const that = this
this.updatePosition(0)
let keyboardHeight = 0
wx.onKeyboardHeightChange(res => {
if (res.height === keyboardHeight) return
const duration = res.height > 0 ? res.duration * 1000 : 0
keyboardHeight = res.height
setTimeout(() => {
wx.pageScrollTo({
scrollTop: 0,
success() {
that.updatePosition(keyboardHeight)
that.editorCtx.scrollIntoView()
}
})
}, duration)
})
},
updatePosition(keyboardHeight) {
const toolbarHeight = 50
const { windowHeight, platform } = wx.getSystemInfoSync()
let editorHeight = keyboardHeight > 0 ? (windowHeight - keyboardHeight - toolbarHeight) : windowHeight
this.setData({ editorHeight, keyboardHeight })
},
calNavigationBarAndStatusBar() {
const systemInfo = wx.getSystemInfoSync()
const { statusBarHeight, platform } = systemInfo
const isIOS = platform === 'ios'
const navigationBarHeight = isIOS ? 44 : 48
return statusBarHeight + navigationBarHeight
},
//编辑器初始化完成时触发
onEditorReady() {
const that = this
wx.createSelectorQuery().select('#editor').context(function (res) {
that.editorCtx = res.context
}).exec()
},
blur() {
this.editorCtx.blur();//编辑器失焦,同时收起键盘
},
format(e) {
let { name, value } = e.target.dataset;
if (!name) return
console.log('format', name, value)
this.editorCtx.format(name, value);
},
onStatusChange(e) {
const formats = e.detail
this.setData({ formats })
},
//加分割线
insertDivider() {
this.editorCtx.insertDivider();
},
//消除文本样式
removeFormat() {
this.editorCtx.removeFormat();//清除当前选区的样式
},
//删除
clear() {
this.editorCtx.clear();//清空文本
},
//加入当前日期
insertDate() {
const date = new Date()
const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
this.editorCtx.insertText({
text: formatDate
})
},
// 上传图片
insertImage() {
const that = this
wx.chooseImage({
count: 1,
success: function (res) {
that.editorCtx.insertImage({
src: res.tempFilePaths[0],
data: {
id: 'abcd',
role: 'god'
},
width: '80%',
success: function () {
console.log('insert image success')
}
})
}
})
},
//获取数据
getData(){
console.log('点击')
this.editorCtx.getContents({
success(res) {
console.log(res)
}
})
}
})
六.多列选择
1.picker mode = multiSelector
xwml:
<view class="section">
<view class="section__title">省份选择</view>
<picker mode="multiSelector" bindchange="change" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}" range-key="label">
<view class="picker">
{{multiArray[0][multiIndex[0]].label}},{{multiArray[1][multiIndex[1]].label}},{{multiArray[2][multiIndex[2]].label}}
</view>
</picker>
</view>
js:
Page({
data: {
//从后台获取到的json数据
iniTData:[
{
value: "350000",
label: '福建省',
level: 1,
children: [
{
value: "350100",
label: "福州市",
level: 2,
children:[
{
value: "350102-1",
label: "鼓楼区1",
level: 3,
},
{
value: "350102-2",
label: "鼓楼区2",
level: 3,
}
]
},
{
value: "350200",
label: "厦门市",
level: 2,
children: [
{
value: "350102-1",
label: "思明区1",
level: 3,
},
{
value: "350102-2",
label: "思明区2",
level: 3,
}
]
},
{
value: "350300",
label: "莆田市",
level: 2,
children: [
{
value: "350102-1",
label: "莆田区1",
level: 3,
},
{
value: "350102-2",
label: "莆田区2",
level: 3,
}
]
}
]
},
{
value: '340000',
label: '安徽省',
level: 1,
children: [
{
value: '340100',
label: '合肥市',
level: 2,
children: [
{
value: "350102-1",
label: "合肥区1",
level: 3,
},
{
value: "350102-2",
label: "合肥区2",
level: 3,
}
]
},
{
value: '340200',
label: '芜湖市',
level: 2,
children: []
}
]
}
],
//当前选中数组
multiArray: [],
//当前选中数组的下标值
multiIndex:[0,0,0],
//当前选中的数据与字段
multiSelect:{}
},
onLoad:function(option){
let datas = this.data.iniTData;
let multiArray = [[...datas], [...datas[0].children], [...datas[0].children[0].children]];
this.setData({
multiArray: multiArray
})
},
bindMultiPickerColumnChange: function (e) {
let iniTData = this.data.iniTData;
var data = {
multiArray: this.data.multiArray,
multiIndex: this.data.multiIndex
};
//e.detail.column 是第几列 e.detail.value 是第几行
data.multiIndex[e.detail.column] = e.detail.value;
/**
* 当e.detail.column 等于0 就是第一列 省 1 市 2 区
*/
var searchColumn = () => {
for (var i = 0; i < iniTData.length; i++) {
var arr1 = [];
var arr2 = [];
if (i == data.multiIndex[0]) {
for (var j = 0; j < iniTData[i].children.length; j++) {
arr1.push(iniTData[i].children[j]);
if (j == data.multiIndex[1]) {
for (var k = 0; k < iniTData[i].children[j].children.length; k++) {
arr2.push(iniTData[i].children[j].children[k]);
}
data.multiArray[2] = arr2;
}
}
data.multiArray[1] = arr1;
}
};
}
switch (e.detail.column) {
case 0:
//省改变
data.multiIndex[1] = 0;
data.multiIndex[2] = 0;
searchColumn();
break;
case 1:
//市改变
data.multiIndex[2] = 0;
searchColumn();
break;
}
this.setData(data);
},
//最后确定的值
change: function (e) {
let num = e.detail.value;
let multiArray = this.data.multiArray;
let data = {
name: multiArray[0][num[0]].label + "," + multiArray[1][num[1]].label + "," + multiArray[2][num[2]].label, //文字
code: multiArray[0][num[0]].value + "," + multiArray[1][num[1]].value + "," + multiArray[2][num[2]].value//id
}
this.setData({
multiSelect:data,
multiIndex:num
})
console.log(data)
}
})
简单一列的情况
<view class="section">
<view class="section__title">省份选择</view>
<picker mode="multiSelector" bindchange="change" value="{{multiIndex}}" range="{{multiArray}}" range-key="label">
<view class="picker">
{{multiArray[0][multiIndex[0]].label}},{{multiArray[1][multiIndex[1]].label}},{{multiArray[2][multiIndex[2]].label}}
</view>
</picker>
</view>
Page({
data: {
//数据 ["350000", "350100", "350102"]
multiArray: [
[{
value: "350000",
label: '福建省'
}],
[
{
value: "350100",
label: "福州市"
}
],
[
{
value: "350102",
label: "鼓楼区",
level: 3,
},
{
value: "350103",
label: "台江区",
level: 3,
},
{
value: "350104",
label: "仓山区",
level: 3,
},
{
value: "350105",
label: "马尾区",
level: 3,
},
{
value: "350111",
label: "晋安区",
level: 3,
},
{
value: "350112",
label: "长乐区",
level: 3,
},
{
value: "350121",
label: "闽侯县",
level: 3,
},
{
value: "350123",
label: "罗源县",
level: 3,
},
{
value: "350124",
label: "闽清县",
level: 3,
},
{
value: "350125",
label: "永泰县",
level: 3,
},
{
value: "350128",
label: "平潭县",
level: 3,
}
]
],
//当前选中数组的下标值
multiIndex: [0, 0, 0],
//当前选中的数据与字段
multiSelect: {}
},
change: function (e) {
let num = e.detail.value;
let multiArray = this.data.multiArray;
console.log(multiArray)
let data = {
name: multiArray[0][num[0]].label + "," + multiArray[1][num[1]].label + "," + multiArray[2][num[2]].label, //文字
code: multiArray[0][num[0]].value + "," + multiArray[1][num[1]].value + "," + multiArray[2][num[2]].value//id
}
this.setData({
multiSelect: data,
multiIndex: num
})
console.log(data)
},
})
七.official-account 开发者可在小程序内配置公众号关注组件,方便用户快捷关注公众号
注:设置的公众号需与小程序主体一致。
八.解决每次发布后码代码 不能及时更新:UpdateManager
const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
console.log(res.hasUpdate)
})
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function (res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function () {
// 新的版本下载失败
wx.showModal({
title: '更新提示',
content: '新版本下载失败',
showCancel: false
})
})
九.扫码获取参数
wx.getEnterOptionsSync() 与onShow是一样的性质,wx.getLaunchOptionsSync() 和onLaunch一样性质(只要加载一次,再次进入后,数据是一样的)
getLaunchOptionsSync,这个接口,扫码进入的时候,第二次不能获取到薪的码带来的参数,获取到的参数还是第一次。
十.webSocket
//监听 WebSocket 连接打开事件
wx.onSocketOpen(res=>{
console.log("websocket打开:",res)
})
1.链接websockect
wx.connectSocket({
url:'test.php',
header:{
'content-type': 'application/json'
},
success:function(res){
console.log('链接websockect成功')
}
})
2.获取服务传过来的数据
wx.onSocketMessage((res) => {
console.log("websocket接收到服务端传过来的数据:",res)
})
3.发送信息
wx.sendSocketMessage({
data:"发送数据"
})
4.监听 WebSocket 关闭
wx.onSocketClose((res) => {
console.log('连接已关闭:', res)
//这边可以重新在链接webSocket
});
5.监听WebSocket 链接失败
wx.onSocketError(function (res) {
console.log('WebSocket 连接打开失败,请检查!', res);
});
十二. 引入VR全景图
选择一款合适的vr制作工具 (krpano付费)(pannellum免费)
1.拿到做好的vr图片导入到HTML中(本案例用的pannellum) https://pannellum.org/
然后将其发布到正式网上去,在小程序中通过web-view进行展示VR场景,若是有加点击场景内的某个点进行跳转,记得引入jssdk(微信js接口)
十三.微信H5移动端真机调试--vConsole
微信打开这个网址 http://debugx5.qq.com/ 或是扫一扫下面的二维码
进去后,选择中间‘’信息‘’,然后一直往下翻,把vConsole打开,把下面两个Content Cache关掉。
然后打开你要调试的页面,你就你能看到右下角有个绿色按钮vConsole。点击就能查看你代码中console的内容了。
还有一种方法是引入vConsole文件。就直接可以看到打印的东西了。
https://github.com/Tencent/vConsole/blob/dev/doc/tutorial_CN.md