小程序开发备忘

相关资料

小程序简易教程
https://developers.weixin.qq.com/miniprogram/dev/
框架介绍
https://developers.weixin.qq.com/miniprogram/dev/framework/MINA.html
组件介绍
https://developers.weixin.qq.com/miniprogram/dev/component/
Api
https://developers.weixin.qq.com/miniprogram/dev/api/

PART1 构成

小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。
一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下:
文件必需作用
app.js小程序逻辑(配置第一次打开时, 崩溃,后台切换时需要做的逻辑处理)
app.json小程序公共配置 (小程序有哪些页面page, 窗口的背景/颜色, 超时设置等)
app.wxss小程序公共样式表
具体每个页面page是由由四个文件组成,分别是:
文件类型必需作用
js页面逻辑
wxml页面结构
json页面配置
wxss页面样式表
比如整个小程序所有的page的路径信息需要配置到app.json中,举例如下:
{ "pages": [ "pages/login/login", "pages/index/index", "pages/order/order", "pages/solution/solution", "pages/personal/personal", "pages/navigation/navigation", "pages/solutionChart/solutionChart" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" }}
17

17

 

1

{

2

  "pages": [ 

3

    "pages/login/login",

4

    "pages/index/index",

5

    "pages/order/order",

6

    "pages/solution/solution",

7

    "pages/personal/personal",

8

    "pages/navigation/navigation",

9

    "pages/solutionChart/solutionChart"

10

 ],

11

  "window": {

12

    "backgroundTextStyle": "light",

13

    "navigationBarBackgroundColor": "#fff",

14

    "navigationBarTitleText": "WeChat",

15

    "navigationBarTextStyle": "black"

16

 }

17

}

"pages" #用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。

用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径+文件名 信息。文件名不需要写文件后缀,框架会自动去寻找对于位置的 .json, .js, .wxml, .wxss 四个文件进行处理。

数组的第一项代表小程序的初始页面(首页)。小程序中新增/减少页面,都需要对 pages 数组进行修改。

如开发目录为:

├── app.js #整个小程序的通用配置(配置第一次打开时, 崩溃,后台切换时需要做的逻辑处理)├── app.json #小程序公共配置 (小程序有哪些页面page, 窗口的背景/颜色, 超时设置等)├── app.wxss #小程序整体通用公共样式表├── pages #小程序具体的各个子页面目录│   │── index #一个小程序page对应以下4个文件组成 │   │ ├── index.wxml #相当于web的html页面 │   │ ├── index.js #控制页面的逻辑 │   │ ├── index.json #配置本页面的标题,背景等 │   │ └── index.wxss #页面的个性化样式│   └── logs│   ├── logs.wxml│   └── logs.js└── utils #用户自定义用于存放工具类
└── images #用户自定义存放图片路径


则需要在 app.json 中写

{ "pages":[ "pages/index/index",//这里对应的就是pages/index/index.wxml页面 "pages/logs/logs" ]}

"window" #定义小程序所有页面的顶部背景颜色,文字颜色定义等
app.json具体配置项见https://developers.weixin.qq.com/miniprogram/dev/framework/config.html

PART2 逻辑层和视图层

以数据绑定的程序为例
https://developers.weixin.qq.com/s/HofnzKmb6fZe
技术分享图片
index目录就是一个具体的页面, 下面有js,wxml,wxss等文件用来描述index.wxml这个页面
app.json中的pages配置了index这个页面
{ "pages":[ "index/index" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle":"black" }}
12

12

 

1

{

2

  "pages":[

3

    "index/index"

4

 ],

5

  "window":{

6

    "backgroundTextStyle":"light",

7

    "navigationBarBackgroundColor": "#fff",

8

    "navigationBarTitleText": "WeChat",

9

    "navigationBarTextStyle":"black"

10

 }

11

}

12

打开
index.wxml页面
<!--index.wxml-->
<
view
>
{{text}}
</
view
>
<
button

bindtap
=
"changeText">
Change normal data
</
button
>
<
view
>
{{num}}
</
view
>
<
button

bindtap
=
"changeNum">
Change normal num
</
button
>
<
view
>
{{array[0].text}}
</
view
>
<
button

bindtap
=
"changeItemInArray">
Change Array data
</
button
>
<
view
>
{{object.text}}
</
view
>
<
button

bindtap
=
"changeItemInObject">
Change Object data
</
button
>
<
view
>
{{newField.text}}
</
view
>
<
button

bindtap
=
"addNewField">
Add new data
</
button
>

其中<view> 和<button>等分别是小程序提供的视图组件和表单组件, 可以理解为html中的标签
可直接使用并配置相关参数(事件,大小等属性), 并由小程序渲染.

index.js 代码如下

// pages/index/index.jsPage({/*** 页面的初始数据*/data: {array: [‘当天‘, ‘本月‘, ‘近三月‘,‘近半年‘,‘本年‘],index: 0,date: ‘2016-09-01‘,time: ‘12:01‘,barItem: [{name: ‘利润汇总‘,image: ‘../../images/menu1_unfocus.png‘,selectedImage: ‘../../images/menu1_focus.png‘,selected: false,color: ‘#666666‘,url: ‘/pages/solution/solution‘},{name: ‘每日营业情况‘,image: ‘../../images/menu3_unfocus.png‘,selectedImage: ‘../../images/menu3_focus.png‘,selected: true,color:‘#FF0000‘,url: ‘/pages/index/index‘},{name: ‘运营支出‘,image: ‘../../images/menu2_unfocus.png‘,selectedImage: ‘../../images/menu2_focus.png‘,selected: false,color: ‘#666666‘,url: ‘/pages/order/order‘},// {// name: ‘‘,// image: ‘../../images/menu4_unfocus.png‘,// selectedImage: ‘../../images/menu4_focus.png‘,// selected: false,// url: ‘/pages/personal/personal‘// },],successresponseData: [],datalist:[]},//更新日期选型,刷新取值bindPickerChange: function (e) {var that = this;console.log(‘picker发送选择改变,携带值为‘, e.detail.value)this.setData({index: e.detail.value})wx.request({url: require(‘../../config‘).getnumUrl,//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,method: ‘POST‘,header: {‘content-type‘: ‘application/x-www-form-urlencoded‘},data: {gasid: wx.getStorageSync(‘gasid‘),type: e.detail.value},success: function (res) {console.log(‘success‘)console.log(res.data)that.setData({numresponseData: res.data.response,})},fail: function (res) {console.log(‘fail‘)}})wx.request({url: require(‘../../config‘).getsaleUrl,//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,method: ‘POST‘,header: {‘content-type‘: ‘application/x-www-form-urlencoded‘},data: { gasid: wx.getStorageSync(‘gasid‘) },success: function (res) {console.log(‘success‘)console.log(res.data)that.setData({responseData: res.data.response,})var gasnameArr = wx.getStorageSync(‘gasname‘);var gasname;if (gasnameArr.length != 0 && gasnameArr != undefined) {gasname = gasnameArr.join(",");if (gasname.length > 10) {gasname = gasname.substring(0, 10) + "...";}}that.setData({gasname: gasname,gasnameArr: wx.getStorageSync(‘gasname‘),})},fail: function (res) {console.log(‘fail‘)}})},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {let that =this;var gasnameArr = wx.getStorageSync(‘gasname‘);var gasname;if (gasnameArr.length != 0 && gasnameArr != undefined) {gasname = gasnameArr.join(",");if (gasname.length > 10) {gasname = gasname.substring(0, 10) + "...";}}that.setData({gasname: gasname,gasnameArr: wx.getStorageSync(‘gasname‘)})/*wx.request({url: require(‘../../config‘).getsaleUrl,//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,method: ‘POST‘,header: {‘content-type‘: ‘application/x-www-form-urlencoded‘},data: { gasid: wx.getStorageSync(‘gasid‘) },success: function (res) {console.log(‘success‘)console.log(res.data)that.setData({responseData: res.data.response,})},fail: function (res) {console.log(‘fail‘)}}) */wx.request({url: require(‘../../config‘).getnumUrl,//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,method: ‘POST‘,header: {‘content-type‘: ‘application/x-www-form-urlencoded‘},data: {gasid: wx.getStorageSync(‘gasid‘),type:0 //默认值为当天},success: function (res) {console.log(‘success‘)console.log(res.data)that.setData({numresponseData: res.data.response,})},fail: function (res) {console.log(‘fail‘)}})},//加油站点击事件bindButtonTap: function (e) {wx.redirectTo({url: ‘/pages/personal/personal?userid=‘ + wx.getStorageSync(‘userid‘) + ‘&type=1‘,})},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {},/*** 生命周期函数--监听页面显示*/onShow: function () {},/*** 生命周期函数--监听页面隐藏*/onHide: function () {},/*** 生命周期函数--监听页面卸载*/onUnload: function () {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {},/*** 页面上拉触底事件的处理函数*/onReachBottom: function () {},/*** 用户点击右上角分享*/onShareAppMessage: function () {},/*** 菜单单击*/onBarItemClick: function (e) {let url = this.data.barItem[e.currentTarget.dataset.sno].url;if (url == null || url == ‘‘) {return;}wx.redirectTo({url: url})},/*** 导航栏单击*/onNavigation: function () {wx.navigateTo({url: ‘/pages/navigation/navigation‘})},onHotPro2: function(e) {wx.navigateTo({url: ‘/pages/groupLine/groupLine?id=‘ + e.currentTarget.id,})},onHotPro3: function(e) {wx.login({ //调用微信登录接口success: function (res) {wx.setStorageSync("code", res.code)let code = wx.getStorageSync("code")//wx.request({url: ‘http://172.16.16.145:8180/wxService/wx/queryProductDetail‘,method: ‘GET‘,data: {id: 3,},success: function (res) {console.log(‘success‘)console.log(res)},fail: function (res) {console.log(‘fail‘)}});},fail: function () {}});wx.navigateTo({url: ‘/pages/flowPay/flowPay‘,})},onCase1: function(e) {wx.navigateTo({url: ‘/pages/case/case?id=‘ + e.currentTarget.id,})},//输入搜索内容searchmessage: function (e) {this.setData({searchmessage: e.detail.value})},//点击搜索onsearch: function (e) {wx.navigateTo({url: ‘/pages/order/order?productName=‘ + this.data.searchmessage,})},//点击注册regist: function (e) {wx.navigateTo({url: ‘/pages/login/reg/reg‘,})}})
324

324

 

1

// pages/index/index.js

2

Page({

3

4

/**

5

* 页面的初始数据

6

*/

7

data: {

8

array: [‘当天‘, ‘本月‘, ‘近三月‘,‘近半年‘,‘本年‘],

9

index: 0,

10

date: ‘2016-09-01‘,

11

time: ‘12:01‘,

12

barItem: [

13

{

14

name: ‘利润汇总‘,

15

image: ‘../../images/menu1_unfocus.png‘,

16

selectedImage: ‘../../images/menu1_focus.png‘,

17

selected: false,

18

color: ‘#666666‘,

19

url: ‘/pages/solution/solution‘

20

},

21

{

22

name: ‘每日营业情况‘,

23

image: ‘../../images/menu3_unfocus.png‘,

24

selectedImage: ‘../../images/menu3_focus.png‘,

25

selected: true,

26

color:‘#FF0000‘,

27

url: ‘/pages/index/index‘

28

},

29

{

30

name: ‘运营支出‘,

31

image: ‘../../images/menu2_unfocus.png‘,

32

selectedImage: ‘../../images/menu2_focus.png‘,

33

selected: false,

34

color: ‘#666666‘,

35

url: ‘/pages/order/order‘

36

},

37

// {

38

// name: ‘‘,

39

// image: ‘../../images/menu4_unfocus.png‘,

40

// selectedImage: ‘../../images/menu4_focus.png‘,

41

// selected: false,

42

// url: ‘/pages/personal/personal‘

43

// },

44

],

45

successresponseData: [],

46

datalist:[]

47

},

48

49

//更新日期选型,刷新取值

50

bindPickerChange: function (e) {

51

52

var that = this;

53

console.log(‘picker发送选择改变,携带值为‘, e.detail.value)

54

this.setData({

55

index: e.detail.value

56

})

57

wx.request({

58

url: require(‘../../config‘).getnumUrl,

59

//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,

60

method: ‘POST‘,

61

header: {

62

‘content-type‘: ‘application/x-www-form-urlencoded‘

63

},

64

65

data: {

66

gasid: wx.getStorageSync(‘gasid‘),

67

type: e.detail.value

68

},

69

success: function (res) {

70

console.log(‘success‘)

71

console.log(res.data)

72

that.setData({

73

numresponseData: res.data.response,

74

})

75

},

76

fail: function (res) {

77

console.log(‘fail‘)

78

}

79

80

})

81

wx.request({

82

url: require(‘../../config‘).getsaleUrl,

83

//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,

84

method: ‘POST‘,

85

header: {

86

‘content-type‘: ‘application/x-www-form-urlencoded‘

87

},

88

data: { gasid: wx.getStorageSync(‘gasid‘) },

89

success: function (res) {

90

console.log(‘success‘)

91

console.log(res.data)

92

that.setData({

93

responseData: res.data.response,

94

})

95

var gasnameArr = wx.getStorageSync(‘gasname‘);

96

var gasname;

97

if (gasnameArr.length != 0 && gasnameArr != undefined) {

98

gasname = gasnameArr.join(",");

99

if (gasname.length > 10) {

100

gasname = gasname.substring(0, 10) + "...";

101

}

102

}

103

that.setData({

104

gasname: gasname,

105

gasnameArr: wx.getStorageSync(‘gasname‘),

106

})

107

},

108

fail: function (res) {

109

console.log(‘fail‘)

110

}

111

112

})

113

114

115

116

117

},

118

/**

119

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

120

*/

121

onLoad: function (options) {

122

let that =this;

123

var gasnameArr = wx.getStorageSync(‘gasname‘);

124

var gasname;

125

if (gasnameArr.length != 0 && gasnameArr != undefined) {

126

gasname = gasnameArr.join(",");

127

if (gasname.length > 10) {

128

gasname = gasname.substring(0, 10) + "...";

129

}

130

}

131

that.setData({

132

gasname: gasname,

133

gasnameArr: wx.getStorageSync(‘gasname‘)

134

})

135

/*wx.request({

136

url: require(‘../../config‘).getsaleUrl,

137

//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,

138

method: ‘POST‘,

139

header: {

140

‘content-type‘: ‘application/x-www-form-urlencoded‘

141

},

142

143

data: { gasid: wx.getStorageSync(‘gasid‘) },

144

success: function (res) {

145

console.log(‘success‘)

146

console.log(res.data)

147

that.setData({

148

responseData: res.data.response,

149

})

150

},

151

fail: function (res) {

152

console.log(‘fail‘)

153

}

154

155

}) */

156

157

158

159

wx.request({

160

url: require(‘../../config‘).getnumUrl,

161

//url: ‘http://localhost:8081/framework-protal/main/gas/getsale‘,

162

method: ‘POST‘,

163

header: {

164

‘content-type‘: ‘application/x-www-form-urlencoded‘

165

},

166

167

data: {

168

gasid: wx.getStorageSync(‘gasid‘),

169

type:0 //默认值为当天

170

},

171

success: function (res) {

172

console.log(‘success‘)

173

console.log(res.data)

174

that.setData({

175

numresponseData: res.data.response,

176

})

177

},

178

fail: function (res) {

179

console.log(‘fail‘)

180

}

181

182

})

183

184

185

},

186

//加油站点击事件

187

bindButtonTap: function (e) {

188

wx.redirectTo({

189

url: ‘/pages/personal/personal?userid=‘ + wx.getStorageSync(‘userid‘) + ‘&type=1‘,

190

})

191

},

192

/**

193

* 生命周期函数--监听页面初次渲染完成

194

*/

195

onReady: function () {

196

},

197

198

/**

199

* 生命周期函数--监听页面显示

200

*/

201

onShow: function () {

202

},

203

204

/**

205

* 生命周期函数--监听页面隐藏

206

*/

207

onHide: function () {

208

},

209

210

/**

211

* 生命周期函数--监听页面卸载

212

*/

213

onUnload: function () {

214

},

215

216

/**

217

* 页面相关事件处理函数--监听用户下拉动作

218

*/

219

onPullDownRefresh: function () {

220

},

221

222

/**

223

* 页面上拉触底事件的处理函数

224

*/

225

onReachBottom: function () {

226

},

227

228

/**

229

* 用户点击右上角分享

230

*/

231

onShareAppMessage: function () {

232

},

233

234

/**

235

* 菜单单击

236

*/

237

onBarItemClick: function (e) {

238

let url = this.data.barItem[e.currentTarget.dataset.sno].url;

239

if (url == null || url == ‘‘) {

240

return;

241

}

242

wx.redirectTo({

243

url: url

244

})

245

},

246

/**

247

* 导航栏单击

248

*/

249

onNavigation: function () {

250

wx.navigateTo({

251

url: ‘/pages/navigation/navigation‘

252

})

253

},

254

255

onHotPro2: function(e) {

256

wx.navigateTo({

257

url: ‘/pages/groupLine/groupLine?id=‘ + e.currentTarget.id,

258

})

259

},

260

261

onHotPro3: function(e) {

262

263

264

wx.login({ //调用微信登录接口

265

success: function (res) {

266

wx.setStorageSync("code", res.code)

267

let code = wx.getStorageSync("code")

268

//

269

wx.request({

270

url: ‘http://172.16.16.145:8180/wxService/wx/queryProductDetail‘,

271

method: ‘GET‘,

272

273

data: {

274

id: 3,

275

},

276

success: function (res) {

277

console.log(‘success‘)

278

console.log(res)

279

},

280

fail: function (res) {

281

console.log(‘fail‘)

282

}

283

});

284

},

285

fail: function () {

286

287

}

288

});

289

290

291

292

293

294

wx.navigateTo({

295

url: ‘/pages/flowPay/flowPay‘,

296

})

297

},

298

299

onCase1: function(e) {

300

301

wx.navigateTo({

302

url: ‘/pages/case/case?id=‘ + e.currentTarget.id,

303

})

304

},

305

//输入搜索内容

306

searchmessage: function (e) {

307

this.setData({

308

searchmessage: e.detail.value

309

})

310

},

311

//点击搜索

312

onsearch: function (e) {

313

314

wx.navigateTo({

315

url: ‘/pages/order/order?productName=‘ + this.data.searchmessage,

316

})

317

},

318

//点击注册

319

regist: function (e) {

320

wx.navigateTo({

321

url: ‘/pages/login/reg/reg‘,

322

})

323

}

324

})

index.js中的data属性用于配置页面第一次渲染使用的初始数据.
页面加载时,
data
 将会以
JSON
字符串的形式由逻辑层传至渲染层,因此
data
中的数据必须是可以转成
JSON
的类型:字符串,数字,布尔值,对象,数组。

举例代码中data定义了text 和array

Page({ data: { text: ‘init data‘, array: [{msg: ‘1‘}, {msg: ‘2‘}] }})

对应index.wxml中的

<view>{{text}}</view><view>{{array[0].msg}}</view>
页面初始化的时候小程序会自动从js的data中加载对应的text和array数据初始化显示到{{}}中.
 
< view > {{text}} </ view >
< button bindtap = "changeText"> Change normal data </ button >
wxml中在按钮上配置的changeText定了点击对应的函数,在js中对应changeText()方法中:

 changeText: function () { // this.data.text = ‘changed data‘ // bad, it can not work console.log(this.data.text); var text2="hola baby"; this.setData({ text: text2, }) console.log(this.data.text); }
9

9

 

1

  changeText: function () {

2

    // this.data.text = ‘changed data‘ // bad, it can not work

3

    console.log(this.data.text);

4

    var text2="hola baby";

5

    this.setData({

6

      text: text2,

7

   })

8

    console.log(this.data.text);

9

 }

 
可以通过this.setData来修改text的值.在changeText中通过 this.data.text可以获取到初始化设置的data中的属性的text的值

Page({ data: { text: ‘init data‘, array: [{msg: ‘1‘}, {msg: ‘2‘}] }})
6

6

 

1

Page({

2

  data: {

3

    text: ‘init data‘,

4

    array: [{msg: ‘1‘}, {msg: ‘2‘}]

5

 }

6

})

以本例
 
技术分享图片
第一次打印的是index.js中data中设置的text初始化的值( this .data.text ) 为 init data
通过this.setData()方法中修改text后, 重新打印 this .data.text的值即变为了我们设置的hola baby
通过this.setData()修改text成功后, 对应页面上的值也会自动改变.

this.setData解释:

Page.prototype.setData(Object data, Function callback)

setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。

以上可见对应的视图层控制在wxml中 逻辑控制在js中

引用官方的说明如下: 视图层(由wxml, wxss,wxs等来支持实现): 

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/

WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。

它支持数据绑定, 列表渲染,条件渲染,模版 事件, 引用等.

引用官方的说明如下: 逻辑层(由页面的js, 小程序api等来支持实现): 

https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/

其中小程序提供的api说明如下:

小程序开发框架提供丰富的微信原生 API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。

小程序原生API类型如下:
  • 事件监听 (我们约定,以 on 开头的 API 用来监听某个事件是否触发,如:wx.onSocketOpen 监听 WebSocket 连接打开事件,wx.onCompassChange 等。)
  • 同步API (如 wx.setStorage 数据存储:将数据存储在本地缓存中指定的 key 中。数据存储生命周期跟小程序本身一致)
  • 异步API (如wx.setStorageSync 异步的数据存储, 如wx.request 发起异步网络请求)

以上我们可以通过api进行小程序全局的本地数据存储和获取, 或者发起http请求
比如在小程序页面打开的时候加载后台数据:
在页面index.js的
onLoad:
function
(options) {}监听页面加载自动调用的onload方法中
通过wx:request请求后台数据

var that = this;
wx.request({ //请求后台数据
    
url:
require
(
‘../../config‘
).getregistcostlistUrl,
    
method:
‘POST‘
,
    
header: {
    
    
‘content-type‘
:
‘application/x-www-form-urlencoded‘
    
},
    
data: { //向后台数据发送的请求参数
    
    
id: wx.getStorageSync(
‘gasid‘
), //以id为name,value为全局缓存中key为gasid的值, 发送给后台
    
    
type
:
3
    
},
    
success:
function
(res) { //请求成功后的回调方法
    
    
that.setData({
           
responseData: res.data  //将请求成功的值,通过this.setData 修改保存到responseData中, 这里的responseData对应可以下wxml中{{responseData}}来同步显示.甚至如果responseData是对象,我们可以新增属性responseData.name responseData.pwd而不需要预先定义.
      
})
    
let
a =
0
;
    
    
for
(
let
i =
0
; i < res.data.length; i++) {
    
    
a = a + res.data[i].total
    
}
    
that.setData({
    
    
total: a
    
})
    
},
    
fail:
function
(res) {
    
console.log(
‘fail‘
)
    
}
 
})


以功能多选为例
技术分享图片
<block wx:for="{{responseData}}" wx:key="{{responseData}}"> <view class=‘content‘ id=‘{{item.id}}‘ data-text="{{item.name}}" name=‘{{item.name}}‘ bindtap=‘itemSelected‘> <text>{{item.name}}</text> <image id=‘img-{{item.id}}‘ class=‘select_icon‘ src="{{item.isSelected?‘../../images/selected.png‘:‘‘}}"></image> {{iconVar}} </view></block>
x

1

<block wx:for="{{responseData}}" wx:key="{{responseData}}">

2

 <view class=‘content‘ id=‘{{item.id}}‘ data-text="{{item.name}}" name=‘{{item.name}}‘ bindtap=‘itemSelected‘>

3

  <text>{{item.name}}</text> 

4

  <image id=‘img-{{item.id}}‘ class=‘select_icon‘ src="{{item.isSelected?‘../../images/selected.png‘:‘‘}}"></image>

5

 {{iconVar}}

6

 </view>

7

</block>

responseData为数据集合被循环.

item为循环变量, item.name为加油站的名字, view中的
data-
text后台函数就可以通过
 var name = e.currentTarget.dataset.
text; 来获取值. 这是小程序约定的数据传递绑定方式.
//选中 itemSelected: function (e) { var id = e.currentTarget.id;//e.currentTarget.dataset.index;//当前选中加油站的id var name = e.currentTarget.dataset.text; var replyLikeArr = this.data.replyLike; var replyLikeNameArr = this.data.replyLikeName; //初次加载的加油站对象数据通过onload方法中的this.setData保存在responseData中 //而wxml中有{{responseData}}, 所以我们可以通过this.data.responseData获取 for (var i = 0; i < this.data.responseData.length; i++) { if (this.data.responseData[i].id==id){ var item = this.data.responseData[i];//遍历加油站集合,将结合中与将当前选中的加油站id相同的那个对象获取到 if(!item.isSelected){ //加油站一开始并没有isSelected属性,这里第一次肯定是false.本段代码执行后,加油站对象就多了一个isSelect属性,默认值为false if (replyLikeArr.length > 2) { wx.showToast({ title: ‘选择不可超过3个‘, icon: ‘loading‘, duration: 2000 }) return; } } item.isSelected = !item.isSelected; //将加油站选中的标记属性isSelect置为相反 if (item.isSelected){ //如果加油站被选中的属性为是,这将其id和名字放入新的集合变量中 replyLikeArr.push(id); replyLikeNameArr.push(item.name); }else{//如果加油站被选中的属性为否,这将其id和名字从选中集合变量中删除 replyLikeArr.splice(replyLikeArr.indexOf(id),1); replyLikeNameArr.splice(replyLikeNameArr.indexOf(item.name),1); } break; } } this.setData({ //务必通过setData修改以上操作.否则新增isSelect属性或者修改isSelect属性的值都不会发生变化 responseData: this.data.responseData, replyLike: replyLikeArr, replyLikeName: replyLikeNameArr }); },
40

40

 

1

//选中

2

  itemSelected: function (e) {

3

    var id = e.currentTarget.id;//e.currentTarget.dataset.index;//当前选中加油站的id

4

    var name = e.currentTarget.dataset.text;

5

    var replyLikeArr = this.data.replyLike;

6

    var replyLikeNameArr = this.data.replyLikeName;

7

    //初次加载的加油站对象数据通过onload方法中的this.setData保存在responseData中

8

    //而wxml中有{{responseData}}, 所以我们可以通过this.data.responseData获取

9

    

10

    for (var i = 0; i < this.data.responseData.length; i++) {

11

      if (this.data.responseData[i].id==id){

12

        var item = this.data.responseData[i];//遍历加油站集合,将结合中与将当前选中的加油站id相同的那个对象获取到

13

        if(!item.isSelected){ //加油站一开始并没有isSelected属性,这里第一次肯定是false.本段代码执行后,加油站对象就多了一个isSelect属性,默认值为false

14

          if (replyLikeArr.length > 2) {

15

            wx.showToast({

16

              title: ‘选择不可超过3个‘,

17

              icon: ‘loading‘,

18

              duration: 2000

19

           })

20

            return;

21

         }

22

       }

23

        item.isSelected = !item.isSelected; //将加油站选中的标记属性isSelect置为相反

24

        if (item.isSelected){ //如果加油站被选中的属性为是,这将其id和名字放入新的集合变量中

25

            replyLikeArr.push(id);

26

            replyLikeNameArr.push(item.name);

27

       }else{//如果加油站被选中的属性为否,这将其id和名字从选中集合变量中删除

28

          replyLikeArr.splice(replyLikeArr.indexOf(id),1);

29

          replyLikeNameArr.splice(replyLikeNameArr.indexOf(item.name),1);

30

       }

31

       break;

32

     }

33

   }

34

    this.setData({

35

        //务必通过setData修改以上操作.否则新增isSelect属性或者修改isSelect属性的值都不会发生变化

36

      responseData: this.data.responseData,

37

      replyLike: replyLikeArr,

38

      replyLikeName: replyLikeNameArr

39

   });

40

 },

变量replyLikeArr和replyLikeNameArr被定义在page:data中从来存放被选中的加油站的id和名字.
通过wxml中的

<
image

id
=
‘img-{{item.id}}‘

class
=
‘select_icon‘

src
=
"{{item.isSelected?‘../../images/selected.png‘:‘‘}}"></
image
>
可见,如果加油站一开始没有isSelect属性或者属性为false就不会出现选中的图片.

这里展示了如何循环遍历, 如果在方法中获取页面上的传值, 如何在方法中获取页面的数据并修改,并且显示了如果通过修改页面的值同同时控制页面效果.这个效果是基于小程序页面数据绑定单向的这一特性(修改页面的属性,这页面上的值也会自动变化).
另外如需跨页面传值可通过跳转时url绑定或者api的wx.setStorage(key,object
) 来实现. 特别是wx.setStorage和wx.getStorage可实现整个小程序内部的本地缓存数据的存放和读取.

同样图标选中变红的效果
技术分享图片
<view class="layout_horizontal" style=‘float:left; width:80%;‘> <block wx:for="{{responseData}}" wx:key="{{responseData}}" wx:for-item="item" wx:for-index="index"> <view bindtap="chooseGood" style=‘display:inline-block; width:23%; margin-left:2%;‘ data-index="{{index}}" data-goodId="{{item.goodid}}"> <button class="{{index==idx?‘btnRed‘:‘btn1‘}}" >{{item.goodname}}</button> </view></block></view>
x

 

1

<view class="layout_horizontal" style=‘float:left; width:80%;‘>

2

  <block wx:for="{{responseData}}" 

3

    wx:key="{{responseData}}" 

4

    wx:for-item="item" wx:for-index="index">

5

    <view  bindtap="chooseGood" 

6

       style=‘display:inline-block; width:23%; margin-left:2%;‘ 

7

         data-index="{{index}}" data-goodId="{{item.goodid}}">

8

     <button class="{{index==idx?‘btnRed‘:‘btn1‘}}" >{{item.goodname}}</button>

9

    </view>

10

</block>

11

</view>

点击后调用了chooseGood方法
到对应页面的js中将查看方法
 //选择产品类型,同时更新数据更新报表 chooseGood: function (e) { let index = e.currentTarget.dataset.index; var goodid = e.currentTarget.dataset.goodid;//所选产品类型的id this.setData({ idx: index }) wx.setStorageSync("chooseGoodid", goodid); this.getXYData(); },
x

 

1

 //选择产品类型,同时更新数据更新报表

2

  chooseGood: function (e) {

3

    let index = e.currentTarget.dataset.index;

4

    var goodid = e.currentTarget.dataset.goodid;//所选产品类型的id

5

    this.setData({

6

      idx: index

7

   })

8

    wx.setStorageSync("chooseGoodid", goodid);

9

    this.getXYData();

10

 },

页面上有data-goodId="{{item.goodid}} 和 data-index="{{index}}" 其中index是循环的索引(从0开始)
所以我们可以通过e.currentTarget.dataset.index和e.currentTarget.dataset.goodid来获取值
我们在页面上定义如果index为idx则样式为
btnRed(被选中) 否则为btn1样式(没被选中)
<button class="{{index==idx?‘btnRed‘:‘btn1‘}}" >{{item.goodname}}</button>
此时只需要在js中将
idx的值改为当前索引值即可. 此时被选中的商品的索引传给了idx,页面上
它的索引值就和idx一致,它就会使用
btnRed的样式,表示为被选中.

而效果
技术分享图片
点击显示隐藏的其他数据并将整体其他view下移可通过计算
一开始获取商品类型如果超过4个,则数组另存为responseData 并截取只保留4个显示.
点击按钮更多时,判断本地缓存中wx.getStorageSync(‘goodsType‘)
商品类型数量,
如果超过4个则修改样式
size = responseData.length / 4;
size = size * 60;
对应wxml中
<
view

style
=
‘font-size:20rpx ;width:100% ;display: flex;margin-left:3%;margin-top:{{moveSize}}rpx‘>
moveSize变量初始在page.data设为0,此时即可通过上外距撑开.
反之,再次点击图标,则会收缩.隐藏商品类型,只显示4个.
此时将本地缓存中商品类型截取, 保留4个并复制给页面上的需要遍历的变量.
并将需要下拉的外边距变量moveSize的值改为0即可.
这些操作后都需要this.setData来保存.
 moreGoods: function () { var objArrAll = wx.getStorageSync(‘goodsType‘); var responseData=this.data.responseData; var size = 0; var ifMore = this.data.ifMore; //一开始没有这多个属性的话此时会新增属性,默认值为false //商品类型超过4个才有展开的需求 if (objArrAll.length>4){ if (ifMore){//已展开,则菜单进行收缩操作 //size默认已值为0 responseData = responseData.slice(0,4); ifMore=false;//标记为未展开 }else{ //未展开, 则对菜单进行展开操作 responseData = objArrAll; //将全部商品赋给需要显示的遍历的对象 ifMore = true;//标记展开 //修改样式 size = responseData.length / 4; size = size * 60; } } this.setData({ responseData, moveSize: size, ifMore, }) },
x

 

1

  moreGoods: function () {

2

    var objArrAll = wx.getStorageSync(‘goodsType‘);

3

    var responseData=this.data.responseData;

4

    var size = 0;

5

    var ifMore = this.data.ifMore; //一开始没有这多个属性的话此时会新增属性,默认值为false

6

    //商品类型超过4个才有展开的需求

7

    if (objArrAll.length>4){

8

      if (ifMore){//已展开,则菜单进行收缩操作

9

       //size默认已值为0

10

        responseData = responseData.slice(0,4);

11

        ifMore=false;//标记为未展开

12

     }else{ //未展开, 则对菜单进行展开操作

13

        responseData = objArrAll; //将全部商品赋给需要显示的遍历的对象

14

        ifMore = true;//标记展开

15

        //修改样式

16

        size = responseData.length / 4;

17

        size = size * 60;

18

     }

19

   }

20

21

    this.setData({

22

      responseData,

23

      moveSize: size,

24

      ifMore,

25

   })

26

 },


来自为知笔记(Wiz)

相关文章