为什么选择mpvue
在比较了原生开发小程序和wepy
以及mpvue
之后,由于mpvue
是一个基于Vue
的框架,里面可以使用Vue
的各种语法,由于自己也学习了Vue
所以学习成本也不高,可以说是无缝对接了。
总体概述
小程序使用的是前后分离的开发模式,后端构造接口,然后前端请求接口拿到数据后进行页面的渲染。后台采用的是提供的例子。采用的是Node.js
和Mysql
。下载之后需要做一些简单的配置,网上也有很多教程。这里后端大部分代码不需要自己写,这需要写一些自己需要用到的接口。小程序前端封装了需要经常用到的函数,在utils
目录下,所以在代码中如果看到utils
就表示使用的是utils
中的方法。
小程序的主要代码都写在src目录下。目录结构
补充一点
由于现在豆瓣的图书API已经不能用了,但是在网上看到了一片,我就是使用的这种方法来获取图书的详情,但是获取的图书资料不是和完整,但也还是凑合着用吧,后端代码实现见:server/controllers/addbook.js
。
下面给大家讲一讲主要页面的代码
一、个人中心页面
核心代码;这里采用了小程序提供的wafer2-client-sdk库,在使用之前我们要先引入
import qcloud from "wafer2-client-sdk"
async login() { let user = wx.getStorageSync("userinfo"); if (!user) { wx.showLoading({ title: "登录中", mask: true }) qcloud.setLoginUrl(config.loginUrl); qcloud.login({ success: (res) => { wx.hideLoading() console.log("success:", res); wx.setStorageSync("userinfo", res); this.userinfo = res utils.showSuccess("登录成功"); }, fail: function(err) { console.log("fail:", err); } });}}复制代码
在登录成功之后我们把数据存储到本地,下次进入小程序的时候先判断本地是否有数据,如果有就直接获取,
onShow() { let userinfo = wx.getStorageSync("userinfo") if (userinfo) { this.userinfo = userinfo } }复制代码
登录成功之后会有添加图书的按钮
scanBook() { wx.scanCode({ success: res => { console.log(res) if(res.result) { this.addBook(res.result) } } }); }, async addBook(isbn) { // 扫码成功后添加书籍 const res = await utils.post('/weapp/addbook', { isbn, openid: this.userinfo.openId }) console.log(res) if (res.code === 0) { utils.showModal('提示',`添加成功${res.title}`) } else { utils.showModal('提示', `添加失败${res.msg}`) } },复制代码
这里调用了微信小程序自带的API,得到扫描的结果之后向后台发送数据(server.controllers/addbooks.js
),后台得到ISBN编码后查询结果,然后存入数据库。存入数据库的信息包括isbn, openid, title, image, alt, publisher, summary, price, rate, tags, author
。
二、图书列表页面
获取图书列表代码
async getList(init) { // 获取图书列表 if (init) { // init代表初始化数据的时候 this.page = 0 this.more = true } wx.showNavigationBarLoading() let res = await utils.get('/weapp/booklist', { page: this.page}) if (res.list.length < 10 && this.page > 0) { this.more = false } if (init) { this.books = res.list wx.stopPullDownRefresh() } else { this.books = this.books.concat(res.list) } wx.hideNavigationBarLoading() }, 复制代码
这里采用的是分页查询(后端:server/controllers/booklist
),每次只加载十条数据然后当触发onReachBottom()
事件后就把当前的数据拼接上获取到的数据。这里在获取图书列表的时候会使用联表查询:根据图书信息中的openid去查找对应的用户信息。
.select('books.*', 'cSessionInfo.user_info').join('cSessionInfo', 'books.openid', 'cSessionInfo.open_id')复制代码
这里的评分是一个单独的组件src/components/Rate.vue
,
☆☆☆☆☆复制代码★★★★★
设置hollow
为绝对定位,然后根据图书的评分设置它的宽度。
三、图书详情页面
在进入图书详情页的时候会把当前图书的id
做为参数传给下一个页面,在进入下一个页面的时候可以通过 this.$root.$mp.query.id
获取到。 在进入图书详情页之后先通过this.$root.$mp.query
获取当前图书的id,然后在数据库中根据id查找图书的详情信息。然后根据id
在数据库评论表中查找评论。这里在查找的时候也会使用联表查询获取图书添加者的信息(根据图书信息的openid
获取用户信息)。
一本书一位用户只能评价一次,如果用户评价了就不能再次评价,相应的评论框也会被隐藏。
判断用户是否可以评价
computed: { showAdd() { // 是否展示发表评论按钮 if (!this.userinfo.openId) { // 未登录 return false } if (this.comments.some(v => v.openid = this.userinfo.openId)) { // 已经评论了 return false } return true } },复制代码
如果用户还没有评价则显示评价框:
获取手机型号
getPhone(e) { if (e.target.value) { let systemInfo = wx.getSystemInfoSync(); this.phone = systemInfo.model; } else { this.phone = ""; }},复制代码
获取地址位置
getGeo(e) { if (e.target.value) { wx.getLocation({ success: geo => { console.log(geo) wx.request({ url: config.baiduURL, data: { ak: config.baiduAK, location: `${geo.latitude},${geo.longitude}`, output: "json" }, success: res => { if (res.data.status === 0) { this.location = res.data.result.addressComponent.city; } else { this.location = "外太空"; } } }); } }); } else { this.location = ""; }},复制代码
需要注意的是,使用微信自定义的API只能获取到经纬度,我们通过的开放接口申请小程序,来进行逆地址解析。
四、评论页面
在这个页面你可以看到你发表的评论以及添加的书籍,这里根据你的openid去后台数据库查找,然后展示在页面上。点击评论可以进入这条评论对应的书籍,但是在图书详情页不会,这主要添加了一个标识来判断当前处于的页面。
最后
感谢蜗牛老师。如果你觉得还不错的话请你点个赞呢。
GitHub地址: