额,我觉得这个东西应该叫做数组,有没有更专业的说法,我实在不知道。
惯例,先看效果,只实现数组存储,点击跳转网页,其他的都省略了。
如图可见,这个小程序有两个页面,1是首页index,2是跳转页detail,点击1中的“1-马”可以跳转李贺 的《马》,点击“2-南园”可以跳转李贺的《南园》……
从3中的小程序结构图可以看出,我实现这个功能,不是通过建立N多个网页,而是只有一个detail网页作为跳转页,当我在首页index里点击不同条目的时候,跳转页的内容是随之变化的。
页面跳转如何实现,已经在《详解微信小程序地图组件实例:远征军墓地分布图小程序》这篇教程里说过了。
http://blog.csdn.net/sinat_41310868/article/details/78916811
在这篇教程中,我实现点击marker跳转页面是通过新建同级目录下一页又一页网页实现的,但这么做显然不太规范,也不够智能,十几个网页还行,要是一百来个网页就太可怕了。
所以这篇就讲讲怎么通过数组来存储并调用网页。
内容很简单。
1.定义数组
2.调用数组
1.定义数组:
先讲定义数组。
在远征军墓地分布的程序中,我就想通过数组来实现网页跳转,但当时没成功。
后来多方查找资料,发现数组调用其实稍稍有些限制性和模式化,有点小坑小陷阱。
首先,定义数组,要存储在全局变量中,小程序的全局变量就是app文件中。
下面是app.js的代码,把代码拉到下面可见,我把数组存在globalData: {}中了,zuopins: [{}]中的内容就是。zuopins数组是按照json格式写的,json这种数据交换格式挺规范的,而且调用起来方便。新建的小程序自带快速启动模板中的App.js中就有globalData模块,小程序发布的时候应该就是想让开发者们把全局的数据存放在这里吧。
//app.js
App({
onLaunch: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
// 获取用户信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
globalData: {
zuopins: [{
"name": "马",
"content": "大漠沙如雪,燕山月似钩。何当金络脑,快走踏清秋。"
},{
"name": "南园",
"content": "男儿何不带吴钩,收取关山五十州。请君暂上凌烟阁,若个书生万户侯。"
},{
"name": "雁门太守行",
"content": "黑云压城城欲摧,甲光向日金鳞开。角声满天秋色里,塞上燕脂凝夜紫。半卷红旗临易水,霜重鼓寒声不起。报君黄金台上意,提携玉龙为君死!"
}, {
"name": "浩歌",
"content": "南风吹山作平地,帝遣天吴移海水。王母桃花千遍红,彭祖巫咸几回死。青毛骢马参差钱,娇春杨柳含细烟。筝人劝我金屈卮,神血未凝身问谁。不须浪饮丁都护,世上英雄本无主。买丝绣作平原君,有酒惟浇赵州土。漏催水咽玉蟾蜍,卫娘发薄不胜梳。看见秋眉换新绿,二十男儿那刺促。"
}, {
"name": "致酒行",
"content": "零落栖迟一杯酒,主人奉觞客长寿。主父西游困不归,家人折断门前柳。吾闻马周昔作新丰客,天荒地老无人识。空将笺上两行书,直犯龙颜请恩泽。我有迷魂招不得,雄鸡一声天下白。少年心事当拿云,谁念幽寒坐呜呃。"
}]
}
})
2.调用数组:
数组定义完了,我们看调用。
先看1页面,也就是index这个页面。
先看index.js,这个有点像前端中Dreamweaver的JavaScript,定义页面中的交互动作。
//index.js
//获取应用实例
var app = getApp()
Page({
data: {
zuopin: [],
},
//第一步
onLoad: function (options) {
console.log('加载成功', options)
},
//第二步
onShow: function () {
},
//第三步
onReady: function (e) {
console.log('渲染完成', e)
this.setData({
zuopin: getApp().globalData.zuopins
})
}
})
这里面的代码,加载数据、调用数据都是固定的。
主要看一看,
data: {
zuopin: [],
},
先声明了zuopin这个数组,固定写法是放在data:{}里面。
然后,获取app.js里的zuopins数据,赋给zuopin数组。
this.setData({
zuopin: getApp().globalData.zuopins
})
index.js里面就这些东西。
看index.wxml,这个文件的代码也很简单。
<view wx:for="{{zuopin}}">
<navigator url="./../detail/detail?id={{index}}" >
<view>
<text>{{index+1}}-{{item.name}}text>
view>
navigator>
view>
首先wx:for是一个列表渲染,参考成果可见,就是在页面中把zuopin这个数组列表中,每一条目都遍历一遍。
navigator是一个程序内的导航链接,更多的可以参考官方文档。
https://mp.weixin.qq.com/debug/wxadoc/dev/component/navigator.html
index就是序列号,整个小程序并没有定义过index,也没有定义过item,这段代码的写法是比较固定的,顶多加一个class定义个样式什么的。
detail这个页面是新建的,在pages下新建一个目录detail,然后新建一个页面detail。
detail.js代码:
var app = getApp();
Page({
data: {
id: 0,
loading: false,
details: [],
},
onLoad: function (options) {
this.setData({
id: options.id
})
console.log('options---', options)
console.log('详情', this.data.details)
},
//加载数据
onReady: function (options) {
this.setData({
details: getApp().globalData.zuopins
})
console.log('渲染完成', options)
},
setLoading: function (e) {
this.setData({
loading: !this.data.loading
})
}
})
onload函数的写法应该是固定的,主要目的是id对应上,index上点击的内容跟detail跳转的内容要一致。
onReady也是把app.js中的数组zuopins赋给了details这个数组。
setLoading加载数据。
detail.wxml代码:
<view>
<view>{{details[id].name}}view>
<view>{{details[id].content}}view>
view>
js文件中定义的id用上了,通过id调用数组中的要素,名称name和内容content。
detail.json:
{
"navigationBarTitleText": "作品"
}
这个就是把页面头部的名称改成“作品”。
其他文件都没有变化,wxss都没有写内容,这个主要是为了实现数组网页的调用,所以把与之无关的都删掉了。
这个实例的模板还是可以用来做很多小程序的,作品集,菜谱啥的。