仿写京东小程序

1,162 阅读6分钟

前言

最近学了一段时间微信小程序,也是和小伙伴们尝试做了京东小程序,着重于实现一些商业逻辑和网上购物的基础功能。本着学习和分享的初心,我会在文章中分享开发中遇到的小坑,希望能给我一样的小白带来点帮助。

想看进阶的欢迎转战我们大佬的文章

开发前的准备

项目展示

先看看效果吧

1630550290265.gif

图片如下

image.png image.png

image.pngimage.png

总体框架

  • 该项目是基于微信小程序云开发,由于是个全栈项目,前端使用小程序所支持的wxml + wxss + js开发模式,后端数据则是借助云数据库进行数据管理。

项目的总体结构

|-jd 京东
    |- miniprogram 项目模块
        |-vant     有赞vant组件库
        |-assets   部分数据,做到模块分离
            |-db.js 数据
        |-app.js   全局JS
        |-app.json 全局JSON配置,自定义tabbar
        |-app.wxss 全局WXSS配置
        |-pages 页面
            |-index   首页界面
            |-details 购物界面
            |-search  搜索界面

这里assets文件的数据采用的是common js的写法,数据module.exports暴露,在需要使用的地方,直接 require引入,

云数据库

云数据库是一种NoSQL数据库。每一张表是一个集合。值得注意的是在设计数据库时,_id 和_openid这两个字段需要带上。_id是表的主键,而_openid是用户标识,每个用户都有不同的_openid,可区分不同用户。

数据库的设计

下面是我设计的两张表

|-JDShop
    |-_id 表的主键
    |-_openid 用户标识
    |-address 商品旗舰店
    |-comment 评论数
    |-goodcomment 好评百分比
    |-imgUrl 商品图片链接
    |-origins 商品来源
    |-plusPrice jd会员价
    |-price 商品价格
    |-sales_count 销量
    |-tags 标签
    |-time 时间
    |-title 商品标题
    |-type 商品类型

image.png

|-suggestResult
    |-_id 
    |-desc 描述

表做的比较简陋,凑合的看吧!

u=1405840109,4784534&fm=26&fmt=auto&gp=0.webp

云存储

云开发提供了一块存储空间,可以上传文件至云端,类似于一个网盘,对于压缩在2M以内的小程序很有帮助

image.png

image.png 这里上传云端后,可以直接复制下载地址,就节省了很大的空间了

注意:记得权限一定要改成所有用户可读,才可以哦 image.png

项目明细

品牌分类页

image.png

左右两个scoll-view弹性布局,左边设置为固定宽度,右设置为display:1则可以占满剩余的宽度

这里分享一下这个点击样式吧

1630567734782.gif

仔细看,我这里有三个动态的样式,首先最明显的文字左边的红色边框,其次,字体加粗最后底部背景变得亮白

  <view class="cates {{ activeIndex == index ? 'active_cates': '' }}"  // 可以设置多个样式

拿红色边框举例,这里可以用样式叠加,分别用不同的类名分开表达不同效果, 就拿我这里来说,通过设置一个三元运算符,添加一个点击事件bindtap,当点击时来判断activeIndex == index,当true时,就会运行提前设置好的active_cates,于是左边的边框就出来。看了是不是觉得是不是有手就行?

还有当点击不同类别时,右边的页面好像也变了对吧?

变了但没完全变

本质上它的结构wxml,js逻辑并没有变,只数据驱动界面通过wx:for全部给遍历给出来的,这就是微信云开发的好的地方,特别方便,有了这是不是省了很多切页面的功夫

商品筛选页

先上效果

image.png

这里简单的页面布局,对大家肯定小菜一碟,就不赘述了, 我来讲讲这里数据库的数据筛选,举个栗子

1630569184688.gif

这是对应JS代码

 async  sales_btn(e){
  let {data} = await jdshop    // async,await ES6的异步转同步写法
  .orderBy('sales_count','desc')
  .get()
  this.setData({
    jdshop:data
  })
},

因为是云开发,我们造的假数据都在云数据库里,所以需要从访问云数据库,调用所要的数据。因为访问数据库这是个异步任务,我这里用的是ES6最新Async的写法,将这个异步任务变成同步任务,用await来接收,具体详细可以看看阮一峰老师的Async函数

在这里通过orderBy(),来改变排列顺序,我这里是根据销量降序排序,最后.get()获得数据,在赋值给遍历的数据jdshop,就实现了数据筛选,是不是很简单?至于数据库的一些方法,建议多看看云开发数据库文档

还有我这里用的是自定义样式,占满整个屏幕

image.png 这是json代码

{
  "usingComponents": {},
  "navigationStyle":"custom"  // 占满整个屏幕
}

搜索页

不多说,先看效果

1630570740625.gif

这里和大家分享几个可能遇到小坑

  • 很明显当点击时,我们进入了另一个页面,但这个数据水瓶是怎么穿过去的?
  • 当前改变关键词时,下面的搜索框是怎么做到实时改变的?
  • 在点击确实搜索时,怎么把你的搜索历史给保存出来,并立即反馈出来的?

慢慢来

第一个,其实这个数据传递特别简单

search_btn(){
  //console.log(this.data.value);
  let value = this.data.value;
  wx.navigateTo({
    url: `../search/search?value=`+value,     // wx.navigateto跳转页面
  })
}

调用wx.navigateTo,跳转到serach页面,并带一个数据value这里用的ES6的字符串模板符方法,特别好用!

注意写法:“?value=value

第二个,首先这里的搜索栏用的是vant组件,而这里的小坑在于绑定的事件不是bindtap而是bind:change,所以有事没事还是要多翻翻vant文档

这是绑定的函数代码

async onChange(e) {
    let dataList = wx.getStorageSync('title');  // 这是设计到Storage的本地存储
        let searchKey = e.detail;               //首先打印e取到e.detail赋值给searchKey
    // console.log("searchKey",searchKey);      // 多打console.log好调试
    let {data} =await suggestResultCollection.where({
      desc:db.RegExp({
        regexp:searchKey,                  //正则表达式匹配searhKey
      })
    })
    .get()
    this.setData({
      suggest_list:data,
      isSuggestShow: true,
      dataList
    })
    if(!e.detail){
      this.setData({
        isSuggestShow: false
      })
    }
  }

同样因为要调用数据库数据,所以用Async将异步任务转为同步任务,我们通过bind:change事件获得你实时输入的值searchKey,至于怎么匹配下面的搜索就需要用到正则表达式。首先通过我们前面学到的,suggestResultCollection这张表的,用**.where** 来筛选最后调用正则RegExp,匹配词语就是我们的searchKey,最后.get() 获得数据

第三个

storage

storage是小程序自带的本质缓存,可以帮你暂存一些用户id,信息啥的,所以有时不一定要全放入数据库里,将数据放入storage里,可能是一个更简便的思路。 ** 示例代码**

wx.setStorage({
  key:"key",
  data:"value"
})

image.png

具体实现

代码如下(这是绑定bind:Search事件的函数)

 onSearch(e){
   let dataList = [],
   data = e.detail;
   dataList.push(data);
   let storageList = wx.getStorageSync("title")
   if(storageList){   //if判读如果是假的就不用合并
     dataList = dataList.concat(storageList);    // concat合并两个数组
   }
   wx.setStorageSync('title', dataList);   // 最后将dataList这个数据放入storage里
 },

源码

项目源码

一点心得

  • 多用组件,一些重复的代码可以优化成自定义组件。其实我们在做真正的商业项目,工程是特别的大的,所以多用用组件,该偷懒时就得偷懒
  • 有事没事多打打console.log,亲测有效

最后

这也是我第一次写小程序项目,功能不是很齐全。大佬们看完了赏脸点个赞吧! u=3126377335,1628995714&fm=26&fmt=auto&gp=0.webp