npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

taro-listview

v2.0.4

Published

listView pullDownRefresh and skeleton

Downloads

65

Readme

  • [x] 列表内部懒模块-解决小程序图片过多内存问题
  • [ ] skeleton 拓展状态屏
  • [ ] virtual-list(WIP)【虚拟列表】
  • [x] 支持TaroV3 、NPM版本2.x.x

Documents

安装方式

安装:npm i taro-listviewyarn add taro-listview

使用案例

引入组件

列表 Demo

!!!需给组件设置固定高度

API

ListView

可配置参数

页面状态控制参数

| 属性 | 说明 | 类型 | 默认值 | 必传 | | :---------------- | :---------------------------------------------- | :---------------- | :-------------------- | :--- | | style | - | - | - | - | | lazy | 开启懒加载(传入字符串为父元素 className 且开启) | boolean or string | false or '.lazy-view' | - | | hasMore | 加载更多 | boolean | true | true | | isEmpty | 展示空凭页 | boolean | - | - | | isError | 展示错误页 | boolean | - | - | | needInit | 初始化&自动调用下拉刷新方法 | boolean | - | - | | distanceToRefresh | 下拉刷新距离 | number | - | - | | damping | 最大下拉距离 | number | - | - | | autoHeight | 开启自适应高度 | boolean | - | - | | lazyStorage | Storage Key值用于区分ListView | string | box | - |

自定义页面 UI(状态提示语,空白屏、错误屏、底部状态的 UI 自定义)

| 属性 | 说明 | 类型 | 默认值 | 必传 | | :------------------ | :--------------------------------------------------------------- | :-------- | :------------------------------------------------------------------------------------------------------ | :--- | | color | 下拉加载时 loading 的颜色 | string | #667baf | - | | emptyText | 空白页提示语 | string | - | - | | footerLoadedText | 列表底部加载完毕提示语 | string | - | | footerLoadingText | 列表底部加载中提示语 | string | 加载中 | - | | launch | *是否开启状态屏的渲染,状态屏节点对应以下 renderXX 属性(如下) | object | { launchError = false, launchEmpty = false, launchFooterLoaded = false, launchFooterLoading = false } | - | | renderError | 错误页 | Taro.Node | - | - | | renderEmpty | 空白页 | Taro.Node | - | - | | renderFooterLoaded | 自定义底部加载完毕 | Taro.Node | - | - | | renderFooterLoading | 自定义底部加载 | Taro.Node | - | - | | indicator | 下拉提示语 | Object | { release = '加载中', activate = '下拉刷新', deactivate = '释放刷新'} | - |

*错误屏中重新初始化方法与下拉刷新方法一致

import Taro, { Component } from "@tarojs/taro";
import { View, Image } from "@tarojs/components";
import ListView, { LazyBlock } from "taro-listview";

const blankList = [
  {
    author: {},
    title: "this is a example"
  },
  {
    author: {},
    title: "this is a example"
  },
  {
    author: {},
    title: "this is a example"
  },
  {
    author: {},
    title: "this is a example"
  }
];

let pageIndex = 1;

export default class Index extends Component {
  state = {
    isLoaded: false,
    error: false,
    hasMore: true,
    isEmpty: false,
    list: blankList
  };

  getData = async (pIndex = pageIndex) => {
    if (pIndex === 1) this.setState({ isLoaded: false });
    const {
      data: { data }
    } = await Taro.request({
      url: "https://cnodejs.org/api/v1/topics",
      data: {
        limit: 10,
        page: pIndex
      }
    });
    console.log({ data });
    return { list: data, hasMore: true, isLoaded: pIndex === 1 };
  };

  componentDidMount() {
    this.refList.fetchInit();
  }

  pullDownRefresh = async () => {
    pageIndex = 1;
    const res = await this.getData(1);
    this.setState(res);
  };

  onScrollToLower = async fn => {
    const { list } = this.state;
    const { list: newList, hasMore } = await this.getData(++pageIndex);
    this.setState({
      list: list.concat(newList),
      hasMore
    });
    fn();
  };

  refList = {};

  insRef = node => {
    this.refList = node;
  };

  render() {
    const { isLoaded, error, hasMore, isEmpty, list } = this.state;
    return (
      <View className="skeleton lazy-view">
        <ListView
          lazy
          ref={node => this.insRef(node)}
          isLoaded={isLoaded}
          isError={error}
          hasMore={hasMore}
          style={{ height: "100vh" }}
          isEmpty={isEmpty}
          onPullDownRefresh={this.pullDownRefresh}
          onScrollToLower={this.onScrollToLower}
          lazyStorage='lazyView'
        >
          {list.map((item, index) => {
            return (
              <View className="item skeleton-bg" key={index}>
                <LazyBlock current={index} className="avatar" lazyStorage='lazyView'>
                  <Image
                    className="avatar skeleton-radius"
                    src={item.author.avatar_url}
                  />
                </LazyBlock>
                <View className="title skeleton-rect">{item.title}</View>
              </View>
            );
          })}
        </ListView>
      </View>
    );
  }
}

模块懒加载

1.模块需固定同一高度。

2.只能在 ListView 组件内使用,并开启 lazy 模式,且父元素的 className='lazy-view'!!!

3.组件需传入模块遍历后的下标。

API

LazyBlock

| 属性 | 说明 | 类型 |默认值 |必传 | | :------- | :--------------- | :--------- |:--------- |:--------- | | current | 传入模块遍历后的下标 | number | null | true | | lazyStorage | Storage Key值用于区分ListView(获取是哪一个ListView) | string | box | - |

import Taro, { Component } from "@tarojs/taro";
import { View, Image } from "@tarojs/components";
import ListView, { LazyBlock } from "taro-listView";

let pageIndex = 1;

export default class Index extends Component {
  state = {
    isLoaded: false,
    error: false,
    hasMore: true,
    isEmpty: false,
    list: []
  };

  getData = async (pIndex = pageIndex) => {
    if (pIndex === 1) this.setState({ isLoaded: false });
    const {
      data: { data }
    } = await Taro.request({
      url: "https://cnodejs.org/api/v1/topics",
      data: {
        limit: 10,
        page: pIndex
      }
    });
    return { list: data, hasMore: true, isLoaded: pIndex === 1 };
  };

  componentDidMount() {
    this.getData();
  }

  onScrollToLower = async fn => {
    const { list } = this.state;
    const { list: newList, hasMore } = await this.getData(++pageIndex);
    this.setState({
      list: list.concat(newList),
      hasMore
    });
    fn();
  };

  render() {
    const { isLoaded, error, hasMore, isEmpty, list } = this.state;
    return (
      <View className="lazy-view">
        <ListView
          lazy
          isLoaded={isLoaded}
          hasMore={hasMore}
          style={{ height: "100vh" }}
          onScrollToLower={this.onScrollToLower}
          lazyStorage='lazyViewBlock'
        >
          {list.map((item, index) => {
            return (
              <View className='item' key={index}>
                <LazyBlock current={index} className='avatar' lazyStorage='lazyViewBlock'>
                  <Image className='avatar' src={item.author.avatar_url} />
                </LazyBlock>
                <View className="title">{item.title}</View>
              </View>
            );
          })}
        </ListView>
      </View>
    );
  }
}

骨架屏

1.因骨架屏是捕捉已有占位数据的样式,再绘制出骨架,所以要先注入默认空白占位数据。

2.且需要一个传入父元素的 className(默认获取为“skeleton”),以便寻找元素下的所有“关节”元素。可通过传入 selector 参数自定义 className。

有且只有捕捉以下提供的“关节”样式名:背景('skeleton-bg')、矩阵('skeleton-rect')、圆形('skeleton-redius')。

3.ListView 组件已嵌套 Skeleton 组件,直接调用对应属性即可。

*“关节”元素需内容撑开,或者固定高度。

API

Skeleton

| 属性 | 说明 | 类型 | 默认值 | 必传 | | :------- | :------------------------------------ | :------- | :----- | :--- | | isLoaded | 骨架屏是否显示(eg:加载第一页时开启) | boolean | false | - | | selector | 骨架屏外层 class 名称 | skeleton | - | - |

骨架屏 Demo

import Taro, { useState } from "@tarojs/taro";
import { View, Button } from "@tarojs/components";
import { Skeleton } from "components";
import "./index.scss";

export default () => {
  const [isLoaded, setLoaded] = useState(false);
  return (
    <View>
      <Button onClick={() => setLoaded(!isLoaded)}>toggle</Button>
      <View className="skeleton">
        <Skeleton isLoaded={isLoaded}>
          {Array(4)
            .fill(1)
            .map(i => (
              <View className="item skeleton-bg" key={i}>
                <View className="avatar skeleton-radius" />
                <View className="title skeleton-rect">title</View>
              </View>
            ))}
        </Skeleton>
      </View>
    </View>
  );
};

方法参数

| 事件名称 | 说明 | 类型 | 默认值 | 必传 | | :---------------- | :--------------- | :------- | :----- | :--- | | onPullDownRefresh | 下拉刷新触发函数 | function | - | - | | onScrollToLower | 上拉底触发函数 | function | - | - |

onPullDownRefresh = () => {
  getData();
};

onScrollToLower = async fn => {
  await getData();
  fn();
};