商品参数信息在返回data中的分布也很松散,将它们整合为一个类GoodsParam,然后将数据保存在GoodsParam的实例paramsInfo中,发送给子组件DetailParamsInfo:

export class GoodsParam{
  constructor(info,rule) {
    this.image = info.images ? info.images[0] : '';
    this.infos = info.set;
    this.sizes = rule.tables;
  }
}
      this.paramsInfo = new GoodsParam(
        data.itemParams.info,
        data.itemParams.rule
      );
<detail-params-info :param-info="paramsInfo" ref="params"></detail-params-info>

接下来就是布局的工作了,没有什么难点,无非是使用v-for来生成表格以及表格的每一行:

 1 <template>
 2   <div class="param-info" v-if="Object.keys(paramInfo).length !== 0">
 3 
 4     <table v-for="(table, index) in paramInfo.sizes"
 5            class="info-size" :key="index">
 6       <tr v-for="(tr, indey) in table" :key="indey">
 7         <td v-for="(td, indez) in tr" :key="indez">{{td}}</td>
 8       </tr>
 9     </table>
10     
11     <table class="info-param">
12       <tr v-for="(info, index) in paramInfo.infos" :key="index">
13         <td class="info-param-key">{{info.key}}</td>
14         <td class="param-value">{{info.value}}</td>
15       </tr>
16     </table>
17     <div class="info-img" v-if="paramInfo.image.length !== 0">
18       <img :src="paramInfo.image" alt="">
19     </div>
20   </div>
21 </template>

 

评论信息的显示:首先判断该商品下是否有评论,有则获取,并将其发送给DetailCommentInfo组件:

//  6、获取评论信息
      if (data.rate.cRate !== 0) {
        this.commentInfo = data.rate.list[0];
      }
<detail-comment-info :comment-info="commentInfo" ref="comment"></detail-comment-info>

剩下的布局,除了一个关于日期格式化的过滤器,其它都很好理解:

<template>
  <div v-if="Object.keys(commentInfo).length !== 0" class="comment-info">
    <div class="info-header">
      <div class="header-title">用户评价</div>
      <div class="header-more">更多</div>
    </div>
    <div class="info-user">
      <img :src="commentInfo.user.avatar" alt="" />
      <span>{{ commentInfo.user.uname }}</span>
    </div>
    <div class="info-detail">
      <p>{{ commentInfo.content }}</p>
      <div class="info-other">
        <span class="date">{{ commentInfo.created | showDate }}</span>
        <span>{{ commentInfo.style }}</span>
      </div>
      <div class="info-imgs">
        <img
          :src="item"
          v-for="(item, index) in commentInfo.images"
          :key="index"
        />
      </div>
    </div>
  </div>
</template>

可以看到这个showDate过滤器以commentInfo.created为参数,定义如下:

filters: {
    showDate(value) {
      let date = new Date(value * 1000);
      return formatDate(date, "yyyy-MM-dd hh:mm:ss");
    },
  }
commentInfo.created为一串时间戳,如:1537791634。它表示UTC时间,扩大1000倍后转化为毫秒表示。showDate中先将时间戳转化为Date对象,再通过调用formatDate函数,让Date对象按照第二个参数指定的日期格式进行显示。下面解析一下formatDate函数的代码,顺便对Date对象做个总结:
export function formatDate(date, fmt) {
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  let o = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds()
  };
  for (let k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      let str = o[k] + '';
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
    }
  }
  return fmt;
};

function padLeftZero (str) {
  return ('00' + str).substr(str.length);
};

1、如果指定格式fmt中匹配到一个或多个y,则将第一个捕获组RegExp.$1替换为date中的年份。先调用getFullYear()获取年份,再将其转换为字符串,最后通过substr方法将年份截取为合适的长度。

2、后面的月日时分秒的匹配类似,所以定义一个对象o,通过遍历o属性完成对其余单位的匹配。如果捕获组的长度大于1,则通过padLeftZero为其补零。

(str两位 原样返回;15  0015  ;str一位 补一个零:5   005)

 
posted on 2021-06-29 23:28  springxxxx  阅读(79)  评论(0编辑  收藏  举报