从0开发豆果美食小程序——tag组件
效果图
分析数据
本项目购买的是聚合数据菜谱大全接口,首次购买赠送1000次。
首先观察一下接口返回的数据。
整个对象中包含 resultCode、reason 和 result 数组。result 数组中返回若干对象,每个对象中包含 parentId、name 和 list 数组,list 对象数组中,每个对象包含 id、 name 和 parentId。
返回的数据中包含了很多分类,本项目只选择其中 5 个,parentId 为 10001,10003,10005,10009 和 10012。
处理数据
为方便组件的渲染,在分类页面对返回的数据进行处理再传给组件。
域名设置
使用 wx.request 发起请求,在发请求之前,需要对域名进行设置,这样小程序才能和指定域名进行网络通信。文档详情
模块化
一方面,将配置都写在统一的文件中,这样日后如果修改配置相关的项只需要到这一个文件中去改。
另一方面,我们不希望别人知道我们的 appKey,如果 appKey 对外公开,也就意味着其他人能够盗用我们的请求次数。在根目录下创建 config.js,在该文件下定义 appKey,在其他文件中引用这个常量。在 git 提交的时候选择忽略这个文件。模块化文档详情
在 config.js 下编写如下代码。
const appKey = 'xxxxxxxxxxxxxxxxxx'; module.exports= appKey;
在 classify 文件夹下的 index.js 中添加如下语句。注意:require 中只能写相对路径。
var appKey = require('../../config.js');
发起请求
将我们要访问的地址定义在常量 classifyURL 中,在 onLoad 中调用 handleResult 发起请求。这里没有将发起请求直接写在 onLoad 中,因为 onLoad 中可能还要处理其他事情。
在 handleResult 中使用 wx.request 发请求,success 中的 this 指向已经改变,不是当前页面的 this,要在发请求之前保存一下 this,let self = this;
。
由于这里只需要 parentId 为 10001,10003,10005,10009 和 10012 的标签,它们在 result 数组中对应的数组下标是 0, 2, 4, 8, 11,将以上数据存到 tagList 中。
const classifyURL = 'https://apis.juhe.cn/cook/category?key='; data: { tagList: [], }, onLoad: function(options) { this.handleResult(); }, handleResult(){ let self = this; // 注意! wx.request({ url: classifyURL + appKey, data: { result: [] }, success: function (res) { const tempList = [] const ids = [0, 2, 4, 8, 11]; ids.map(i => tempList.push(res.data.result[i])); self.setData({ tagList: tempList }) console.log(self.data.tagList) } }); },
组件结构
组件的结构设计要从数据入手。tagList 中的 name 作为一大类的 title ,这里的 title 分别是菜式菜品、时令食材、场景、西点和人群。在每一个大类中有若干小类,菜式菜品的下属类别有:家常菜、快手菜、创意菜、素菜、凉菜、烘焙、面食、汤和自制调味料。
那么将容器划分为两部分,类别和类别下的若干分类。
<view wx:for="{{List}}" wx:key="index" class="container"> <view class='title-wrapper'> <text class='title'>{{item.name}}</text> </view> <view class='tag-wrapper'> <view wx:for="{{item.list}}" wx:key="index" class='tag-item-wrapper'> <text class='tag-item'>{{item.name}}</text> </view> </view> </view>
这里的 List 由页面传来,也就是 tagList。
Component({ properties: { List: { type: Array, value: [], }, }, });
注意:
<view wx:for="{{List}}" wx:key="index" class="container"> <view class='title-wrapper'> <text class='title'>{{item.name}}</text> </view>
此处的 item 指的是 {parentId: "10001", name: "菜式菜品", list: Array(9)}
<view wx:for="{{item.list}}" wx:key="index" class='tag-item-wrapper'> <text class='tag-item'>{{item.name}}</text> </view>
此处的 item 指的是 {id: "1", name: "家常菜", parentId: "10001"}
组件样式
对于样式的设定,要注意子代关系。container 的只系子代是 title-wrapper 和 tag-wrapper,一共有 5 个 title-wrapper 、tag-wrapper,每组标签有自己的颜色。
.container { width: 750rpx; } .container:nth-child(1) { color: #a5d6a7; } .container:nth-child(2) { color: #ff5252; } .container:nth-child(3) { color: #64b5f6; } .container:nth-child(4) { color: #ffb74d; } .container:nth-child(5) { color: #9575cd; } .container .title-wrapper { text-align: center; margin: 40rpx; } .container .title { color: #000; font-size: 38rpx; } .container .tag-wrapper { margin: 30rpx 80rpx; } .container .tag-item-wrapper { display: inline-block; margin: 20rpx 0 20rpx 18rpx; } .container .tag-item { padding: 10rpx 25rpx; font-size: 32rpx; } .container:nth-child(1)>.tag-wrapper>.tag-item-wrapper>.tag-item { border: 1rpx solid #a5d6a7; border-radius: 40rpx; } .container:nth-child(2)>.tag-wrapper>.tag-item-wrapper>.tag-item { border: 1rpx solid #ff5252; border-radius: 40rpx; } .container:nth-child(3)>.tag-wrapper>.tag-item-wrapper>.tag-item { border: 1rpx solid #64b5f6; border-radius: 40rpx; } .container:nth-child(4)>.tag-wrapper>.tag-item-wrapper>.tag-item { border: 1rpx solid #ffb74d; border-radius: 40rpx; } .container:nth-child(5)>.tag-wrapper>.tag-item-wrapper>.tag-item { border: 1rpx solid #9575cd; border-radius: 40rpx; }
页面 json
{ "usingComponents": { "ck-tags": "/components/tags/index" } }
页面 wxml
<ck-tags List="{{tagList}}"></ck-tags>
结束语
至此,tag 组件已完成初步开发。