Skip to content

横向分类列表开发,搞定诸多类似场景 ​

本节目标:理解“横向分类列表开发,搞定诸多类似场景”的核心思路,并能把它用于实际开发或面试表达。

说明:原 OneNote 中有图片引用,但图片未包含在导出目录中;本页保留了可用的文字与代码内容。 ==本节最终效果如下所示==:

接受参数 ==在== baseUI ==文件夹下新建== horizen-item ==目录,接着新建== index.js==。== ==首先分析这个基础组件接受哪些参数,==

import React, { useState, useRef, useEffect, memo } from 'react';import styled from'styled-components';import Scroll from '../scroll/index'import { PropTypes } from 'prop-types';import style from '../../assets/global-style';
function Horizen (props) {  return (    //

==暂时省略==

  )}
//

==首先考虑接受的参数==

//list

==为接受的列表数据==

//oldVal

==为当前的== item ==值==

//title

==为列表左边的标题==

//handleClick

==为点击不同的== item ==执行的方法==

Horizen.defaultProps = {  list: [],  oldVal: '',  title: '',  handleClick: null};
Horizen.propTypes = {  list: PropTypes.array,  oldVal: PropTypes.string,  title: PropTypes.string,  handleClick: PropTypes.func};export default memo (Horizen);

==现在,来把== props ==对象进行解构赋值,==

const { list, oldVal, title } = props;const { handleClick } = props;

==返回的== JSX ==代码为==

:
return (   <Scroll direction={"horizental"}>    <div>      <List>        <span>{title}</span>        {          list.map ((item) => {            return (              <ListItem                 key={item.key}                className={`${oldVal === item.key ? 'selected': ''}`}                 onClick={() => handleClick (item.key)}>                  {item.name}              </ListItem>            )          })        }      </List>    </div>  </Scroll>);

==样式代码==

:
//

==由于基础组件样式较少,直接写在== index.js ==中==

const List = styled.div`  display: flex;  align-items: center;  height: 30px;  overflow: hidden;  >span:first-of-type {    display: block;    flex: 0 0 auto;    padding: 5px 0;    margin-right: 5px;    color: grey;    font-size: ${style ["font-size-m"]};    vertical-align: middle;  }`const ListItem = styled.span`  flex: 0 0 auto;  font-size: ${style ["font-size-m"]};  padding: 5px 8px;  border-radius: 10px;  &.selected {    color: ${style ["theme-color"]};    border: 1px solid ${style ["theme-color"]};    opacity: 0.8;  }`

==现在大家还看不到效果,可能会有些慌张,没关系,我们现在就把这个组件进入到页面中试一试。== 载入页面 ==进入到== application/Singers/index.js ==中,代码如下==

:
import React from 'react';import Horizen from '../../baseUI/horizen-item';import { categoryTypes } from '../../api/config';
function Singers () {  return (    <Horizen list={categoryTypes} title={"

==分类== (==默认热门==

):"}></Horizen>  )}
export default React.memo (Singers);

==分类数据在== api/config.js ==中,但现在还没定义,现在在这个文件中添加以下代码==

:
//

==歌手种类==

export const categoryTypes = [{  name: "

==华语男==

",  key: "1001"},{  name: "

==华语女==

",  key: "1002"},{  name: "

==华语组合==

",  key: "1003"},{  name: "

==欧美男==

",  key: "2001"},{  name: "

==欧美女==

",  key: "2002"},{  name: "

==欧美组合==

",  key: "2003"},{  name: "

==日本男==

",  key: "6001"},{  name: "

==日本女==

",  key: "6002"},{  name: "

==日本组合==

",  key: "6003"},{  name: "

==韩国男==

",  key: "7001"},{  name: "

==韩国女==

",  key: "7002"},{  name: "

==韩国组合==

",  key: "7003"},{  name: "

==其他男歌手==

",  key: "4001"},{  name: "

==其他女歌手==

",  key: "4002"},{  name: "

==其他组合==

",  key: "4003"},];
//

==歌手首字母==

export const alphaTypes = [{    key: "A",    name: "A"  },  {    key: "B",    name: "B"  },  {    key: "C",    name: "C"  },  {    key: "D",    name: "D"  },  {    key: "E",    name: "E"  },  {    key: "F",    name: "F"  },  {    key: "G",    name: "G"  },  {    key: "H",    name: "H"  },  {    key: "I",    name: "I"  },  {    key: "J",    name: "J"  },  {    key: "K",    name: "K"  },  {    key: "L",    name: "L"  },  {    key: "M",    name: "M"  },  {    key: "N",    name: "N"  },  {    key: "O",    name: "O"  },  {    key: "P",    name: "P"  },  {    key: "Q",    name: "Q"  },  {    key: "R",    name: "R"  },  {    key: "S",    name: "S"  },  {    key: "T",    name: "T"  },  {    key: "U",    name: "U"  },  {    key: "V",    name: "V"  },  {    key: "W",    name: "W"  },  {    key: "X",    name: "X"  },  {    key: "Y",    name: "Y"  },  {    key: "Z",    name: "Z"  }];

解决滚动问题 ==启动项目,进入歌手列表页后,你发现这个横向列表并不能滚动,我们再回顾下== better-scroll ==的== (==横向==) ==滚动原理,首先外面容器要宽度固定,其次内容宽度要大于容器宽度。== ==因此目前存在两个问题==:

  1. ==外部容器未限定宽度,也就是两个== Horizen ==外面包裹的== div ==元素。==
  2. ==内部宽度没有进行相应的计算,始终为屏幕宽度。==

==现在就分别来解决这两个问题。== ==首先,新建== Singers/style.js ==并增加:==

import styled from'styled-components';import style from '../../assets/global-style';
export const NavContainer  = styled.div`  box-sizing: border-box;  position: fixed;  top: 95px;  width: 100%;  padding: 5px;  overflow: hidden;`;

==在== Singers/index.js ==中使用==

:
import { NavContainer } from "./style";
//...//

==返回的==

 JSXreturn (  <NavContainer>    <Horizen list={categoryTypes} title={"

==分类== (==默认热门==

):"}></Horizen>    <Horizen list={alphaTypes} title={"

==首字母==

:"}></Horizen>  </NavContainer>)//...

==接下来== ==,我们进入== baseUI/horizen-item/index.js ==中==

:
//

==加入声明==

const Category = useRef (null);
//

==加入初始化内容宽度的逻辑==

useEffect (() => {  let categoryDOM = Category.current;  let tagElems = categoryDOM.querySelectorAll ("span");  let totalWidth = 0;  Array.from (tagElems).forEach (ele => {    totalWidth += ele.offsetWidth;  });  categoryDOM.style.width = `${totalWidth}px`;}, []);
// JSX

==在==Scroll==下面,对第一个== div ==赋予==

 ref<Scroll direction={"horizental"}>  <div ref={Category}>

点击 item 样式改变 ==现在整个列表就可以滑动啦。不过还有一个问题,当我们点击某个== item ==的时候,应该呈现选中样式,然后并没有,因为我们并没有在点击的时候改变== oldVal ==的值。== ==现在进入到== Singers/index.js ==中,我们加入部分逻辑后代码如下==

:
import React, {useState} from 'react';import Horizen from '../../baseUI/horizen-item';import { categoryTypes, alphaTypes } from '../../api/config';import { NavContainer } from "./style";
function Singers () {  let [category, setCategory] = useState ('');  let [alpha, setAlpha] = useState ('');
let handleUpdateAlpha = (val) => {    setAlpha (val);  }
let handleUpdateCatetory = (val) => {    setCategory (val);  }
return (    <NavContainer>      <Horizen         list={categoryTypes}         title={"

==分类== (==默认热门==

):"}         handleClick={(val) => handleUpdateCatetory (val)}         oldVal={category}></Horizen>      <Horizen         list={alphaTypes}         title={"

==首字母==

:"}         handleClick={val => handleUpdateAlpha (val)}         oldVal={alpha}></Horizen>    </NavContainer>  )}
export default React.memo (Singers);

==好,现在就有了我们开头的效果。现在你可以为所欲为地滑动、点击,都没有任何问题啦。== > 来自

 <https://juejin.im/book/5da96626e51d4524ba0fd237/section/5da97528e51d452527779f1f>

本站总访问 — 次