项目视频演示地址
搜索页面样式布局完成
要完成样式
- search.wxml
1 2 3 4 5 6 7 8 9
| <view class="item-list-group"> <view class="item-group"> <image src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2635676317.webp" class="thumbnail"></image> <view class="info-group"> <view class="title">六人-泰坦尼克上的中国幸存者</view> <view class="rate-year">8.5分/2020</view> </view> </view> </view>
|
- search.wxss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| .item-list-group{ padding: 10rpx 20rpx; } .item-list-group .item-group{ padding:10rpx 0; border-bottom:1px solid #e4e4e4; display: flex; } .item-group .thumbnail{ width: 80rpx; height: 100rpx; margin-right: 20rpx; } .item-group .info-group{ flex:1; display:flex; flex-direction: column; justify-content: space-between; }
.info-group .title{ font-size: 32rpx; } .info-group .rate-year{ font-size: 32rpx; color: #7b7b7b; }
|
样式渲染完成,采用flex布局
搜索功能实现
- 搜索请求实现
分析:1.在输入框中输入输入文字,那么就应该要获取到输入框中的文字了,但是输入框是单独放在
一个searchbar组件中,我们要获取的话没有那么方便
2.解决:在组件中监听输入框中input事件,将监听到的input输入框中输入的东西及时反馈,然后组件监听得到后再区触发另外一个事件,这样就可以传到外面了。
- 代码实现
bindinput事件是只要你在输入框中新增删除文字它都会去执行事件
searchbar.js
方法实现,组件主要复制将信息传递出去,执行在search中,这样职责划分更明确
search.wxml绑定查找事件
1
| <searchbar bindsearchinput="onSearchInputEvent"></searchbar>
|
serch.js监听事件
此时控制台type类型变为searchinput类型,能够得到用户输入的值
- 发送网路请求url
url.js
1 2 3
| searchUrl: function (q) { return "https://m.douban.com/rexxar/api/v2/search?type=movie&q=" + q }
|
network.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| getSearch:function(params){ var q =params.q; var url = globalurls.searchUrl(q); wx.request({ url: url, success:function(res){ var subjects = res.data.subjects; if (params.success){ params.success(subjects); } } }) }
|
search.js
1 2 3 4 5 6 7 8 9 10 11 12 13
| onSearchInputEvent:function(event){ var that= this;
var value = event.detail.value; network.getSearch({ q:value, success:function(subjects){ that.setData({ subjects:subjects }) } }) },
|
因豆瓣Api限制访问,经常请求不到数据
- 此时能够拿到数据,我们将数据渲染到页面
1 2 3 4 5 6 7 8 9 10 11 12 13
| <searchbar bindsearchinput="onSearchInputEvent"></searchbar> <view class="item-list-group"> <view wx:for="{{subjects}}" class="item-group" wx:key ="{{item.id}}" bindtap="onItemTapEvent" data-id="{{item.id}}" > <image src="{{item.pic.normal}}" class="thumbnail"></image> <view class="info-group"> <view class="title">{{item.title}}</view> <view class="rate-year"> {{item.rating.value}}分{{item.year}}</view> </view> </view> </view>
|
绑定了一个点击事件,这样点击item可以跳转到详情页面中,同时获取id
1
| bindtap="onItemTapEvent" data-id="{{item.id}}"
|
search.js
1 2 3 4 5 6 7 8
| onItemTapEvent:function(event){ var id = event.currentTarget.dataset.id; wx.navigateTo({ url: '/pages/detail/detail?type=movie&id='+id, }) }
|
至此,点击电影也可以跳转到详情页面了
历史搜索记录布局
search.wxml
1 2 3 4 5 6 7
| <view class="history-list-group"> <view class="history-title"> <view class="title">历史记录</view> <view class="clear">清除</view> </view> <navigator class="history-group">泰坦尼克号</navigator> </view>
|
search.wxss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| .history-list-group{ padding:10rpx 20rpx; } .history-list-group .history-title{ display: flex; justify-content: space-between; padding: 20rpx 0; background: #f9f9f9; font-size: 28rpx; color: #9e9e9e; } .history-list-group .history-group{ font-size: 32rpx; padding: 20rpx 0; border-bottom:1px solid #e4e4e4 }
|
优化:history-group可以将它变为一个navigator组件,因为历史搜索是不需要任何操作的,可以直接从本地读取
历史记录功能实现
由于豆瓣api次数限制控制,搜索有时候请求不到,故这里并未实现
学习思路
详情评分bug解决
所有电影,综艺,电视剧评分均为9.7,因为我们这里写成固定的了
代码修改
1
| <stars rate="{{item.rating.value}}"></stars>
|
评论的评分是能够接收的,同理上面的星星评分也是能设置进来的。
分析:stars.js中代码问题
1 2 3 4 5
| lifetimes:{ attached:function(){ this.updateRate(); } }
|
问题原因:attached生命周期函数执行时,rate还没有设置进来,因为rate是通过网络请求加载出来的,需要时间加载进来,所以这时候rate为0默认值。
解决
stars.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| properties: { rate:{ type:Number, value:0, observer: function(newVal, oldVal,changePath) { this.updateRate(); } } }, methods: { updateRate:function(){ var that = this; var rate= that.properties.rate; var inRate = parseInt(rate); var light = parseInt(rate/2); var half = inRate%2; var gray = 5-light-half; var lights = []; var halfs = []; var grays = []; for(var index=1;index<=light;index++){ lights.push(index); } for(var index=1;index<=half;index++){ halfs.push(index); } for(var index=1;index<=gray;index++){ grays.push(index); } var ratetext = rate && rate>0?rate.toFixed(1):"未评分" that.setData({ lights:lights, halfs:halfs, grays:grays, ratetext:ratetext, }); } },
lifetimes:{ attached:function(){ this.updateRate(); } }
|
至此,问题解决了
问题的核心元素是:代码之前执行是放在一个attached中,这个函数是被加载到页面中才会去执行,加载到页面中我们的数据没有从网络中请求到,这时候数据就是默认的0,我们可以用observer函数,一旦监听到改变了评分的值,就可以重新设置一下这个值。