豆瓣评分项目实战

1.封装组件
封装效果如下:在这里插入图片描述

// componets/itemBox/itemBox.js
Component({
  properties: {
    item: {
      type: Object,
      value: {}
    },
    itemurl: {
      type: String,
      value: ""
    }
  },
  data: {},
  lifetimes: {
    attached: function () {
    }
  },
  methods: {
  }
})

<!--componets/itemBox/itemBox.wxml-->
<navigator wx:if="{{item}}" class='item-navigator' url="{{itemurl}}">
  <view class='item-group'>
    <view class='thumbnail-group'>
      <image class='thumbnail' src='{{item.cover.url}}'></image>
    </view>
    <view class='item-title'>{{item.title}}</view>
    <star rate="{{item.rating.value}}" starSize="25" fontSize="25"></star>
  </view>
</navigator>
<view wx:else class="item-navigator"></view>
/* componets/itemBox/itemBox.wxss */
.item-navigator{
  width: 200rpx;
  margin-right: 20rpx;
  display: inline-block;
}
.item-navigator .item-group{
  width: 100%;
}
.item-group .thumbnail-group{
  width: 100%;
  height: 284rpx;
}
.thumbnail-group .thumbnail{
  width: 100%;
  height: 100%;
}
.item-group .item-title{
  font-size: 28rpx;
  text-align: center;
  margin-top: 20rpx;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  margin-bottom: 20rpx;
}
/* componets/itemBox/itemBox.json */{
  "component": true,
  "usingComponents": {
    "star": "/componets/star/star"
  }
}

在这里插入图片描述

// componets/listView/listView.js
Component({
  properties: {
    title: {
      type: String,
      value: ""
    },
    moreurl: {
      type: String,
      value: ""
    },
    items: {
      type: Array,
      value: []
    },
    type: {
      type: String,
      value: ""
    }
  },
  data: {},
  lifetimes: {
  },
  methods: {
  }
})

<!--componets/listView/listView.wxml-->
<view class='module-group'>
  <view class='module-top'>
    <view class='module-title'>{{title}}</view>
    <navigator url="{{moreurl}}" class='module-more'>更多</navigator>
  </view>
  <scroll-view class='module-scroll-view' scroll-x="{{true}}">
    <itemBox wx:for="{{items}}" wx:key="{{item.title}}" item="{{item}}" itemurl="/pages/detail/detail?type={{type}}&id={{item.id}}"></itemBox>
  </scroll-view>
</view>

.module-group{
  padding: 40rpx;
  background-color: #fff;
}
.module-group .module-top{
  font-size: 36rpx;
  display: flex;
  justify-content: space-between;
}
.module-top .module-title{
  color: #494949;
}
.module-top .module-more{
  color: #41be57;
}
.module-scroll-view{
  margin-top: 40rpx;
  width: 100%;
  height: 400rpx;
  white-space: nowrap;
}

在这里插入图片描述

// componets/star/star.js
Component({
  properties: {
    // 评分
    rate:{
      type:Number,
      value: 5.3
    },
    //星星大小rpx
    starSize:{
      type:Number,
      value: 30
    },
    // 是否显示文字
    isText:{
      type:Boolean,
      value: true
    },
    // 评分文字颜色
    fontColor:{
      type:String,
      value: '#FFB712'
    },
    // 评分文字大小rpx
    fontSize:{
      type:Number,
      value: 30
    }
  },
  data: {},
  lifetimes: {
    attached: function () {
      this.updateRate();
    }
  },
  methods: {
    updateRate: function () {
      var that = this;
      var rate = this.properties.rate; //评分
      var intRate = parseInt(rate);    //将输入的评分取整
      var light = parseInt(intRate / 2);  //计算亮着的星星,评分除以二后取整
      var half = intRate % 2;   //半星的计算就是取整后的评分取余
      var gray = 5 - light - half; //灰色星星的计算
      var lights = [];
      var halfs = [];
      var grays = [];
      for (var i = 1; i <= light; i++) {
        lights.push(i)
      }
      for (var i = 1; i <= half; i++) {
        halfs.push(i)
      }
      for (var i = 1; i <= gray; i++) {
        grays.push(i)
      }
      // toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。
      var ratetext = rate && rate > 0 ? rate.toFixed(1) : "未评分"
      this.setData({
        lightStar: lights,
        halfStar: halfs,
        grayStar: grays,
        ratetext: ratetext
      })
    }
  }
})
<view class="starBox">
  <image style="width: {{starSize}}rpx;height: {{starSize}}rpx;" wx:for="{{lightStar}}" src="/images/x3.png" />    
  <image style="width: {{starSize}}rpx;height: {{starSize}}rpx;" wx:for="{{halfStar}}" src="/images/x2.png" />    
  <image style="width: {{starSize}}rpx;height: {{starSize}}rpx;" wx:for="{{grayStar}}" src="/images/x1.png" />    
  <text wx:if="{{isText}}" style="color:{{fontColor}};font-size:{{fontSize}}rpx;margin-left:5rpx">{{ratetext}}</text>
</view>
/* componets/star/star.wxss */
.starBox{
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

在这里插入图片描述

// componets/userComment/userComment.js
Component({
  properties: {
    item: {
      type: Object,
      value: {}
    }
  },
  data: {},
  methods: {
  }
})
<!--componets/userComment/userComment.wxml-->
<view class='comment-group'>
  <view class='left-comment'>
    <image class="avatar" src="{{item.user.avatar}}"></image>
  </view>
  <view class='right-comment'>
    <view class='username-rate'>
      <text class='username'>{{item.user.name}}</text>
      <star rate="{{item.rating.value*2}}" starsize="30" isText='{{false}}'></star>
    </view>
    <view class="release-time">{{item.create_time}}</view>
    <view class='content'>{{item.comment}}</view>
  </view>
</view>

/* componets/userComment/userComment.wxss */
.comment-group{
  display: flex;
  justify-content: flex-start;
  padding-top: 40rpx;
}
.comment-group .left-comment{
  width: 70rpx;
  margin-right: 20rpx;
}
.left-comment .avatar{
  width: 70rpx;
  height: 70rpx;
  border-radius: 50%;
}
.comment-group .right-comment{
  flex: 1;
}
.right-comment .username-rate{
  display: flex;
  justify-content: flex-start;
  align-items: center;
}
.username-rate .username{
  font-size: 36rpx;
  margin-right: 20rpx;
}
.release-time{
  color: #b3b3b3;
  font-size: 32rpx;
  margin-top: 10rpx;
}
.content{
  font-size: 32rpx;
  color: #353535;
  margin-top: 10rpx;
}

2.封装接口,方法

/* componets/utils/url.js */
const urlList = [
 "https://m.douban.com/rexxar/api/v2/subject_collection/movie_showing/items",
  "https://m.douban.com/rexxar/api/v2/subject_collection/tv_hot/items",
 "https://m.douban.com/rexxar/api/v2/subject_collection/tv_variety_show/items",
  "https://m.douban.com/rexxar/api/v2/search"
]
const parameter = {
  itemDetail(type, id) {
    return "https://m.douban.com/rexxar/api/v2/" + type + "/" + id
  },
  typeTag(type, id) {
    return "https://m.douban.com/rexxar/api/v2/" + type + "/" + id + "/tags?count=8"
  },
  commentary(type, id) {
    return "https://m.douban.com/rexxar/api/v2/"+type+"/"+id+"/interests"
  }
}
export { urlList,parameter }
/* componets/utils/net.js */
const netWork = {
  listData(obj) {
    new Promise(function (resolve, reject) {
      wx.showLoading({
      })
      wx.request({
        url: obj.url,
        data: {
          count: obj.num
        },
        success: (res) => {
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        }
      })
    }).then(res => {
      wx.hideLoading()
      obj.success(res)
    }).catch(res => {
      console.log('网络请求失败', res)
    })
  },
  search(obj) {
    new Promise(function (resolve, reject) {
      wx.showLoading({
      })
      wx.request({
        url: obj.url,
        data: {
          q: obj.value
        },
        success: (res) => {
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        }
      })
    }).then(res => {
      wx.hideLoading()
      obj.success(res)
    }).catch(res => {
      console.log('网络请求失败', res)
    })
  },
  itemData(obj) {
    new Promise(function (resolve, reject) {
      wx.showLoading({
      })
      wx.request({
        url: obj.url,
        success: (res) => {
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        }
      })
    }).then(res => {
      wx.hideLoading()
      obj.success(res)
    }).catch(res => {
      console.log('网络请求失败', res)
    })
  },
  commentary(obj) {
    new Promise(function (resolve, reject) {
      wx.showLoading({
      })
      wx.request({
        url: obj.url,
        data:{
          count: obj.count,
          start: obj.start
        },
        success: (res) => {
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        }
      })
    }).then(res => {
      wx.hideLoading()
      obj.success(res)
    }).catch(res => {
      console.log('网络请求失败', res)
    })
  }
}
export { netWork }

3.显示
在这里插入图片描述

// pages/index/index.js
import { urlList } from '../../utils/url'
import { netWork } from '../../utils/net'
Page({
  // 搜索框动效
  showSearch: function () {
    this.setData({
      center: "center"
    })
    setTimeout(() => {
      this.setData({
        center: "left"
      })
    }, 3000)
  },
  /**
   * 页面的初始数据
   */
  data: {
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this
    // 电影
    netWork.listData({
      url: urlList[0],
      num: 10,
      success(data) {
        that.setData({
          movies: data.data.subject_collection_items
        })
        // console.log(that.data.movies)
      }
    })
    // 电视剧
    netWork.listData({
      url: urlList[1],
      num: 10,
      success(data) {
        that.setData({
          teleplay: data.data.subject_collection_items
        })
        // console.log(that.data.movies)
      }
    })
    // 综艺
    netWork.listData({
      url: urlList[2],
      num: 10,
      success(data) {
        that.setData({
          variety: data.data.subject_collection_items
        })
        // console.log(that.data.movies)
      }
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
<!--pages/index/index.wxml-->
<search isnavigator="{{true}}" position="{{center}}" bindtap="showSearch"></search>
<listView title="电影" items="{{movies}}" moreurl="/pages/list/list?type=movie" type="movie"></listView>
<listView title="电视剧" items="{{teleplay}}" moreurl="/pages/list/list?type=tv" type="tv"></listView>
<listView title="综艺" items="{{variety}}" moreurl="/pages/list/list?type=tvshow" type="tv"></listView>
<!-- <userComment wx:for="{{comments}}" item="{{item}}"></userComment> -->

在这里插入图片描述

// pages/list/list.js
import { urlList } from '../../utils/url'
import { netWork } from '../../utils/net'
var current = 1;
Page({

  /**
   * 页面的初始数据
   */
  data: {
    num:9
  },
  // 上拉加载
  loadData: function (num,type) {
    var that = this
    if(type == 'movie')
    {
      netWork.listData({
        url: urlList[0],
        num: num * current,
        success(data) {
          that.setData({
            listData: data.data.subject_collection_items
          })
          // console.log(that.data.movies)
        }
      })
    }else if(type == 'tv')
    {
      netWork.listData({
        url: urlList[1],
        num: num * current,
        success(data) {
          that.setData({
            listData: data.data.subject_collection_items
          })
          // console.log(that.data.movies)
        }
      })
    }else if(type == 'tvshow')
    {
      netWork.listData({
        url: urlList[2],
        num: num * current,
        success(data) {
          that.setData({
            listData: data.data.subject_collection_items
          })
          // console.log(that.data.movies)
        }
      })
    }
    
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(options.type);
    current=1
    // var that = this
    this.setData({
      type:options.type
    })
    this.loadData(this.data.num,this.data.type) 
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    current++;
    this.loadData(this.data.num,this.data.type) 
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
<!--pages/list/list.wxml-->
<view class="listBox">
  <itemBox wx:for="{{listData}}" wx:key="{{item.title}}" item="{{item}}" itemurl="/pages/detail/detail?type={{type}}&id={{item.id}}"></itemBox>
</view>


/* pages/list/list.wxss */
.listBox{
  width: 660rpx;
  margin: 30rpx auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
}

在这里插入图片描述

// pages/detail/detail.js
import { urlList,parameter } from '../../utils/url'
import { netWork } from '../../utils/net'
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },
  netWork(type,id){
    var that = this
    // 详情
    netWork.itemData({
      url: parameter.itemDetail(type,id),
      success(data) {
        that.setData({
          itemData: data.data
        })
      }
    })
    // 标签
    netWork.itemData({
      url: parameter.typeTag(type,id),
      success(data) {
        that.setData({
          tagData: data.data.tags
        })
      }
    })
    // 短评
    netWork.commentary({
      url: parameter.commentary(type,id),
      count: 3,
      start: 0,
      success(data) {
        that.setData({
          commentaryData: data.data.interests,
          total:data.data.total
        })  
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.netWork(options.type,options.id)
    this.setData({
      type: options.type,
      id: options.id
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
<!--pages/detail/detail.wxml-->
<view class="detailBox" wx:if="{{itemData}}">
  <view style="font-weight: bold;font-size:45rpx">{{itemData.title}}</view>
  <view style="display:flex">
    <view class="detailBox-l">
      <view style="display:flex">
        <star wx:if="{{itemData.rating.value != undefined}}" rate="{{itemData.rating.value}}" starSize="23" fontSize="23" fontColor="#000"></star>
        <view style="font-size: 23rpx;margin-left:10rpx;color: #A9A9A9">{{itemData.review_count}}人评价</view>
      </view>
      <view class="textBox">{{itemData.durations}} {{itemData.genres[0]}}/{{itemData.genres[1]}}</view>
      <view class="textBox">{{itemData.pubdate}}</view>
      <view class="textBox">{{itemData.card_subtitle}}</view>
    </view>
    <view class="detailBox-r">
      <image src="{{itemData.pic.large}}" mode="aspectFill"></image>
    </view>
  </view>
  <!-- 豆瓣成员常用标签 -->
  <view class="detailBox-tag">
    <view style="font-size: 26rpx;color:#A9A9A9">豆瓣成员常用标签</view>
    <view class="detailBox-tag-box" >
      <view wx:for="{{tagData}}">{{item}}</view>
    </view>
  </view>
  <!-- 短评 -->
  <view>
    <view class="detailBox-commentary">短评({{total}}</view>
    <userComment wx:for="{{commentaryData}}" item="{{item}}"></userComment>
    <navigator class="more-commentary" url="/pages/comment/comment?img={{itemData.pic.large}}&title={{itemData.title}}&pf={{itemData.rating.value}}&type={{type}}&id={{id}}">查看更多短评</navigator>
  </view>
</view>
/* pages/detail/detail.wxss */
.detailBox{
  width: 100vw;
  box-sizing: border-box;
  padding: 30rpx;
  display: flex;
  flex-direction: column;
}
.detailBox .detailBox-l{
  width: 384rpx;
  margin-right: 60rpx;
  line-height: 100rpx;
}
.detailBox .detailBox-l .textBox{
  font-size: 30rpx;
  line-height: 60rpx;
  /* 允许在单词内换行 */
  word-break:break-all;  
} 
.detailBox .detailBox-r image{
  width: 250rpx;
  height: 380rpx;
}
.detailBox .detailBox-tag{
  width: 100%;
  margin-top: 20rpx;
  display: flex;
  flex-direction: column;
}
.detailBox .detailBox-tag .detailBox-tag-box{
  display: flex;
  flex-wrap: wrap;
}
.detailBox .detailBox-tag .detailBox-tag-box view{
  overflow: hidden;
  background-color: #F5F5F5;
  border-radius: 40rpx;
  padding: 10rpx 20rpx;
  text-align: center;
  font-size: 28rpx;
  font-weight: 500;
  margin: 30rpx 0rpx 0 13rpx;
}
.detailBox-commentary{
  width: 90vw;
  margin: 80rpx auto 20rpx auto ;
  font-size: 26rpx;
  color:#A9A9A9
}
.more-commentary{
  width: 100vw;
  text-align: center;
  color: #43BE58;
  margin-top: 30rpx;
}

在这里插入图片描述

// pages/comment/comment.js
import { urlList, parameter } from '../../utils/url'
import { netWork } from '../../utils/net'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    isButton: true,
    start: 0
  },
  // 影评数据
  commentData(type, id) {
    var that = this
    netWork.commentary({
      url: parameter.commentary(type, id),
      count: 8,
      start: 0,
      success(data) {
        that.setData({
          commentData: data.data.interests,
          total: data.data.total,
        })
      }
    })
  },
  // 上一页
  pageUpClick() {
    var that = this
    netWork.commentary({
      url: parameter.commentary(that.data.type, that.data.id),
      count: 8,
      start: that.data.start - 8,
      success(data) {
        that.setData({
          commentData: data.data.interests,
          total: data.data.total,
          start: that.data.start - 8
        })
        if (that.data.start == 0) {
          // 禁用上一页
          that.setData({
            isButton: true
          })
        } 
        wx.pageScrollTo({
          scrollTop: 0,
        })
      }
    })
  },
  // 下一页
  pageDownClick() {
    var that = this
    netWork.commentary({
      url: parameter.commentary(that.data.type, that.data.id),
      count: 8,
      start: that.data.start + 8,
      success(data) {
        that.setData({
          commentData: data.data.interests,
          total: data.data.total,
          start: that.data.start + 8,
          isButton: false
        })
        wx.pageScrollTo({
          scrollTop: 0,
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.setData({
      img: options.img,
      title: options.title,
      pf: options.pf,
      type: options.type,
      id: options.id
    })
    this.commentData(options.type, options.id)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
<!--pages/comment/comment.wxml-->

<view wx:if="{{commentData}}">
  <view class="commentbox">
    <image src="{{img}}" />
    <view class="commentbox-title">{{title}}</view>
    <view style="color:#A9A9A9;font-size:28rpx;width:120rpx">{{pf}}</view>
  </view>
  <!-- 短评 -->
  <view class="commentary-box">
    <view class="commentary">全部影评({{total}}</view>
    <userComment wx:for="{{commentData}}" item="{{item}}"></userComment>
    <view class="button-box">
      <button style="width:230rpx" disabled="{{isButton}}" catch:tap="pageUpClick">上一页</button>
      <button style="width:230rpx"  catch:tap="pageDownClick">下一页</button>
    </view>
  </view>

</view>
/* pages/comment/comment.wxss */
.commentbox {
  display: flex;
  width: 90vw;
  margin: 0 auto;
  height: 10vh;
  align-items: center;
}

.commentbox image {
  width: 50rpx;
  height: 60rpx;
  margin-right: 15rpx;
}

.commentary {
  width: 90vw;
  margin: 20rpx auto 20rpx auto;
  font-size: 40rpx;
  font-weight: bold;
}

.commentary-box {
  width: 100vw;
  box-sizing: border-box;
  padding: 30rpx;
  display: flex;
  flex-direction: column;
}

.button-box {
  width: 100vw;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  justify-content: space-evenly;
  margin: 50rpx 0;
}
.button-box button{
  background-color:	#F5F5F5;
}

.commentbox-title {
  color: #4CC05F;
  margin-right: 15rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

项目结构
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值