【项目实战】基于Vue3+Vant3造一个网页版的类掘金app项目 - 推荐作者列表

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

前言

上一次分享我们实现了关注页面推荐作者的头像展示,以及其它几个列表页中子标签组件JTags的封装和使用,从而实现了子标签的动态加载,那么除了头像和标签的展示以外,点击头像或者点击某个具体的标签还有其它功能,比如点击关注页中的作者头像会跳转到一个新的页面展示更多的作者,点击其它列表页中的子标签则会根据已选择的主标签和子标签作为条件重新过滤列表中的文章数据。今天这次分享中我们先来实现点击关注页作者头像跳转到作者列表页面。

作者排行榜

点击关注页面中的推荐作者头像会跳转到作者列表页面。下面是官方的效果图,我们来分析一下:首先在最顶部是一个导航栏,跟其它页面中的导航一样无非就是一个van-nav-bar组件,左侧是一个返回按钮和“优秀作者榜”标题,右侧是排名规则说明。紧接着又是一个标签tab页,下面则是具体的列表展示,跟前面的首页基本一样。这样一来要用到的组件也就基本确定了(van-nav-bar,van-tabs,van-list)。

image.png

页面的组成结构以及所要用到的组件已经清晰,下面再来分析一下如何实现(大概思路):

  • 首先新建一个AuthorList.vue的新页面并配置好相关路由信息
  • 添加模板内容
    • 首先在页面顶部添加一个van-nav-bar组件,设置left-arrow属性值为true,left-text属性设置为“优秀作者榜”,right-text属性设置为“排序规则”,并添加@click-left和@click-right事件,实现点击返回图标返回上一页,点击排序规则后弹出具体的规则说明。但由于在web端没找到请求规则的接口,所以暂时先不实现该功能。
    • 在van-nav-bar组件下方再添加一个van-tabs组件,并设置sticky和swipeable属性均为true
    • 然后在van-tabs里面添加一个子元素van-tab,title属性设置为“热榜”,再添加另外一个子元素van-tab,该元素需通过v-for指令循环输出,数据源通过query_category_briefs接口返回
    • 再在每个子tab(van-tab)中添加van-pull-refresh和van-lis两个组件用于实现数据列表展示及下拉刷新功能,这里还需要注意每个作者后面的“关注”或“已关注”按钮状态(可根据后台返回的数据源中的isFollowed属性进行判断)
  • JavaScript核心代码内容
    • 首先定义如下几个响应式属性:refreshing,finished,loading,active,categoryList,authorList
    • 在setup方法中分别调用query_category_briefs和recommend两个后端接口来获取标签类别和作者列表数据源并将返回结果分别赋值给categoryList和authorList两个响应式属性
    • 定义onLoad方法用于调用后端接口请求作者数据(滚动自动翻页加载数据)
    • 定义onRefresh方法用于实现下拉刷新状态

核心代码及效果图:

<van-nav-bar left-arrow left-text="优秀作者榜" right-text="排序规则" />
  <van-tabs color="#1e80ff" v-model:active="active" @click-tab="clickTab">
    <van-tab
      v-for="item in categoryList"
      :key="item.category_id"
      :title="item.category_name"
    >
      <div class="tab-list-content">
        <van-pull-refresh
          v-model="refreshing"
          @refresh="onRefresh(item.category_id)"
        >
          <van-list
            v-model:loading="loading"
            :finished="finished"
            finished-text="没有更多了"
            @load="onLoad(item.category_id)"
          >
            <van-cell v-for="item in authorList" :key="item.user_id">
              <div class="author-list">
                <van-image round :src="item.avatar_large" />
                <div class="author-item">
                  <div>
                    <span class="name">{{ item.user_name }}</span>
                    <van-image :src="level[item.level]" />
                  </div>
                  <div class="info">
                    {{ item.job_title }} @ {{ item.company }}
                  </div>
                  <div class="describ">
                    获得 {{ item.got_digg_count }} 赞 ·
                    {{ item.got_view_count }} 阅读
                  </div>
                </div>
                <div class="follow">
                  <van-button
                    v-show="!item.isfollowed"
                    round
                    plain
                    size="mini"
                    type="primary"
                    >+ 关注</van-button
                  >
                  <van-button
                    v-show="item.isfollowed"
                    type="success"
                    size="mini"
                    round
                    >已关注</van-button
                  >
                </div>
              </div>
            </van-cell>
          </van-list>
        </van-pull-refresh>
      </div>
    </van-tab>
  </van-tabs>
复制代码
api.queryCategoryBriefs().then((res) => {
      state.categoryList = res.data;
      state.categoryList.unshift({
        category_id: "-999",
        category_name: "热榜",
      });
    });

    let pageNo = 0;
    const onLoad = function (cate_id) {
      console.log(cate_id);
      cate_id = cate_id === -999 ? "" : cate_id;
      http.post("/juejin/recommend", { limit: 20, cate_id: "" }).then((res) => {
        if (state.refreshing) {
          state.authorList = [];
          state.refreshing = false;
        }
        state.authorList.push(...res.data);
        state.loading = false;

        if (pageNo >= 50) {
          //只加载50页(1000条)数据
          state.finished = true;
        }
        pageNo++;
      });
    };

    const onRefresh = function (cate_id) {
      pageNo = 0; //从第一页重新加载
      state.finished = false; //清空列表数据,重新加载
      state.loading = true;
      onLoad(cate_id);
    };

复制代码

test2.gif

总结

本次分享中我们实现了推荐作者列表的展示和加载,但是还有一些小细节没有实现,比如点击切换标签对应的列表数据切换,点击作者名称或头像跳转的作者主页,点击关注或已关注按钮实现关注或取消关注等功能,下次分享我们继续来优化。今天的分享就到这里了。

Guess you like

Origin juejin.im/post/7066076316298117134