【项目实战】基于Vue3+Vant3造一个网页版的类掘金app项目 - 签到状态数据的动态绑定

461 阅读4分钟

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

前言

上篇分享中,我们实现了点击签到按钮进行签到功能,同时实现点击已签按钮或者签到成功后跳转到签到日历页面,并且对签到日历页面实现了简单封装,实现签到天数和当前矿石数的静态数据绑定,以及日历控件的展示,但是数据都是静态的,并且也没有对页面进行美化。接下来今天的分享中,我们将实现签到天数和当前矿石数的动态获取及绑定,并改造日历控件将每日的签到状态动态绑定。今天要实现的功能:

  • 签到天数和当前矿石数的动态获取及绑定
  • 每日签到状态及获取矿石数的动态绑定

签到天数和当前矿石数的动态获取及绑定

在前面文章的分享中我们已经将后端接口都进行了分析和封装,而本次获取签到天数和矿石数所用到的API是:

  • get_count用于获取连续签到天数和累计签到天数
  • get_cur_point 用于获取当前矿石数 具体是实现步骤也很简单:
  • 声明三个响应式变量:days、totalDays和currentPoint
  • 调用已经封装好的getCount和getPoint接口获取数据并绑定给上面的三个变量
  • 将静态数据用三个变量代替变为动态数据绑定
  • 样式美化 代码及效果如下:

image.png

<div class="checkin-count">
    <div class="days">
      <div>连续签到天数</div>
      <div>{{ days }}</div>
    </div>
    <div>|</div>
    <div class="days">
      <div>当前矿石数</div>
      <div>{{ currentPoint }}</div>
    </div>
  </div>
setup() {
    const state = reactive({ days: 0, totalDays: 0, currentPoint: 0 });
    const router = useRouter();
    const back = function () {
      router.push("/");
    };
    api.getMonth().then((res) => {
      console.log(res);
    });
    api.getCount().then((res) => {
      state.days = res.data.cont_count;
    });
    api.getPoint().then((res) => {
      state.currentPoint = res.data;
    });
    return {
      ...toRefs(state),
      back,
    };

<style lang="less">
.checkin-count {
  display: flex;
  align-content: center;
  width: 100%;
  height: 150px;
  line-height: 120px;
  text-align: center;
  background-color: #1e80ff;
  border-radius: 5px;
  color: #fff;
  & .days {
    display: flex;
    flex-direction: column;
    & div {
      width: 150px;
      height: 20px;
    }
    & div:nth-child(2) {
      font-size: 36px;
      margin-top: 8px;
    }
  }
}
</style>

每天签到状态动态绑定

上面已经将连续签到天数和当前矿石数变为动态绑定了,接下来就是将日历上的每天签到状态及获得的矿石数也变成动态绑定的形式。我们来看下vant的日历控件,默认情况下它会将每个月份的每天都展示出来,可以上下滑动切换月份,但是这并不是我们想要的,在我们的实战中只需要展示当前月份的每一天就可以了,因此还需要为控件设置两个属性,分别是:min-date和max-date,并且需要根据当前月份动态获取天数来为这两个属性赋值。 再来看下数据接口,签到状态所涉及的接口:get_by_month,而这个接口中返回的数据就是当前月份的天数以及每天的签到状态,因此我们就可以根据这个接口返回数据的数量来计算出max-date属性的值,但是从这个接口中返回的数据来看,所返回的日期是一个时间戳格式,因此我们得先将时间戳转换为日期格式,然后再动态的将数据绑定到日历控件的每天上。 image.png 实现思路:

  • 首先封装一个转换方法用于将时间戳转换为日期格式
    • 在src下新增文件夹utils
    • 在utils下新建一个utils.js文件
  • 定义minDate和maxDate两个响应式属性,minDate赋值为当前月1号,maxDate根据接口返回数据的数量计算
  • 定义一个formatter方法,用于将签到状态及获取矿石数动态绑定到日历控件
    • 上图返回的数据中 date就是当前日期的时间戳格式
    • status: 3表示已签到,1表示今天已签,0表示今天未签或漏签,4表示时间还未到
    • point表示已获取或应获取的矿石数
  • 样式美化,已签状态标为掘金蓝色,今日标为红色(如果未签提示未签),未到达日期标为灰色 效果图及源码如下:
  <van-calendar
    :show-title="false"
    readonly
    :min-date="minDate"
    :max-date="maxDate"
    :poppable="false"
    :show-confirm="false"
    :style="{ height: '500px' }"
    :formatter="formatter"
  />
 setup(){
    const getDate = async function () {
      let { data } = await api.getMonth();
      const currentDate = new Date();
      const curM = currentDate.getMonth();
      const curY = currentDate.getFullYear();
      state.minDate = new Date(curY, curM, 1);
      state.maxDate = new Date(curY, curM, data.length);
      state.data = data;
    };
    getDate();
    const formatter = function (day) {
      const date = day.date.getDate();
      state.data.forEach((item) => {
        let d = new Date(utils.getLocalTime(item.date)).getDate();
        if (date === d) {
          if (item.status === 3) {
            day.bottomInfo = `+${item.point}`;
            day.className = "day";
          } else if (item.status === 1 && d === new Date().getDate()) {
            day.bottomInfo = `+${item.point}`;
          } else if (item.status === 0 && d === new Date().getDate()) {
            day.bottomInfo = `未签`;
          } else if (item.status === 4) {
            day.bottomInfo = `+${item.point}`;
            day.className = "day-future";
          }
        }
      });
      return day;
    };

    return {
      ...toRefs(state),
      back,
      formatter,
    };
}
.day {
  color: #1e80ff;
}
.day-future {
  color: #b7b7b7;
}

image.png

总结

本次分享我们实现了连续签到天数、当前矿石数以及每日签到状态的动态绑定,并将每日签到所获得的矿石数以及未来日期签到应或得到矿石数都动态的展示在每日标签的下方。今天的分享就到这里了。明天将继续来完善我们的网页版掘金app。