网页程序迁移至微信小程序web-view详解

网页程序迁移至微信小程序web-view详解

2018/08/02 · JavaScript
· 小程序

原文出处: NeoPasser   

小程序现在越来越流行,但是公司的很多项目都是用网页写的,小程序语法不兼容原生网页,使得旧有项目迁移至小程序代价很高。

小程序之前开放了webview功能,可以说是网页应用的一大福音了,但是微信的webview有一些坑,这篇文章就是列举一下我在开发过程中遇到的一些问题以及我找到的一些解决方案。

js引入:

近期,微信官方修改了 getUserInfo、authorize等
接口,无法直接弹出授权窗口,这让我们以前一开始就获取用户信息完成登录的功能全部失效,新规定是第一次获取用户信息只能通过
button 去触发,那么有什么解决方案呢?

微信小程序开发内测一个月.数据传递的方式很少.经常遇到页面销毁后回传参数的问题,小程序中并没有类似Android的startActivityForResult的方法,也没有类似广播这样的通讯方式,更没有类似eventbus的轮子可用.

教你如何使用微信开发工具体验微信小程序。微信小程序将在2017年1月9日正式上线,目前个人不能注册小程序,如果我们要向体验小程序开发过程可以使用微信开发工具进行体验。

遇到的问题

  1. openid登录问题
  2. webview动态src
  3. 支付功能
  4. 分享功能
  5. 扫描普通二维码跳转特定页面
  6. 返回按钮缺失问题

const util =require(‘../../utils/util.js’)

我的思路是一进入小程序的时候,立马去调用登录接口(wx.login,之前的代码不用变)并在回调中去调用获取用户信息接口(wx.getUserInfo),这时候就需要特别注意了,需要会wx.getUserInfo的获取失败钩子进行判断,如果失败,那么直接跳转去登录页面(登录页面中可以实现按钮登录);如果成功,继续后续逻辑代码。

现在已知传递参数的方法只找到三种,先总结下.由于正处于内测阶段,文档也不是很稳定,经常修改,目前尚没有人造轮子.

1 创建项目

openid登录问题

微信webview的使用方法很简单,只要如下设置src就可以展示具体的网站了。

<!– wxml –> <!– 指向微信公众平台首页的web-view –>
<web-view src=”;

1
2
3
<!– wxml –>
<!– 指向微信公众平台首页的web-view –>
<web-view src="https://mp.weixin.qq.com/"></web-view>

微信环境里的很多网页都是用页面要实现网站的登录功能,只要把登录的信息,比如openid或者其他信息拼接到src里就好了。

这里有个问题,公众号的账号体系一般是以openid来判断唯一性的,小程序是可以获取openid的,但是小程序的openid和原公众号之类的openid是不一样的,需要将原先的openid账号体系升级为unionid账号体系。

以下是微信对unionid的介绍

获取用户基本信息(UnionID机制)

在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。

请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

UnionID机制说明:

开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

做完以上步骤,就可以调用小程序api wx.getUserInfo()
来获取用户信息了,此步骤需要进行后台信息解密过程,在此就不再赘述,结合小程序api文档操作就好。

获取到unioid之后,将unionid信息拼接到src就可以进行网页登录操作了(前提是网页可以用跳转链接的方式登录,类似公众号页面获取openid的形式)。

获取全局对象和方法:

具体代码如下:

先上GIF:

首先在微信提供的网站下载开发工具:

webview动态src

微信的webview有个坑的地方,不会动态的监听src的变化,这就造成了一个问题,要通过改变src实现页面跳转就不可以了。
我尝试了一些方法之后,找到了一个解决方案:

微信webview在页面load的时候会加载一次webview,我们就利用这个特性来实现动态src问题。

  1. 首先把要跳转的链接信息设置成全局变量,要改变src的时候,先把要src以’?‘拆分为链接和参数两部分,存入全局函数,再调用onLoad就可以实现webview刷新了。
  2. 页面跳转时,我们也需要src的动态刷新,所以要把链接信息存入全局函数;页面跳转时,onShow函数会被调用,这时候再调用一次onLoad就可以了。

data: { url: ”, loaded: false } // 小程序js里的onLoad函数可以写成这样
onLoad: function () { this.setData({ url: getApp().globalData.urlToken +
‘?’ + getApp().globalData.urlData }) }, changUrl: function () {
getApp().globalData.urlToken = ”
getApp().globalData.urlToken = ‘a=1&b=2’ //
直接调用onLoad,就会实现src的刷新 this.onLoad() }, onShow: function () {
if (!this.data.loaded) { // 第一次不运行 this.setData({ loaded: true })
return } // 直接调用onLoad,就会实现src的刷新 this.onLoad() } //
wxml可以写成这样 <web-view src=”{{url}}”></web-view>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
data: {
    url: ”,
    loaded: false
}
// 小程序js里的onLoad函数可以写成这样
onLoad: function () {
    this.setData({
      url: getApp().globalData.urlToken + ‘?’ +  getApp().globalData.urlData
    })
},
changUrl: function () {
    getApp().globalData.urlToken = ‘https://www.example.com’
    getApp().globalData.urlToken = ‘a=1&b=2’
    // 直接调用onLoad,就会实现src的刷新
    this.onLoad()
},
onShow: function () {
    if (!this.data.loaded) {
      // 第一次不运行
      this.setData({
        loaded: true
      })
      return
    }
    // 直接调用onLoad,就会实现src的刷新
    this.onLoad()
  }
 
// wxml可以写成这样
<web-view src="{{url}}"></web-view>

const app = getApp()

const Request = require(“/utils/request”); //引入封装的http拦截器

App({

onLaunch: function {

this.authorize(options.query); // 直接授权登录(options.query
参数与分享配置有关,后续文章介绍)

},

authorize: function {

let self = this;

share = share || {};

wx.login({

success: function {

wx.getUserInfo({

success: function {

Request.post(“/api/xcxWxLogin”, {

code: res.code,

encryptedData: resp.encryptedData,

iv: resp.iv

}).then(({

data: response

}) => {

if (response.code !== 0) {

wx.showToast({

title: response.msg,

icon: “none”

});

} else {

// 保存sessionid ,每次请求都会在拦截器中自动添加到header中

wx.setStorageSync(“UserSessionId”, response.data.sessionId);

self.globalData.sessionid = response.data.sessionId;

//todo 后续逻辑代码

}

});

},

fail: function {

//重点,如果获取失败直接跳转

let timer = setInterval => {

let pages = getCurrentPages();

if (pages.length > 0) {

clearInterval;

let currentPage = pages[pages.length – 1];

if (currentPage.route === “pages/user/userbind/userbind”) {

return true;

}

try {

wx.setStorageSync(“SYS_PREVIOUSPAGE”, currentPage);

setTimeout => {

wx.redirectTo({

url: “/pages/login/login”

});

}, 300);

} catch {

wx.redirectTo({

url: “/pages/login/login”

});

}

}

}, 200);

}

});

}

});

}

})

图片 1

支付功能

webview里面可以通过jssdk来实现一些小程序功能,但不能直接调用小程序的支付功能,这时候我们就需要转变一下策略了:

  1. 在网页里引入微信jssdk
  2. 在网页需要发起支付的地方,调用跳转页面的接口,控制小程序跳转到小程序的支付页面(这个要在小程序里单独写的),跳转的时候,需要把订单的一些信息都拼接到链接里,订单信息由后台返回,需要通过微信支付系统的统一下单接口,具体参看支付文档。
  3. 跳转到小程序支付页面后,由小程序页面发起支付,支付完成后跳转回webview页面,通过之前设置的动态src,控制webview跳转到特定的页面。

JavaScript

// 网页引入jssdk // 网页发起支付 wx.miniProgram.navigateTo({ //
payData由后台返回,主要是需要统一下单平台的prepay_id url:
‘../pay/index?data=’ + encodeURIComponent(JSON.stringify(payData)) }) //
微信支付页面 onLoad: function (option) { let page = this try { let data
= JSON.parse(option.data) if (!data || !data.prepay_id) {
console.error(‘支付参数错误,请稍后重试’, data) } wx.requestPayment({
timeStamp: ” + data.timestamp, nonceStr: data.nonceStr, package:
‘prepay_id=’ + data.prepay_id, paySign: data.paySign, signType:
data.signType, success: function (res) { getApp().globalData.urlToken =
`paySuccess.html` // 支付成功 getApp().globalData.urlData =
‘data=paySuccessData’ wx.navigateTo({ url: ‘/page/home/index’, }) },
fail: function (res) { getApp().globalData.urlToken = `payError.html`
// 支付失败 getApp().globalData.urlData = ‘data=payErrorData’
wx.navigateTo({ url: ‘/page/home/index’, }) }, complete: function (res)
{ } }) } catch (e) { console.error(‘支付错误’, e) } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 网页引入jssdk
 
// 网页发起支付
wx.miniProgram.navigateTo({
    // payData由后台返回,主要是需要统一下单平台的prepay_id
    url: ‘../pay/index?data=’ + encodeURIComponent(JSON.stringify(payData))
})
// 微信支付页面
onLoad: function (option) {
    let page = this
    try {
      let data = JSON.parse(option.data)
      if (!data || !data.prepay_id) {
        console.error(‘支付参数错误,请稍后重试’, data)
      }
      wx.requestPayment({
        timeStamp: ” + data.timestamp,
        nonceStr: data.nonceStr,
        package: ‘prepay_id=’ + data.prepay_id,
        paySign: data.paySign,
        signType: data.signType,
        success: function (res) {
          getApp().globalData.urlToken = `paySuccess.html`
          // 支付成功
          getApp().globalData.urlData = ‘data=paySuccessData’
          wx.navigateTo({
            url: ‘/page/home/index’,
          })
        },
        fail: function (res) {
          getApp().globalData.urlToken = `payError.html`
          // 支付失败
          getApp().globalData.urlData = ‘data=payErrorData’
          wx.navigateTo({
            url: ‘/page/home/index’,
          })
        },
        complete: function (res) {
        }
      })
    } catch (e) {
      console.error(‘支付错误’, e)
    }
  }

事件:

获取用户信息成功的回调具体得看业务,获取失败的回调主要是加定时器去判断页面是否加载完成,加载完成后再保存当前页面路径(用于登录成功后跳转),最后跳转到一个带有登录按钮的页面(不在app.js中完成登录,而是在login.js中完成登录,第二次打开就静默授权了)

1.APP.js

安装完成后,打开开发工具,将会要求扫码进入,如图1所示。

分享功能

小程序直接分享的webview所在的页面,如果需要加上页面参数,那我们就需要处理一下了。

  1. webview内是不能直接发起分享的,需要先用wx.miniProgram.postMessage接口,把需要分享的信息,推送给小程序;推送给小程序的信息不是实时处理的,而是用户点击了分享按钮之后,小程序才回去读取的,这就要求每个需要分享的页面再进入的时候就发起wx.miniProgram.postMessage推送分享信息给小程序。
  2. 小程序页面通过bindmessage绑定的函数读取post信息,分享的信息会是一个列表,我们取最后一个分享就好,把分享信息处理好,存到data里面以便下一步onShareAppMessage调用。
  3. 用户点击分享时,会触发onShareAppMessage函数,在里面设置好对应的分享信息就好了。
  4. onload函数有一个option参数的,可以读取页面加载时url里带的参数,这时要对原先的onload函数进行改造,实现从option里读取链接信息。

JavaScript

// 网页wx.miniProgram.postMessage wx.miniProgram.postMessage({ data: {
link: shareInfo.link, title: shareInfo.title, imgUrl: shareInfo.imgUrl,
desc: shareInfo.desc } }) // 小程序index wxml设置 <web-view
src=”{{url}}” bindmessage=”bindGetMsg”></web-view> //
小程序index js bindGetMsg: function (e) { if (!e.detail) { return } let
list = e.detail.data if (!list || list.length === 0) { return } let info
= list[list.length – 1] if (!info.link) {
console.error(‘分享信息错误’, list) return } let tokens =
info.link.split(‘?’) this.setData({ shareInfo: { title: info.title,
imageUrl: info.imgUrl, path:
`/page/index/index?urlData=${encodeURIComponent(tokens[1])}&urlToken=${tokens[0]}`
} }) }, onShareAppMessage: function (res) { if (res.from === ‘button’) {
// 来自页面内转发按钮 console.log(res.target) } let that = this return {
title: that.data.shareInfo.title, path: that.data.shareInfo.path,
imageUrl: that.data.shareInfo.imageUrl, success: function (res) { //
转发成功 }, fail: function (res) { // 转发失败 } } }, onLoad: function
(option) { if (option.urlToken) { getApp().globalData.urlToken =
option.urlToken } if (option.urlData) { getApp().globalData.urlData =
option.urlData } this.setData({ url: getApp().globalData.urlToken + ‘?’

  • getApp().globalData.urlData }) },
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 网页wx.miniProgram.postMessage
wx.miniProgram.postMessage({
  data: {
    link: shareInfo.link,
    title: shareInfo.title,
    imgUrl: shareInfo.imgUrl,
    desc: shareInfo.desc
  }
})
// 小程序index wxml设置
<web-view src="{{url}}" bindmessage="bindGetMsg"></web-view>
// 小程序index js
bindGetMsg: function (e) {
    if (!e.detail) {
      return
    }
    let list = e.detail.data
    if (!list || list.length === 0) {
      return
    }
    let info = list[list.length – 1]
    if (!info.link) {
      console.error(‘分享信息错误’, list)
      return
    }
    let tokens = info.link.split(‘?’)
    this.setData({
      shareInfo: {
        title: info.title,
        imageUrl: info.imgUrl,
        path: `/page/index/index?urlData=${encodeURIComponent(tokens[1])}&urlToken=${tokens[0]}`
      }
    })
},
onShareAppMessage: function (res) {
    if (res.from === ‘button’) {
      // 来自页面内转发按钮
      console.log(res.target)
    }
    let that = this
    return {
      title: that.data.shareInfo.title,
      path: that.data.shareInfo.path,
      imageUrl: that.data.shareInfo.imageUrl,
      success: function (res) {
        // 转发成功
      },
      fail: function (res) {
        // 转发失败
      }
    }
},
onLoad: function (option) {
    if (option.urlToken) {
      getApp().globalData.urlToken = option.urlToken
    }
    if (option.urlData) {
      getApp().globalData.urlData = option.urlData
    }
    this.setData({
      url: getApp().globalData.urlToken + ‘?’ +  getApp().globalData.urlData
    })
},

1、key
以bind或catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。

图片 2login页面,点击按钮完成登录

我把常用且不会更改的参数放在APP.js的data里面了.在各个page中都可以拿到var
app = getApp();

图片 3

扫描普通二维码跳转特定页面

除了分享功能之外,小程序还可以通过配置,实现扫描普通二维码跳转特定页面的功能。

以下是微信对此功能的介绍

为了方便小程序开发者更便捷地推广小程序,兼容线下已有的二维码,微信公众平台开放扫描普通链接二维码跳转小程序能力。

功能介绍

普通链接二维码,是指开发者使用工具对网页链接进行编码后生成的二维码。

线下商户可不需更换线下二维码,在小程序后台完成配置后,即可在用户扫描普通链接二维码时打开小程序,使用小程序的功能。
对于普通链接二维码,目前支持使用微信“扫一扫”或微信内长按识别二维码跳转小程序.

二维码规则

根据二维码跳转规则,开发者需要填写需要跳转小程序的二维码规则。要求如下:

  1. 二维码规则的域名须通过ICP备案的验证。
  2. 支持http、https、ftp开头的链接(如:、)。
  3. 一个小程序帐号可配置不多于10个二维码前缀规则。

前缀占用规则

开发者可选择是否占用符合二维码匹配规则的所有子规则。如选择占用,则其他帐号不可申请使用满足该前缀匹配规则的其他子规则。

如:若开发者A配置二维码规则:,并选择“占用所有子规则“,其他开发者将不可以配置满足前缀匹配的子规则如。

我推荐的方式

webview实现方式

  1. 设置跳转功能小程序后台就可以设置,链接是分为四部分,路https://www.example.com/wxmin…。

    https://www.example.com 域名
    /wxmini/ 小程序前置规则,需要在服务器上建一个文件夹,并且把验证文件放在文件夹线
    home.html 需要跳转的网页页面
    a=1 跳转页面的参数
  2. 对onload函数再进行处理,实现普通二维码跳转。

JavaScript

// 对index onLoad在进行处理 onLoad: function (option) {
this.resetOption(option) if (option.urlToken) {
getApp().globalData.urlToken = option.urlToken } if (option.urlData) {
getApp().globalData.urlData = option.urlData } this.setData({ url:
getApp().globalData.urlToken + ‘?’ + getApp().globalData.urlData }) },
resetOption: function (option) { if (!option) { return } if (option.q) {
option.q = decodeURIComponent(option.q) if
(option.q.indexOf(”) == -1) { return }
let tmp = option.q.replace(‘/wxmini’, ”) let tmps = tmp.split(‘?’)
option.urlToken = tmps[0] option.urlData = tmps[1] } else {
option.urlData = decodeURIComponent(option.urlData) } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 对index onLoad在进行处理
onLoad: function (option) {
    this.resetOption(option)
    if (option.urlToken) {
      getApp().globalData.urlToken = option.urlToken
    }
    if (option.urlData) {
      getApp().globalData.urlData = option.urlData
    }
    this.setData({
      url: getApp().globalData.urlToken + ‘?’ +  getApp().globalData.urlData
    })
},
resetOption: function (option) {
    if (!option) {
      return
    }
    if (option.q) {
      option.q = decodeURIComponent(option.q)
      if (option.q.indexOf(‘https://www.example.com/wxmini/’) == -1) {
        return
      }
      let tmp = option.q.replace(‘/wxmini’, ”)
      let tmps = tmp.split(‘?’)
      option.urlToken = tmps[0]
      option.urlData = tmps[1]
    } else {
      option.urlData = decodeURIComponent(option.urlData)
    }
}

跳转:

下面介绍登录页面的逻辑代码:

app上就可以拿到存在data中的参数.

登录后,将会进入开发工具主界面,如图2所示。

返回按钮缺失问题

如果web页面是在第一个页面的话,这时候会有一个问题,小程序的返回按钮就没有了,webview无法使用微信的返回按钮了,这时候只要在webview页面前多加一个跳转页面就好了(第一个页面也可以设置成获取用户权限的页面,不过我感觉这样体验不好,也不是所有页面都要用户获取了权限才可以使用)

最终的页面层级

JavaScript

“pages”: [ “page/index/index”, //
首页,处理onload里的option内容,为了返回按钮设置的 “page/home/index”, //
webview所在的页面 “page/auth/index”, // 获取用户权限的页面
“page/pay/index”, // 支付页面 “page/error/index” // 错误信息页面 ],

1
2
3
4
5
6
7
"pages": [
    "page/index/index", // 首页,处理onload里的option内容,为了返回按钮设置的
    "page/home/index", // webview所在的页面
    "page/auth/index", // 获取用户权限的页面
    "page/pay/index", // 支付页面
    "page/error/index" // 错误信息页面
  ],

页面和tabBar之间跳转:

const Request = require(“../../utils/request”);

Page({

/**

* 页面的初始数据

*/

data: {

route: “/pages/home/home”

},

/**

* 生命周期函数–监听页面加载

*/

onLoad: function {

let self = this;

wx.getStorage({

key: “SYS_PREVIOUSPAGE”,

success: function {

if (res.errMsg === “getStorage:ok”) {

self.setData({

route: “/” + res.data.route,

share: res.data.options

});

}

wx.removeStorage({

key: “SYS_PREVIOUSPAGE”

});

}

});

},

bindgetuserinfo: function {

if (e.detail.errMsg.indexOf > -1) {

wx.showModal({

title: ‘温馨提示’,

content: ‘您未同意授权,系统无法检测您的身份,请允许授权’,

});

} else {

getApp().authorize(this.data.share);

setTimeout => {

if ([“/pages/home/home”, “/pages/course/courselist/courselist”,
“/pages/course/publiclist/publiclist”,
“/pages/consult/consultlist/consultlist”,
“/pages/usercenter/usercenter”].indexOf(this.data.route) > -1) {

wx.switchTab({

url: this.data.route

});

} else {

wx.redirectTo({

url: this.data.route

});

}

}, 800);

}

}

})

 

图片 4

参考链接

  1. webview文档
  2. 小程序unionid介绍
  3. unionid获取方式

    2 赞 2 收藏
    评论

图片 5

wx.switchTab({

login思路:一进入该页面,从缓存中把上一个页面拿出来(读取后需要清除该缓存),然后把登录按钮设置成获取用户信息类型,如

2. wx.navigateTo({})中URL携带参数

我们选择【本地小程序项目】,选择【添加项目】如图3所示。

url:’../index/index’

图片 6设置登录按钮

demo中已经写出:

图片 7

});

点击登录按钮后触发bindgetuserinfo回调,在回调中判断是否授权,没有点击确定授权就提示要授权,有授权就直接调用app.js的授权方法,最后重定向到上一个页面(是重定向不是返回,而且需要注意是不是导航页面

 wx.navigateTo({
      url: “../newpage/newpage?infofromindex=” +
this.data.infofromindex,
  });

创建【HelloWorld】项目,且AppID选择【无AppID】,如图4所示。

页面之间跳转方法:

图片 8登录回调

页面间传递参数的笔记

图片 9

1、保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。

到这里,需要点击按钮才能触发登录已解决。

 

添加项目后,选择【编辑】,将会在开发工具中看到图5所示界面。

wx.navigateTo({   新页面会有返回按钮

PS:需要考虑的问题是,在其他页面,怎么才能知道是否已经完成登录了呢?

3.wx.setStorage(OBJECT) 数据缓存

图片 10

url:’../logs/logs?key=value&key2=value2′ //传参

微信开发文档中的数据缓存方法:

2 项目结构

,

①存储数据

创建小程序项目后,开发工具在根目录(项目路径)中有三个主体文件app.js、app.json、app.wxss和两个文件夹pages、utils。

success: function(res){

 try {
      wx.setStorageSync(‘infofrominput’, this.data.infofrominput)
    } catch (e) {
 }

(1)app.js :是程序主入口的脚本文件(小程序逻辑);

// success

②获取数据

(2)app.json :是全局配置文件(小程序公共设置);

},

  //获取
        wx.getStorage({
            key: ‘infofrominput’,
            success: function (res) {
                _this.setData({
                    infofromstorage: res.data,
                })
            }
        })

(3)app.wxss :是小程序的样式表文件(小程序公共样式表);

fail: function() {

 

(4)pages:所有的页面都在 pages 文件夹中(小程序页面);

// fail

key是本地缓存中的指定的 key,data是需要存储的内容.

(5)utils:存放全局的一些.js文件,公共用到的一些事件处理代码文件可以放到该文件夹下,用于全局调用。

},

详情见微信小程序开发文档:文档

一个小程序主体部分由三个文件组成,必须放在项目的根目录下面。小程序的所有页面放置在pages文件夹中,且每个页面占据一个子文件夹,并由四个文件组成,分别是index.js(页面逻辑)、index.json(页面配置)、index.wxml(页面结构)和index.wxss(页面样式表)。

complete: function() {

 

注意:四个文件名必须和子文件夹一致

// complete

贴上代码:

图片 11

}

1.index.js

在演示项目中,工具自动生成了两个页面,分别是首页面和日志页面。

})

 

3 主体配置文件

2、wx.redirectTo(OBJECT)

[javascript] view
plain copy

使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多
tab 等。

关闭当前页面,跳转到应用内的某个页面。

 

//app.js

wx.redirectTo({   新页面不会有返回按钮

  1. //index.js  
  2. //获取应用实例  
  3. var app = getApp()  
  4. Page({  
  5.   data: {  
  6.     info: app.data.info,  
  7.     infofromindex: ‘来自index.js的信息’,  
  8.     infofrominput: ”  
  9.   },  
  10.   onLoad: function () {  
  11.   },  
  12.   //跳转到新页面  
  13.   gotonewpage: function () {  
  14.     wx.navigateTo({  
  15.       url: “../newpage/newpage?infofromindex=” + this.data.infofromindex,  
  16.     });  
  17.   },  
  18.   //获取输入值  
  19.   searchInputEvent: function (e) {  
  20.     console.log(e.detail.value)  
  21.     this.setData({ infofrominput: e.detail.value })  
  22.   },  
  23.   //保存参数  
  24.   saveinput: function () {  
  25.     try {  
  26.       wx.setStorageSync(‘infofrominput’, this.data.infofrominput)  
  27.     } catch (e) {  
  28.     }  
  29.   }  
  30. })  

App({

url:’../index/index’,

2.index.wxml

onLaunch: function () {//小程序启动的时候就会调用它

,

[html] view
plain copy

//调用API从本地缓存中获取数据,若没有创建一个空数组

success: function(res){

 

var logs = wx.getStorageSync(‘logs’) || []

// success

  1. <!–index.wxml–>  
  2. <view>  
  3. <button style=”background-color:#00ff00;margin:20rpx” bindtap=”gotonewpage”>跳转</button>  
  4. <input  style=”background-color:#eee;margin:20rpx;height:80rpx” placeholder=”请输入需要保存的参数” bindinput=”searchInputEvent” />  
  5. <button style=”background-color:#ff0000;margin:20rpx” bindtap=”saveinput”>存入Storage</button>  
  6. </view>  

logs.unshift(Date.now())//插入当前的日期

},

3.newpage.js

wx.setStorageSync(‘logs’, logs)//内容写入到本地缓存中

fail: function() {

 

},

// fail

 

getUserInfo:function(cb){//获取当前用户登录信息

},

[javascript] view
plain copy

var that = this

complete: function() {

 

if(this.globalData.userInfo){//已登录

// complete

  1. //newpage.js  
  2. //获取应用实例  
  3. var app = getApp()  
  4. Page({  
  5.     data: {  
  6.         infofromapp: app.data.infofromapp,  
  7.         infofromindex: ”,  
  8.         infofromstorage: ”,  
  9.     },  
  10.     onLoad: function (options) {  
  11.         var _this = this;  
  12.         var infofromindex = options.infofromindex;  
  13.         this.setData({  
  14.             infofromindex: infofromindex  
  15.         })  
  16.         //获取  
  17.         wx.getStorage({  
  18.             key: ‘infofrominput’,  
  19.             success: function (res) {  
  20.                 _this.setData({  
  21.                     infofromstorage: res.data,  
  22.                 })  
  23.             }  
  24.         })  
  25.     }  
  26. })  

typeof cb ==

}

4.newpage.wxml

“function” && cb(this.globalData.userInfo)

})

 

}else{

3、x.navigateBack(OBJECT)

 

//调用登录接口

关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages())
获取当前的页面栈,决定需要返回几层。如果 delta
大于现有页面数,则返回到首页。

[html] view
plain copy

wx.login({

varpages = getCurrentPages()varnum = pages.length

 

success: function () {

navigateBack:function(){wx.navigateBack({

  1. <!–newpage.wxml–>  
  2. <view style=”width:100%;margin:30rpx”>infofromapp:{{infofromapp}}</view>  
  3. <view style=”width:100%;margin:30rpx”>infofromindex:{{infofromindex}}</view>  
  4. <view style=”width:100%;margin:30rpx”>infofromstorage:{{infofromstorage}}</view>  

wx.getUserInfo({

delta: num

5.app.js

success: function (res) {

})

 

that.globalData.userInfo = res.userInfo

}

 

typeof cb ==

页面跳转也可直接用 url:

[javascript] view
plain copy

“function” && cb(that.globalData.userInfo)

<navigator url=”../login/login?title=1111″
>跳转到新页面</navigator>

 

}

<navigator url=”../login/login?title=111″
redirect>在当前页打开新页面</navigator>

  1. //app.js  
  2. App({  
  3.   data: {  
  4.     infofromapp: ‘来自APP.js的信息’  
  5.   },  
  6.   onLaunch: function () {  
  7.   
  8.   }  
  9. })  
  10.  

})

如果要传 数组, 字典等复杂类型, 要先用 JSON.stringify()
转成字符串然后传递,接收到之后要用JSON.parse()转换。.

}

取参:

})

Page({

}

onLoad:function(options) {

},

this.setData({       //用于给data中的变量赋值

globalData:{

title: options.key

userInfo:null

})

}

}

})

})

这里初始化了一个 App 对象,并且定义了三个方法 onLaunch,getUserInfo 和
globalData。

数据绑定:

4 app.json

数据绑定使用 Mustache 语法(双大括号)将变量包起来。

{

内容:<view>{{message}}</view>

“pages”:[//工程有两个页面

控制属性:<view wx:if=”{{condition}}”></view>

“pages/index/index”,//第一个元素作为小程序的主页,与index名称无关

关键字:<checkbox checked=”{{false}}”></checkbox>

“pages/logs/logs”

],

http:(微信公众号和小程序上线的话都必须是https请求,小程序接口不允许ip和端口号)

“window”:{

wx.request({ 

“backgroundTextStyle”:”light”,//背景文本类型

 url:’test.php’,//仅为示例,并非真实的接口地址

“navigationBarBackgroundColor”: “#fff”,//导航背景颜色

data: { x:”, y:”},

“navigationBarTitleText”: “WeChat”,//导航文本

 header:
{‘content-type’:’application/json、默认值、或者、、’application/x-www-form-urlencoded’//
}, 

“navigationBarTextStyle”:”black”//导航文字颜色

method:’GET/POST’,

}

 success:function(res){console.log(res.data) }

}

})

这个配置文件中定义了两个节点,【pages】和【window】, pages
是小程序的所有页面对应的路径, window 是小程序窗口的配置信息。

APP.JSON(tabBar)

5 app.wxss

{

相当于css文件

“pages”:[

/**app.wxss**/

“pages/index/index”,

.container {

“pages/tucao/tucao”,

height: 100%;

“pages/center/center”

display: flex;

],

flex-direction: column;

“window”:{

align-items: center;

“backgroundTextStyle”:””,

justify-content: space-between;

“navigationBarBackgroundColor”:”red”,

padding: 200rpx 0;

“navigationBarTitleText”:”一个标题而已”,

box-sizing: border-box;

“navigationBarTextStyle”:”white”

}

},

6 pages文件夹

“tabBar”: {

pahes文件夹中结构如图6所示。

“list”: [{

图片 12

“pagePath”:”pages/index/index”,

其中index和logs文件夹对应app.json中两个页面。

“text”:”首页”,

6.1 index文件夹

“iconPath”:”public/menu-cd.png”,

6.1.1 index.js

“selectedIconPath”:”public/menu.png”

//index.js

},{

//获取应用实例

“pagePath”:”pages/tucao/tucao”,

var app = getApp()//获取app实例,即根目录app.js定义的APP

“text”:”吐槽”,

Page({

“iconPath”:”public/hot-cd.png”,

data: {

“selectedIconPath”:”public/hot.png”

motto: ‘Hello World’,

},{

userInfo: {}

“pagePath”:”pages/center/center”,

},

“text”:”我的”,

//事件处理函数

“iconPath”:”public/center-cd.png”,

bindViewTap: function() {

“selectedIconPath”:”public/center.png”

wx.navigateTo({//页面跳转

}],

url: ‘../logs/logs’

“borderStyle”:”white”

})

}

},

}

onLoad: function () {

console.log(‘onLoad’)

var that = this

//调用应用实例的方法获取全局数据

app.getUserInfo(function(userInfo){

//更新数据

that.setData({

userInfo:userInfo

})

})

}

})

6.1.2 index.wxml

首页面UI

//容器

//绑定点击事件(index.js中定义)

{{userInfo.nickName}}

//motto为pages/index/index.jsp中定义数据

{{motto}}

对应于首页面的一张图片和一句问候语,如图7所示。

图片 13

7 上传小程序

logs 和 index 的页面的基本思路都是一样。 开发完小程序后,我们怎么部署呢?
切换到项目选项卡,然后点击上传按钮即可。

图片 14

由于我的环境没有内测账号,所以在上传区域显示的是项目未关联 AppID,
如果有了测试账号,就会显示你的 AppID 了。
目前只有内测账号才能够上传小程序。这就是唯一的差别了。没有内测账号只是不能上传,但完全可以在本地开发和测试。

网站地图xml地图