【项目实战】基于Vue3+Vant3造一个网页版的类掘金app项目 - 话题广场

343 阅读3分钟

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

前言

大家好,上一篇数据渲染文章分享中,我们实现了发现主页面的数据动态渲染,并且还实现了一些页面跳转,比如点击搜索跳转到搜索页,点击话题跳转到话题广场,点击活动跳转到活动页面等等。其中有些页面的功能在以前的一些分享中已经实现了,比如搜索页面和作者列表页。但也有些页面是新增的空白页面,比如话题页和活动页。接下来的几篇分享中我们就一一把这些跳转的新页面功能实现一下,今天的分享主要实现话题广场页面

布局分析

image.png 如图所示,话题广场页整体布局比较简单,主要由顶部标题栏和主页面中的话题列表组成,其中话题列表又包括:话题标题、话题描述、话题图片、参加的掘友数以及阅读人数等内容。并且话题列表可以实现下拉刷新内容,上划加载新内容。下面我们就来把功能实现一下。

功能实现

  • 标题栏 标题栏仅包含一个返回按钮和“话题广场”标题,我们可以直接使用vant组件库中的NavBar组件完美实现。首先在TopicSquare.vue中添加一个van-nav-bar组件,设置title属性值为“话题广场”,设置left-arrow为true(显示返回按钮),添加click-left事件用于点击返回按钮时返回到上一页,返回上一页功能可以借助路由的back方法实现。代码如下:
<van-nav-bar title=""话题广场 left-arrow @click-left="toBack" />
 const router  = useRouter()
 const toBack = () => {
     router.back();
 } 
  • 话题列表 话题列表我们可以借助vant库中的van-pull-refresh和van-list两个组件来实现下来刷新和上拉加载更多数据,其它的只需要根据官方布局设置好对应的样式即可。
  • 首先在van-nav-bar组件下方添加一个van-pull-refresh组件,并设置对应v-model属性和onrefresh事件
  • 在van-pull-refresh组件内添加van-list子组件,并设置v-mode、finished、finished-text属性和onload事件
  • 在van-list下添加子组件van-cell,并用v-for指令循环将后台获取到的话题数据渲染输出
  • 在van-cell中添加topic-item盒子,topic-item下包含两部分内容:话题标题(独占一行)和话题详情
    • 设置话题标题独占一行
    • 话题详情采用flex布局分为左右两部分,左边显示话题描述信息,右边显示话题图片 核心代码及最终效果图如下:
   <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
    <van-list
      v-model:loading="loading"
      :finished="finished"
      finished-text="没有更多了"
      @load="onLoad"
    >
      <van-cell v-for="top in topicList" :key="top.theme.theme_id">
        <div class="topic-item">
          <div class="topic-title">
            #{{ top.theme.name }}#
            <img
              v-if="top.theme.is_rec"
              data-v-5287fbd5=""
              src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/rec.476fe07.png"
              alt=""
              class="tag"
            />
            <img
              v-if="top.theme.is_lottery"
              data-v-5287fbd5=""
              src="//lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/lottery.b40d80b.png"
              alt=""
              class="tag"
            />
          </div>
          <div class="content-box">
            <div class="content">
              <div>
                {{ top.theme.brief }}
              </div>
              <div class="footer">
                {{ top.theme.user_cnt }}位掘友已发布精彩内容
                {{ top.theme.view_cnt }}人阅读
              </div>
            </div>
            <van-image class="image" :src="top.theme.cover" />
          </div>
        </div>
      </van-cell>
    </van-list>
  </van-pull-refresh>
  setup() {
    const state = reactive({
      refreshing: false,
      loading: false,
      finished: false,
      topicList: [],
      cursor: "0",
    });
    const router = useRouter();

    const toBack = () => {
      router.back();
    };

    const onRefresh = () => {
      state.finished = false; //清空列表数据,重新加载
      state.loading = true;
      state.refreshing = true;
      onLoad();
    };
    const onLoad = () => {
      api.queryTopicSquare(state.cursor).then((res) => {
        if (state.refreshing) {
          state.topicList = [];
          state.refreshing = false;
        }
        console.log(res);
        state.cursor = res.cursor;
        state.topicList.push(...res.data);
        state.loading = false;
      });
    };
    return {
      ...toRefs(state),
      toBack,
      onRefresh,
      onLoad,
    };
  },

test.gif

总结

本次分享我们对话题广场进行了布局分析,并最终实现了话题广场数据内容的动态渲染及加载。关于话题广场页功能就基本已经实现了,但跟话题相关的还有另外一个功能:就是点击某个具体话题后会跳转到具体的话题详情页,我们将在明天的分享中实现该功能。今天的分享就到这里了,欢迎小伙伴们点个赞,感谢!