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;
}
项目结构