1. 程式人生 > 實用技巧 >關於詳情頁的具體制作(四)

關於詳情頁的具體制作(四)

之後,在一系列圖後,加入尺碼、肩寬、衣長等詳細資訊。

首先,先在detail.js中匯入一個類:

export class GoodsParam{
  constructor(info,rule) {
    this.image = info.images ? info.images[0] : '';
    this.infos = info.set;
    this.sizes = rule.tables;
  }
}

這裡的image這樣寫,是因為介面處不是每一個商品都在尺寸這些詳細資訊這裡有相應圖片。

之後再在detail.vue中,初始化paramInfo,並將從介面處得到的資料傳入paramInfo中。

data() {
    return {
      paramInfo:{ },
    }
  },
this.paramInfo = new GoodsParam(big.itemParams.info, big.itemParams.rule );

之後,建立了一個元件,並將paramInfo傳入該元件中。並按照所需要顯示的,程式碼如下。

<template>
  <div class="param-info" v-if="Object.keys(paramInfo).length !== 0">
    <table v-for="(table, index) in paramInfo.sizes"
           class
="info-size" :key="index"> <tr v-for="(tr, indey) in table" :key="indey"> <td v-for="(td, indez) in tr" :key="indez">{{td}}</td> </tr> </table> <table class="info-param"> <tr v-for="(info, index) in paramInfo.infos"> <td class="info-param-key">{{info.key}}</td> <td class="param-value">{{info.value}}</td> </tr> </table> <div class="info-img" v-if
="paramInfo.image.length !== 0"> <img :src="paramInfo.image" alt=""> </div> </div> </template> <script> export default { name: "detailparaminfo", props:['paramInfo'] } </script> <style scoped> .param-info { padding: 20px 15px; font-size: 14px; border-bottom: 5px solid #f2f5f8; } .param-info table { width: 100%; border-collapse: collapse; } .param-info table tr { height: 42px; } .param-info table tr td { border-bottom: 1px solid rgba(100,100,100,.1); } .info-param-key { /*當value的資料量比較大的時候, 會擠到key,所以給一個固定的寬度*/ width: 95px; }

在尺寸圖下方,即做了使用者評價。

前面的網路請求過程以及從介面拿取來的資料傳入元件的過程不再贅述,主要記錄下關於這個元件的製作。

<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">
      </div>
    </div>
  </div>
</template>

<script>
import {formatDate} from "../../../src/components/common/utils/timejudge";

export default {
  name: "detailcommentinfo",
  props:["commentInfo"],
  filters: {
    showDate(value) {
      let date = new Date(value*1000);
      return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
    }
  }
}
</script>

<style scoped>
.comment-info {
  padding: 5px 12px;
  color: #333;
  border-bottom: 5px solid #f2f5f8;
}

.info-header {
  height: 50px;
  line-height: 50px;
  border-bottom: 1px solid rgba(0,0,0,.1);
}

.header-title {
  float: left;
  font-size: 15px;
}

.header-more {
  float: right;
  margin-right: 10px;
  font-size: 13px;
}

.info-user {
  padding: 10px 0 5px;
}

.info-user img {
  width: 42px;
  height: 42px;
  border-radius: 50%;
}

.info-user span {
  position: relative;
  font-size: 15px;
  top: -15px;
  margin-left: 10px;
}

.info-detail {
  padding: 0 5px 15px;
}

.info-detail p {
  font-size: 14px;
  color: #777;
  line-height: 1.5;
}

.info-detail .info-other {
  font-size: 12px;
  color: #999;
  margin-top: 10px;
}

.info-other .date {
  margin-right: 8px;
}

.info-imgs {
  margin-top: 10px;
}

.info-imgs img {
  width: 70px;
  height: 70px;
  margin-right: 5px;
}
</style>

拿介面的時候發現左下角的時間資料並不是按照年月日給的,而是時間戳(下圖created即是)

為了使得,將該時間戳轉換成年月日時間形式,我封裝了一個函式來矯正時間戳。程式碼如下:

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);
};

之後再在此元件中使用一個過濾器即可實現。

之後,再做了推薦其他商品的元件。

可以看到這個使用者評價之後的模組其實是和主頁的商品詳情差不多的,那就可以把之前封裝的這個元件進行一個複用了。網路請求與初始化並將資料傳入recommends就不再贅述了。主要寫下當時封裝的兩個元件吧。

goodslist元件程式碼

<template>
<div class="goodslist">
  <goodsitem v-for="(item,index) in goods" :goodsitem="item" :key="index">{{item}}</goodsitem>
</div>
</template>

<script>
import goodsitem from "./goodsitem";
export default {
  name: "goodslist",
  components:{goodsitem},
  props:{
    goods:{
      type:Array,
      default(){
        return[]
      }
    }
  }

}
</script>

<style scoped>
.goodslist{
  display: flex;
  flex-wrap:wrap;
  justify-content: space-around;
  padding: 1px;
}

</style>

goodsitem程式碼

<template>
<div class="goodsitem" @click="itemclick">
  <a>
  <img :src="showimage" @load="imageload" >
  <div class="goodsinfo">
    <p>{{goodsitem.title}}</p>
    <span class="price">{{goodsitem.price}}</span>
    <span class="collect">{{goodsitem.cfav}}</span>
  </div>
  </a>
</div>
</template>

<script>
export default {
name: "goodsitem",
  props:{
  goodsitem: {
    type:Object,
    default(){
      return{}
    }
  }
  },
  computed:{
  showimage(){
    return this.goodsitem.image || this.goodsitem.show.img
  }
  },
methods:{
  imageload(){
    this.$bus.$emit("itemimageload")
  },
  itemclick(){
    // console.log("----跳轉到詳情頁");
    this.$router.push('./detail/'+this.goodsitem.iid)
  }
}
}
</script>

<style scoped>
.goodsitem{
  padding-bottom: 40px;
  position: relative;
  width: 48%;
}
.goodsitem img{
  width: 100%;
  border-radius: 5px;
  border:1px solid lightgoldenrodyellow;
}
.goodsinfo{
  font-size: 12px;
  position: absolute;
  bottom: 5px;
  left: 0;
  right: 0;
  overflow: hidden;
  text-align: center;
}
.goodsinfo p{
  overflow: hidden;
  text-overflow:ellipsis;
  white-space: nowrap;
  margin-bottom: 5px;
}
.price{
  color:lightpink;
  margin-right: 20px;
}
.collect{
  position: relative;
}
.collect::before{
  content: '';
  position: absolute;
  left: -15px;
  top:-1px;
  width: 14px;
  height: 14px;
background:url("../../../assets/img/collect.png") 0 0/14px 14px;
}
</style>

這裡直接寫了一個computed來實現這個元件在推薦中使用。在showimage中做一個或判斷,然後將showimage與<img>繫結即可。

之後,再在detail.vue中,將該元件標籤寫入<scroll>裡面,並將goods與recommends進行繫結即可。

 <goodslist :goods="recommends"></goodslist>