Taro跨端开发探索14——商城小程序商品列表页面开发

736 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情

前言

昨天我们完成了所有的商品搜索引导和搜索入口页面。今天我们基于京喜小程序分析一下商品搜索页面的需求并实现它

需求分析

我们先看一下京喜的商品搜索页面

1650462232(1).png
我们昨天已经实现了最顶部的搜索功能。今天我们针对于一下几个功能开展开讲一下

  • 综合筛选、销量、价格
    • 综合排序的用手风琴暂时没有实现,我再试一下用列表筛选
  • 一列展示变为两列展示
  • 列表加载
  • todo
    • 筛选页面(筛选页面实现起来比较复杂,要基于action传值,明天我去学习一下)

列表加载和单双列列加载

我们从看起来比较好做的列表加载和单双列加载来做起。我们可以看到,列表加载其实和我们首页的商品列表加载差不多。
我们在做单双列切换的时候,只需要控制一下样式即可。
我的实现逻辑是这样的:假设我们有4条数据

  • 要单列展示。我们就设置每个view的宽度为100%。这样4个元素就能按行展示了
  • 要双列展示。我们就设置每个view的宽度为50%,这样2个元素占用一行。注意我们要设置变量的view为行内元素,否则还是会换行 goods-list/index.tsx
import { ScrollView, Text, View } from "@tarojs/components";
import { AtImagePicker, AtButton } from "taro-ui";
import { AtSearchBar } from "taro-ui";
import { useEffect, useState } from "react";
import "./index.scss";
import { getCurrentInstance } from "@tarojs/taro";

export default function GoodsList() {
  const { router } = getCurrentInstance();
  const [queryKey, setQueryKey] = useState("");
  const [queryCateId, setQueryCateId] = useState("");
  const [data, setData] = useState([] as any);
  const [goodQueryIndex, setGoodsQueryIndex] = useState(1);
  const [bottomLoading, setBottomLoading] = useState({
    loading: false,
    hasMore: true,
  });
  const [filterSort, setFilterSort] = useState("");
  useEffect(() => {
    const searchKey = router && router.params.searchKey;
    const categoryId = router && router.params.categoryId;
    if (searchKey) {
      setQueryKey(searchKey);
    }
    if (categoryId) {
      setQueryCateId(categoryId);
    }
    if (goodQueryIndex > 5) {
      setBottomLoading({ loading: false, hasMore: false });
      return;
    }
    setBottomLoading({ loading: true, hasMore: true });
    const timer = setTimeout(() => {
      clearTimeout(timer);
      const loadData = [
        {
          id: 111 + "" + goodQueryIndex,
          photo: "",
          title: `第${goodQueryIndex}页,第一个商品`,
          price: goodQueryIndex * 100,
        },
        {
          id: 222 + "" + goodQueryIndex,
          photo: "",
          title: `第${goodQueryIndex}页,第二个商品`,
          price: goodQueryIndex * 200,
        },
        {
          id: 333 + "" + goodQueryIndex,
          photo: "",
          title: `第${goodQueryIndex}页,第三个商品`,
          price: goodQueryIndex * 300,
        },
        {
          id: 444 + "" + goodQueryIndex,
          photo: "",
          title: `第${goodQueryIndex}页,第四个商品`,
          price: goodQueryIndex * 400,
        },
      ];
      setData((data) => [...data, ...loadData]);
      setBottomLoading({ loading: false, hasMore: true });
    }, 2000);
  }, []);
  return (
    <ScrollView
      className="goods-list"
      scrollY={true}
      onScrollToLower={() => {
        setGoodsQueryIndex(goodQueryIndex + 1);
      }}
    >
      <AtSearchBar
        onActionClick={() => {
          console.log(
            "goodQueryIndex",
            goodQueryIndex,
            "queryKey",
            queryKey,
            "queryCateId",
            queryCateId,
            "filterSort",
            filterSort
          );
        }}
        focus={true}
        value={queryKey}
        placeholder="请输入搜索条件"
        onChange={(value) => {
          setQueryKey(value);
        }}
      />
      <View>
        <AtButton
          size="small"
          type={filterSort === "generate" ? "primary" : undefined}
          className="filter-btn"
          onClick={() => {
            setFilterSort("generate");
          }}
        >
          综合
        </AtButton>
        <AtButton
          size="small"
          className="filter-btn"
          type={filterSort === "selelNum" ? "primary" : undefined}
          onClick={() => {
            setFilterSort("selelNum");
          }}
        >
          销量
        </AtButton>
        <AtButton
          size="small"
          type={filterSort === "price" ? "primary" : undefined}
          className="filter-btn"
          onClick={() => {
            setFilterSort("price");
          }}
        >
          价格
        </AtButton>
      </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["title"]}:{(item["price"] / 100).toFixed(2)}
            </Text>
          </View>
        ))}
      </View>
      {bottomLoading.loading ? (
        <Text>加载中</Text>
      ) : bottomLoading.hasMore ? (
        ""
      ) : (
        <Text>没有更多了</Text>
      )}
    </ScrollView>
  );
}

goods-list/index.scss

@import "~taro-ui/dist/style/components/search-bar.scss";
@import "~taro-ui/dist/style/components/icon.scss";
@import "~taro-ui/dist/style/components/button.scss";
.goods-list {
  height: 1100px;
  width: 100%;
}
.filter-btn {
  width: 20%;
  display: inline-flex;
}

最后我们实现的效果就是在点击搜索按钮的时候,会在控制台中输出如下所示信息

1650467048(1).png

结语

今天写的不是很多,主要是我没有接触过action传值。别的不说了,我去学习一下,明天准备处理一下筛选的显示。
在更文活动完成之后我会处理样式问题,这几天的文章我们主要是将实现逻辑和react代码,等以后有时间我再从头学习一下css优化一下所有的组件。
欢迎大家多多关注,gitee地址为:gitee.com/liangminghu…