版权声明:本文由贺嘉 原创文章,转载请注明出处: 
文章原文链接:https://www.qcloud.com/community/article/431172001487671163

来源:腾云阁 https://www.qcloud.com/community

如何用Baas快速在腾讯云上开发小程序-系列4:实现客户侧商品列表、商品详情页程序

一、实验简介
通过实现商品列表、商品详情页程序,熟练掌握云端数据表查询操作。

二、实验目标

  1. 掌握小程序调试方法
  2. 掌握小程序操作云端数据方法
  3. 掌握云端数据表增删改查操作

三、实验步骤
3.1 Hello World

  1. 应用设置
    第一步: 修改 app.js ,初始化全局对象

    1. App({
    2. onLaunch: function () {
    3. // 创建 xpm 对象
    4. this.xpm = require('xpmjs/xpm.js').option({
    5. 'host':'wss.appcook.cn',
    6. 'https':'wss.appcook.cn',
    7. 'wss': 'wss.appcook.cn/ws-server',
    8. 'table.prefix': 'hello',
    9. 'user.table':'user'
    10. });
      12.
    11. // 创建全局对象 this.wss = this.xpm.require('wss'); // 信道
    12. this.session = this.xpm.require('session'); // 会话
    13. this.stor = this.xpm.require('stor'); // 存储17. this.utils = this.xpm.require('utils'); // 工具
    14. this.user = this.xpm.require('user'); // 用户19. },
    15. xpm:null,
    16. user:null,
    17. utils:null,
    18. session:null,
    19. stor:null,
    20. wss:null
    21. })

第二步: 修改 app.json 添加页面清单,修改标题栏默认属性

1. {
2. "pages":[
3. "pages/index/index"
4. ],
5. "window":{
6. "backgroundTextStyle":"light",
7. "navigationBarBackgroundColor": "#ffffff",
8. "navigationBarTitleText": "Hello World",
9. "navigationBarTextStyle":"black"
10. }
11. }

第三步: 修改 app.wxss 设定全局样式

1. .container {
2. height: 100%;
3. display: flex;
4. flex-direction: column;
5. align-items: center;
6. justify-content: space-between;
7. padding: 100rpx 0;
8. box-sizing: border-box;
9. }

2. 用户登录
第一步: 修改 pages/index/index.js 用户登录代码

1. var app = getApp();
2. Page({
3. data: {
4. hello: 'hello world',
5. userInfo: {
6. avatarUrl:'http://of2is3ok3.bkt.clouddn.com/nopic.gif',
7. nickName:'载入中..'
8. }
9. },
10. onLoad: function () {
11. var that = this;
12. app.user.login().then(function( uinfo ){
13. that.setData({userInfo:uinfo});
14. });
15. }
16. });

第二步: 修改 pages/index/index.wxml 更新页面布局

> 1. <view class="container">
> 2. <view bindtap="bindViewTap" class="userinfo">
> 3. <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" backgro und-size="cover"></image>
> 4. <text class="userinfo-nickname">{{userInfo.nickName}}</text>
> 5. </view>
> 6. <view class="usermotto">
> 7. <text class="user-motto">{{hello}}</text>
> 8. </view>
> 9. </view>

第三步: 修改 pages/index/index.wxss 微调页面样式

1. .userinfo {
2. display: flex;
3. flex-direction: column;
4. align-items: center;
5. }
6.
7. .userinfo-avatar {
8. width: 128rpx;
9. height: 128rpx;
10. margin: 20rpx;
11. border-radius: 50%;
12. }
13.
14. .userinfo-nickname {
15. color: #aaa;
16. }
17.
18. .usermotto {
19. margin-top: 120px;
20. }

第五步: 修改 pages/index/index.json 设置页面名称

1. {
2. "navigationBarTitleText": "用户登录

效果预览: 通过微信开发者工具,通过模拟器可以实时预览效果

3.2 商品列表页
1. 全局样式表
在小程序中有两种方式使用全局样式。在 app.wxss中定义的样式为全局样式;也可以通过
@import "common.wxss"; 方法引用样式表文件。为了便于修改前台样式,我们定义一个通用的样式文件 pages/wxss/style.wxss 。
创建 pages/store/wxss/style.wxss 前台通用样式文件; 下为代码片段,完成代码参见源码。

1. view {
2. color:#232323;
3. font-size:32rpx;
4. }
5.
6. button[type="primary"][plain] {
7. border: 1px solid #81c7d1;
8. color: #81c7d1;
9. }
10.
11. button[type="primary"] {
12. color:#FFFFFF;
13. background-color:#81c7d1;
14. }
15.
16. .topbar{
17. background: #f5f5f5;
18. line-height: 64rpx;
19. position: fixed;
20. width: 100%;
21. z-index: 1000;
22. border-bottom: 2rpx solid #e1e1e1;
23. }
24. ...

2. 购物车布局
因为有多个页面,用到了购物车底栏; 所以将购物车布局代码抽离成独立文件使用

标签引入。
创建购物车 pages/store/common/cart.wxml 代码文件。

1. <view class="bottombar view-row">
2. <view style="width:88rpx;">
3. <image mode="widthFix" src="/res/icons/shop.png"></image>
4. </view>
5. <view style="width:40%">
6. <text style="padding-left:20rpx;"> {{cart.total}} 件商品 {{cart.show
_price}} 元 </text>
7. </view>
8. <view class="text-right" style="width:50%">
9.
10. <button
11. class="push-t-10 push-r-10"
12. type="default" size="mini" loading="{{loading}}"
13. disabled="{{disabled}}"
14. bindtap="cleanup"> 清空 </button>
15. <button
16. class="push-t-10 push-r-10"
17. type="warn" size="mini" loading="{{loading}}"
18. disabled="{{disabled}}"
19. data-link="{{order}}" bindtap="payout"> 结算 </button>
20. </view>
21. </view>

3. 购物车、商品信息过滤功能模块
对于不同会员来说,每件商品有不同价格,商品信息过滤功能和购物车也在多个页面用到,将购物车、商品信息过滤等功能封装成对象,在不同页面中复用。
创建 utils 目录, 创建 goods.js 文件

1. function Goods( user, session ) {
2.
3. var that = this;
4.
5. this.user = user;
6. this.ss = session;
7. this.sname = '_cart_' + this.user['_id'];
8. this.suinfo = '_cart_' + this.user['_id'] + '_uinfo';
9.
10.
11. // 生成订号
12. this.genOrderSN = function() {
13. var timestamp = (new Date()).valueOf();
14. return timestamp.toString() + Math.ceil(Math.random()*1000).toS
tring();
15. }
16.
17.
18. // 根据会.信息, 处理价格
19. this.price = function( real_price ) {
20. return real_price['member'];
21. }
22.
23.
24. // 处理商品字段
25. this.fliter = function( goods ) {
26.
27. for( var i =0 ; i<goods.length; i++ ) {
28. var price = new Number(this.price(goods[i]['real_price']));
29. goods[i]['sale_price'] = price;
30. goods[i]['show_price'] = (price/100).toFixed(2).toString();
31. }
32.
33. return goods;
34. }
35.
36. this.cart = {
37.
38. order: function( data ) {
39. var cdata = that.ss.get(that.suinfo) || {};
40.
41. if ( typeof data != 'object' ) {
42. cdata['address'] = cdata['address'] || that.user['addr_
01'];
43. cdata['mobile'] = cdata['mobile'] || that.user['mobile'
];
44. cdata['contact'] = cdata['contact'] || that.user['nickN
ame'];
45. that.ss.set(that.suinfo, cdata);
46. } else {
47. cdata['address'] = data['address'] || cdata['address'];
48. cdata['mobile'] = data['mobile'] || cdata['mobile'];
49. cdata['contact'] = data['contact'] || cdata['contact'];
50. that.ss.set(that.suinfo, cdata);
51. }
52.
53. return cdata;
54. },
55.
56.
57. add: function( id, price, amount ) {
58.
59. var data = that.ss.get(that.sname) || {};
60.
61. if ( typeof data[id] == 'object' ) {
62. data[id]['amount'] = new Number(data[id]['amount'])
+ new Number(amount);
63. } else {
64. data[id] = { id:id, price:price, amount:amount };
65. }
66. that.ss.set(that.sname, data);
67. },
68.
69.
70. rm: function( id, amount ) {
71. var data = that.ss.get(that.sname) || {};
72.
73. if ( typeof data[id] == 'undefined' ) {
74. return;
75. }
76.
77. data[id]['amount'] = new Number(data[id]['amount']) - new N
umber(amount);
78. if ( data[id]['amount'] <= 0 ) {
79. try { delete data[id] } catch( e ){}
80. }
81. that.ss.set(that.sname, data);
82. },
83.
84. remove: function( id ) {
85. var data = that.ss.get(that.sname) || {};
86. try { delete data[id] } catch( e ){}
87. that.ss.set(that.sname, data);
88. },
89.
90. clean: function(){
91. that.ss.set(that.sname, {});
92. },
93.
94. total: function() {
95. var amt=0, fee=0, show='0.00';
96. var data = that.ss.get(that.sname) || {};
97.
98. for( var k in data ) {
99. var iamt = new Number(data[k]['amount']);
100. amt = new Number(amt) + iamt;
101. fee = new Number(fee) + ( new Number(data[k]['price']) *
iamt );
102. }
103.
104. var price = new Number(fee);
105. show = (price/100).toFixed(2).toString();
106. return {total:amt, sale_price:fee, show_price:show };
107. },
108.
109. get: function() {
110. return that.ss.get(that.sname) || {};
111. }
112. }
113.
114. }
115.
116. module.exports = Goods;

4. 商品列表页
创建 pages/store/products 目录,在目录下创建 list.js , list.wxml 和 list.wxss 文件。
第一步: 将页面添加到 app.json

1. {
2. "pages":[
3. "pages/store/products/list",
4. "pages/index/index",
5. "pages/logs/logs",
6. "admin/table/index"
7. ],
8. "window":{
9. "backgroundTextStyle":"light",
10. "navigationBarBackgroundColor": "#fff",
11. "navigationBarTitleText": "Hello World",
12. "navigationBarTextStyle":"black"
13. }
14. }

第二步: 修改 pages/store/products/list.wxml 页面布局

1. <scroll-view scroll-y="true" style="height:{{system.windowHeight}}px;">
2. <view class="table-list">
3. <view class="row border-item-1 pad-10" style="padding-top:26
rpx;" wx:for="{{goods}}" wx:key="_id" >
4. <view style="width:200rpx;" class="push-r-10"> <image
bindtap="detail" data-id="{{item._id}}" mode="widthFix" src="{{item.
corver}}"></image> </view>
5. <view style="width:50%" class="push-r-10"><text bindtap="de
tail" data-id="{{item._id}}" class="font-s15">{{item.name}}</text>
</view>
6. <view style="width:30%" class="push-r-10 push-t-10"> <text
bindtap="detail" data-id="{{item._id}}" class="textprimary">{{
item.show_price}}</text> </view>
7. <view style="width:30%;min-width:160rpx;">
8. <button type="primary" size="mini" bindtap="addtocard"
9. data-id="{{item._id}}"
10. data-price="{{item.sale_price}}"
11. data-amount="1"
12. bindtap="addtocart">购买</button>
13. </view>
14. </view>
15.
16. <view class="row border-item-1 pad-10 {{goodsLoading}}" style=
"padding-top:26rpx;">读取中...</view>
17. <view class="phrow"></view>
18. </view>
19.
20. <include src="../common/cart.wxml" />
21. </scroll-view>

第三步: 修改 pages/store/products/list.wxss 页面样式

1. @import "../wxss/style.wxss"
2.
3. .bottombar {
4. bottom: 0px;
5. border: 1px solid #81c7d1;
6. background: #81c7d1;
7. color:#ffffff;
8. position: fixed;
9. line-height: 100rpx;
10. height:100rpx;
11. width: 100%;
12. z-index: 1000;
13. }
14.
15. .bottombar text {
16. color: #ffffff;
17. font-weight: 400;
18. font-size: 30rpx;
19. }
20. .bottombar image {
21. width: 60rpx;
22. height: 60rpx;
23. margin:20rpx;
24. margin-bottom:0;
25. }
26. .text-mimi{
27. font-size: 25rpx;
28. color: #81c7d1;
29. margin-left: 10rpx;
30. }

第四步: 修改 pages/store/products/list.js 添加读取商品逻辑

1. var Goods = require("../../../utils/goods.js");
2. var app = getApp();
3. Page({
4.
5. data:{
6. system:{},
7. paginate:{},
8. goods:[],
9. cart:{},
10. goodsLoading:'',
11. lock: false
12. },
13.
14. // 链接到详情页
detail:function(e){
16. var data = e.target.dataset;
17. wx.navigateTo({ url: '/pages/store/products/detail?id=' + data.
id });
18. },
19.
20. loading: function() {
21. this.lock = true;
22. this.setData( {goodsLoading:''} );
23. },
24.
25. done: function() {
26. this.lock = false;
27. this.setData( {goodsLoading:'hidden'} );
28. },
29.
30.
31. // 读取商品信息
32. getGoods: function ( page ) {
33.
34. var that = this;
35. page = page || 1;
36.
37. return new Promise( function( resolve, reject ) {
38.
39. that.goods.query()
40. .where('status', '=', 'online')
41. .paginate( 10, page )
42.
43. .fetch('*').then(function(resp) {
44.
45. resp.next_page = resp.current_page + 1;
46. if ( resp.next_page > resp.last_page ) {
47. resp.next_page = resp.last_page;
48. }
49.
50. resolve({
51. paginate:{
52. curr:resp.current_page,
53. next:resp.next_page,
54. last:resp.last_page,
55. total:resp.total
56. },
57. goods:that.storeUtils.fliter(resp.data)
58. });
59.
60. }).catch(function( excp ){
61. reject(excp);
62. })
63.
64. });
65. },
66.
67. onLoad:function( params ) {
68.
69. var that = this;
70. this.goods = app.xpm.require('Table','goods');
71.
72. // 设置页面高度
this.setData({'system':wx.getSystemInfoSync()});
74. console.log( this.data );
75.
76. // 用户登录
app.user.login().then( function( userInfo ) {
78. that.storeUtils = new Goods( userInfo, app.session );
79. that.setData({cart:that.storeUtils.cart.total()}); // 初始
化购物车信息
81. return that.getGoods(); // 读取商品列表
82.
}).then( function( resp ) {
that.setData( resp );
85. that.done();
86. });
87. },
88.
89. goods:null, // 商品表
90. storeUtils:null, // 商店工具对象

第五步: 修改 pages/store/products/list.json 修改标题

1. {
2. "navigationBarTitleText": "商品列表"
3. }

5. 滑到底部追加数据
第一步: 修改 pages/store/products/list.wxml 绑定 bindscrolltolower 事件

1. <!-- 将标签 -->
2. <scroll-view scroll-y="true" style="height:{{system.windowHeight}}px;">
3.
4. <!-- 修改为-->
5. <scroll-view scroll-y="true" bindscrolltolower="next" style="height:{{s
ystem.windowHeight}}px;">

第二步: 修改 pages/store/products/list.js 添加 next 属性

1. ...
2. next: function( e ) {
3. var that = this;
4. if ( this.lock ) return;
5. if ( this.data.paginate.next == this.data.paginate.curr ) retur
n;
6.
7. this.loading();
8. this.getGoods( this.data.paginate.next ).then( function(resp )
{
9. var goods = that.data.goods;
10. for( var i in resp.goods ) {
11. goods.push(resp.goods[i]);
12. }
13. that.setData( {paginate: resp.paginate, goods:goods} );
14. that.done();
15. });
16. },
17. ...
6. 购物车相关功能
修改 pages/store/products/list.js 添加 addtocart 、cleanup 和payout 属性
1. // 购物车.算
2. payout: function(e) {
3. wx.navigateTo({ url: '/pages/store/order/confirm/confirm' });
4. },
5.
6. // 清空购物车
7. cleanup: function(e) {
8. this.storeUtils.cart.clean();
9. this.setData({cart: this.storeUtils.cart.total()});
10. },
11.
12. // 添加到购物车
13. addtocart: function( e ) {
14. var data = e.target.dataset;
15. this.storeUtils.cart.add(data['id'], data['price'], data['amoun
t']);
16. this.setData({cart: this.storeUtils.cart.total()});
17. },

四、实验结果
通过本实验,熟练掌握小程序调试方法;熟悉数据表查询操作。

如何用Baas快速在腾讯云上开发小程序-系列4:实现客户侧商品列表、商品详情页程序的更多相关文章

  1. 如何用Baas快速在腾讯云上开发小程序-系列3 :实现腾讯云COS API调用

    版权声明:本文由贺嘉 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/640268001487425627 来源:腾云阁 h ...

  2. 如何用Baas快速在腾讯云上开发小程序-系列2:搭建Phabricator开发管理平台

    版权声明:本文由贺嘉 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/905333001487424158 来源:腾云阁 h ...

  3. 如何用Baas快速在腾讯云上开发小程序-系列1:搭建API & WEB WebSocket 服务器

    版权声明:本文由贺嘉 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221059001487422606 来源:腾云阁 h ...

  4. 如何在腾讯云上开发一款O2O书签?

    版权声明:本文由潘佳宇原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/187 来源:腾云阁 https://www.qclo ...

  5. 使用腾讯云 GPU 学习深度学习系列之二:Tensorflow 简明原理【转】

    转自:https://www.qcloud.com/community/article/598765?fromSource=gwzcw.117333.117333.117333 这是<使用腾讯云 ...

  6. 腾讯云上免费部署HTTPS

    接上篇<腾讯云下安装 nodejs + 实现 Nginx 反向代理>,想从头一步到位的同学建议从上篇文章开始阅读.本文将继续介绍如何通过 Nginx 免费部署HTTPS. 留意下,这里的“ ...

  7. 腾讯云上PhantomJS用法示例

    崔庆才 前言 大家有没有发现之前我们写的爬虫都有一个共性,就是只能爬取单纯的html代码,如果页面是JS渲染的该怎么办呢?如果我们单纯去分析一个个后台的请求,手动去摸索JS渲染的到的一些结果,那简直没 ...

  8. 腾讯云上Selenium用法示例

    欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者:崔庆才 前言 在上一节我们学习了PhantomJS 的基本用法,归根结底它是一个没有界面的浏览器,而且运 ...

  9. 如何在腾讯云上安装Cloud Foundry

    Cloud Foundry是VMware推出的业界第一个开源PaaS云平台,它支持多种框架.语言.运行时环境.云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的 ...

随机推荐

  1. springmvc中的页面解析器ViewResolver不起作用,变量输出字符串的解决方案

    <web-app xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"> <servlet> <servlet ...

  2. [Android Pro] AndroidX重构和映射

    原文地址:https://developer.android.com/topic/libraries/support-library/refactor https://blog.csdn.net/ch ...

  3. Chromium OS 初体验

    Chromium OS可是早有耳闻,但是一直没有尝试,最近很多评论甚至认为会对Windows和Mac都能够造成压力,于是迫不及待的想尝试一下了,百度下了官网,官网很贴心,不光给了用于写入U盘的镜像文件 ...

  4. Linux下 $(cd `dirname $0`;pwd)

    在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".".这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这个目 ...

  5. crucible 的 破解

    crucible这个东西用了很久,但是从来都没有想过去破解它,毕竟在公司是不能使用破解 软件的.于是再家里面玩一下而已.下载地址 运行crucible_keygen 如图: 点击 patch 将选择安 ...

  6. iOS开发-NSDate获取当前时区时间

    NSDate Date默认显示的是格林尼治所在地的标准时间(GMT),转换为中国时区需要加上八个小时,针对与这个情况你可以直接在获取时间之后加上八个小时,也可以转换到当前时区,都很简单,代码参考如下: ...

  7. eclipse里面使用Maven搭建web工程

    一.建立Maven项目 使用Eclipse的maven构建一个web项目,以构建SpringMVC项目为例: 1.1 选择建立Maven Project 选择File -> New -> ...

  8. PHP 通过带SSL的SMTP 发送邮件的处理

    客户端与SMTP服务器的通讯, 是通过固定的命令以及返回编号完成的. 发送Email, 需要经过的步骤有创建socket (区分带ssl, 还是不带ssl)执行命令, 并检查返回值是否与预期一致, 不 ...

  9. 微信支付(APP支付)-服务端开发(一)

    微信支付,首先需要注册一个商户平台公众账号,(网址:https://pay.weixin.qq.com/index.php/home/d_login) 目前微信支付的接入方式有四种方式:公众号支付,A ...

  10. CS页面-Asp.net+Spring.Net.Framework--SNF快速开发平台3.0

    SNF快速平台有BS和CS两种,之前介绍了BS界面,下面发几张图看一下CS界面看看是什么样的 这是SNF快速开发平台的CS框架 1.有多种主页和登录页面. 2.多种页面风格 下面就先先看看页面显示的效 ...