一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
前言
在前面9天的文章中,我们已经完成了基本的架构搭建和常用的方法封装,还有熟悉了一下父子组件中传值的方法。今天,我们基于京喜小程序分析一下首页需要实现的功能
需求分析
我们先看一下京喜小程序的首页是什么样子的
如上所示,我们可以看到它有以下几个功能
1: 搜索:用户在选中输入框的时候会跳转到搜索页面,搜索之后会到搜索结果页面
2: 分类筛选
3: 活动和引流区域(对应我框出来的1区域)
4: 新人活动(对应我框出来的2区域)
5: 常驻活动(对应我框出来的3区域)
6: 推荐商品(对应我框出来的4区域)
我们取它的 1、5、6模块进行开发,其他的模块大家可以按照我的思路自己试一下开发
功能实现
初始化目录
我们将常驻活动和推荐商品作为独立的子模块在home下新建对应的文件夹并初始化index.tsx和index.scss文件。将搜索商品(在首页和分类搜索都有搜索商品)作为公用的组件,在src下新建component文件夹作为公用的组件库
先实现常驻活动和推荐商品开发
我们在进入首页的时候,会等待常驻活动和推荐商品的后端接口,这里有两种等待策略
- 等待所有接口请求完成之后一起渲染数据
- 所有子组件块的接口分块加载,没有请求完成的时候显示loading,请求完成之后加载数据
我们使用第二种策略。原因为:后端接口存在不确定性,例如某个接口出现问题或者执行的逻辑花费时间过长时,严重影响客户体验
我们的home\index.ts代码如下
import { View } from "@tarojs/components";
import "./index.scss";
import RecommendedGoods from "./recommended-goods";
import ResidentActivities from "./resident-activities";
export default function Home() {
return (
<View className="home">
<ResidentActivities />
<RecommendedGoods />
</View>
);
}
推荐商品的业务代码如下
import { View, Text } from "@tarojs/components";
import { useEffect, useState } from "react";
import { AtImagePicker } from "taro-ui";
import "./index.scss";
export default function RecommendedGoods() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState([] as any);
useEffect(() => {
const timer = setTimeout(() => {
clearTimeout(timer);
setLoading(false);
setData([
{ id: 111, photo: "", price: 300 },
{ id: 222, photo: "", price: 200 },
{ id: 333, photo: "", price: 300 },
{ id: 444, photo: "", price: 200 },
{ id: 555, photo: "", price: 300 },
]);
}, 2000);
}, []);
return (
<View className="recommended-goods">
{loading ? (
<Text>加载中</Text>
) : (
<View>
<View>
{data.map((item) => (
<View>
<AtImagePicker
files={[
{
url: "https://storage.360buyimg.com/mtd/home/111543234387022.jpg",
},
]}
showAddBtn={false}
onImageClick={() => {
console.log(item["id"]);
}}
count={1}
onChange={() => {}}
sizeType={["original", "compressed"]}
/>
<Text>{(item["price"] / 100).toFixed(2)}</Text>
</View>
))}
</View>
</View>
)}
</View>
);
}
常驻活动的业务代码如下
import { View, Text } from "@tarojs/components";
import { useEffect, useState } from "react";
import "./index.scss";
export default function ResidentActivities() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState([] as any);
useEffect(() => {
const timer = setTimeout(() => {
clearTimeout(timer);
setLoading(false);
setData([
{
title: "秒杀活动",
goodsData: [
{ id: "111", photo: "", price: 100 },
{ id: "222", photo: "", price: 200 },
],
},
{
title: "官方补贴",
goodsData: [
{ id: "333", photo: "", price: 300 },
{ id: "444", photo: "", price: 400 },
],
},
]);
}, 2000);
}, []);
return (
<View className="resident-activities">
{loading ? (
<Text>加载中</Text>
) : data.length >= 2 ? (
<View>
<View>
<Text>{data[0].title}</Text>
{data[0].goodsData.map((item) => (
<View
className="goods-item"
onClick={() => {
console.log(item.id);
}}
>
<Text>{(item.price / 100).toFixed(2)}</Text>
</View>
))}
</View>
<View>
<Text>{data[1].title}</Text>
{data[1].goodsData.map((item) => (
<View
onClick={() => {
console.log(item.id);
}}
>
<Text>{(item.price / 100).toFixed(2)}</Text>
</View>
))}
</View>
</View>
) : data.length === 1 ? (
<View>
<View>
<Text>{data[0].title}</Text>
{data[0].goodsData.map((item) => (
<View
onClick={() => {
console.log(item.id);
}}
>
<Text>{(item.price / 100).toFixed(2)}</Text>
</View>
))}
</View>
</View>
) : (
""
)}
</View>
);
}
我们可以看到在我们使用父子组件之后,所有的子组件的加载动作可以自己控制,我们可以自己设置一下定时器的时间,体验一下不同子组件的延迟加载
结语
今天的开发进度不是很快,主要是一开始采用了父组件传值给子组件进行渲染,导致浪费了一些时间,还有taro ui的一些组件不太好集成。下篇文章我们探索一下下拉刷新的业务场景。
本系列文章对应git地址为:gitee.com/liangminghu… 欢迎各位css大佬提交样式pr。也欢迎大家多多点赞关注!