code:点击
做完“天气预报”之后就尝试做“豆瓣电影app”了,学到不少东西,下面是详细步骤:
各个页面效果如下图所示:
看起来还可以吧,接下来先到豆瓣api官网看看,网址:https://developers.douban.com/wiki/?title=api_v2。
如下图所示,一步一步来做准备工作,都是现成的 API ,调用还是挺方便的。
大致目录结构如下:
好了,了解完各个页面需要调用的 API 之后,先进行简单的页面布局,一个一个来做,先来贴首页(正在热映)的布局代码,后面几个页面的布局都可以公用这份代码的!
hotMovies.wxml 文件代码如下:
<view class="wrapper"> <!--顶部轮播图--> <swiper indicator-dots="{{indicatorDots}}" indicator-color="{{indicatorColor}}" indicator-active-color="{{indicatorActivedColor}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"> <block wx:for="{{imgUrls}}"> <swiper-item> <image src="{{item}}" class="slide-image" mode="scaleToFill" /> </swiper-item> </block> </swiper> <view class="search"> <input bindinput="keyword" placeholder="示例输入:'广州'or'guangzhou'" placeholder-style="color:#0ff"/> <button bindtap="requestHotMovies" data-keyword="{{keyword}}">搜索</button><!--data-keyword向函数传参keyword--> </view> <!--中间内容块(电影简介)--> <view wx:for="{{hotMovies}}" wx:for-item="item"> <view class="content"> <view class="picView"> <image class="pic" src="{{item.images.medium}}" id="{{item.id}}" bindtap="toDetail" /> </view> <view class="info"> <view class="name"> 名称:{{item.title}} </view> <view class="score">{{item.rating.average}}分</view> <view class="type"> 类型: <block wx:for="{{item.genres}}" wx:for-item="type"> {{type}}, <!--注意不要使用<view>,不然调不出效果。。--> </block> </view> <view class="director"> 导演: <block wx:for="{{item.directors}}" wx:for-item="director"> {{director.name}}, </block> </view> <view class="actor"> 演员: <block wx:for="{{item.casts}}" wx:for-item="actor"> {{actor.name}}, </block> </view> <view class="time">年份: {{item.year}}</view> </view> </view> </view> </view>
hotMovies.wxss 文件代码如下:
/**htoMovies.wxss**/ .wrapper{ padding:0; margin:0; width:100%; height:100%; } .slide-image{ width:750rpx; height:100%; } .search{ position: absolute; left:0; top:-20rpx; width:100%; height:92rpx; display: flex; flex-direction: row; } input{ height:1rem; flex-grow: 1; /**剩余空间都给我*/ line-height: 70rpx; border:2rpx solid #ccc; margin:20rpx; border-radius: 10rpx; font-size: 0.8rem; } button{ color:#0ff; width:130rpx; height:50rpx; line-height: 50rpx; margin:24rpx 30rpx 0rpx 0rpx; font-size: 0.8rem; } .content{ width:100%; height:300rpx; padding:10rx; display: flex; flex-direction: row; border-bottom: 2rpx solid #CCCCCC; } .picView{ float:left; padding:20rpx 15rpx; } .pic{ width:210rpx; height:260rpx; } .info{ float:left; display: flex; flex-direction: column; color:#888888; padding-top:20rpx; font-size: 30rpx; } .name{ color:#000; width:100%; font-size: 32rpx; margin-bottom: -19rpx; } .score{ position: relative; width:80rpx; float:right; top:-18rpx; color:#8C5A0D; right:-433rpx; } .type{ display: flex; flex-direction: row; margin-bottom: 10rpx; } .director{ display: flex; flex-direction: row; margin-bottom: 10rpx; } .actor{ margin-bottom: 10rpx; }
hotMovies.js 文件代码如下:
//hotMovies.js //获取应用实例 var app = getApp() Page({ data: { imgUrls: [ '../../assets/imgs/1.jpg', '../../assets/imgs/2.jpg', '../../assets/imgs/3.jpg' ], indicatorDots: true, autoplay: true, interval: 5000, duration: 1000, indicatorColor: '#ff0', indicatorActivedColor: '#f00', }, //事件处理函数 bindViewTap: function () { wx.navigateTo({ url: '../recommendMovies/recommendMovies' }) }, onLoad: function () { console.log('onLoad') var that = this; //调用应用实例的方法获取全局数据 app.getUserInfo(function (userInfo) { //更新数据 that.setData({ }) }); that.requestHotMovies(); }, requestHotMovies: function (event) { var keyword = null; if(event){//点击了搜索按钮才有此值 keyword = event.currentTarget.dataset.keyword; } var city = keyword ? keyword : '广州'; console.log('city:'+city); var that = this; var url = 'https://api.douban.com/v2/movie/in_theaters'; var data = { city: city }; console.log('0:'+wx.getStorageSync('city')); wx.setStorageSync('city', city); //覆盖原来key的内容。 console.log('1:' +wx.getStorageSync('city')); var hotMovies; //如果本地已经存储就不再请求 hotMovies = wx.getStorageSync('hotMovies'+city); if (!hotMovies) { wx.request({ url: url, //请求api的接口地址 data: data,//传递的参数 header: { 'content-type': 'json'//不能写"application/json"否则报400错误。 }, success: function (res) {//请求数据成功后才执行的回调函数。 /*console.log(res.data.subjects);*/ hotMovies = res.data.subjects; console.log(hotMovies); that.setData({/**放在外部没效果,因为还没执行成功就分配了数据结果是空数据 */ hotMovies: hotMovies }); that.saveData(hotMovies,city);//第一次请求之后存储数据在本地 } }); } else { console.log(hotMovies); that.setData({ hotMovies: hotMovies }); } }, toDetail: function (event) {//参数:事件对象 console.log(event); wx.navigateTo({ url: '/pages/detail/detail?id=' + event.currentTarget.id, }) }, saveData: function (data,city) { wx.setStorage({ key: 'hotMovies'+city, data: data, }) }, keyword:function(event){ this.setData({ keyword:event.detail.value /**获取input输入的值并设置到搜索值 */ }); }, })
主要运用到了 swiper 组件进行图片的轮播,wx.request 组件请求 api 接口,获取正在热映电影的 api 接口地址为:
https://api.douban.com/v2/movie/in_theaters?city=yourCity。
用到了 for 循环等,注意for循环用<block></block>来循环比较好,不要用<view></view>,不然后者相当于<div></div>,会占据块空间,导致某些时候布局不便。用了 input 组件进行输入搜索关键字,还有 button 组件等等。
点击电影图片跳到详情页面用到了wx.navigateTo({ url:'urlPath' });方法。
因为考虑到频繁请求 api 接口有次数限制,所以我将第一次获取到的数据保存在本地,以后直接使用而不是重复请求,不过这样有个问题就是当它更新时数据不会更新过来,因为是“死”数据了,还没去尝试解决。要注意的一点时,请求 wx.request 时,header:{ 'conten-type':'json' }不能写成 'application/json' 不然会一直报400错误,应该是版本问题。
保存数据:key->data
wx.setStorage({ key: 'hotMovies'+city, data: data, }) 若要覆盖key的原来存放的值,使用 wx.setStorageSync('key', data);读入数据:key
var data = wx.getStorageSync('key');
未完待续!