微信小程序实战小小应用——豆瓣电影


昨天趁着项目结束的空闲期,自己看了一下微信小程序的开发,试着用豆瓣的开源API做了一个小应用,很小很小的应用,主要是展示最近上映的电影列表以及电影的详情页展示。
包含的主要技术点如下:

  • 底部tab页标签的导航切换
  • 基本的布局展示(本例中多使用flex布局),图文混排
  • 事件处理;网络请求
  • 水平滚动scroll-view的实现

运行的效果演示如下,其中“加入想看清单”功能和第二个tab的功能没有实现。主要原因是我一个同事昨天晚上给我一个优酷会员账号然后我看到现在的白夜追凶......所以具体的功能开发以后有时间再慢慢完善吧。


废话不多说,开始码字做笔记。

 1.开发环境及项目结构搭建

微信小程序的开发工具是微信自己开发的一款工具,说实话,很渣的一款IDE,代码提示、代码格式化什么的做得都很炸,而且经常无缘无故的黑屏,心累,但是没办法,还是得用。下载地址:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html   。下载好安装后,点击新建项目按照提示创建一个quick-start项目,它会帮你初始化一个demo项目,并且包含标准的目录结构。其中各个目录及相关文件的作用官方的API都介绍的很详细,这里就不废话了。文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/MINA.html

至此环境已经搭建完成,由于项目是有两个tab标签的,所以我们要准备两个icon图标,我再网上下了几个,在pages目录下新建了一个assets目录用于存放一些图片等资源信息。注意,直接拷贝到开发工具的该目录下是无效的,要手动的在硬盘上打开pages/assets的物理路径,然后将图片拷进去才可以看见。现在我们可以配置tab页的信息了。

在项目根路径下的app.json文件中,加入如下代码:

"tabBar": {
    "list": [
      {
        "pagePath": "pages/movielist/movielist",
        "text": "电影列表",
        "iconPath":"pages/assets/home1.png",
        "selectedIconPath":"pages/assets/home2.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "pages/assets/user2.png",
        "selectedIconPath":"pages/assets/user1.png"
      }
    ]
  }

各参数的含义文档里都有。pagePath是指点击tab标签后主界面显示的页面,text是tab的显示文字,iconPath和selectedIconPath是配置tab的图片信息,前者是正常显示的,后者是选中后显示的。现在我们的两个page还没有编写,所以编译项目是肯定报错的。下面开始编写具体的页面。

 2.开发电影列表页

首先在pages目录下创建一个文件夹movielist,再在movielist目录中新建一个page,工具会自动给你创建四个相关页面的。注意quick-start项目给我们默认创建了两个页面,一个index一个log。我们要在app.json里面的pages配置中,将本页面移到第一个。因为小程序默认就是用app.json中pages配置项的第一个值作为入口页面的。本例采用的是豆瓣开源API,它的接口地址是:https://github.com/jokermonn/-Api/blob/master/DoubanMovie.md#introduce 。本页面主要是调用其第一个接口, 查看最近上映的电影信息。

界面wxml文件,其中bindtap是绑定点击事件,data-id是给绑定的事件传递参数,hover-class是当点击该view时显示的样式,因为要区别点击项和其他项的区别所以要指定,wx:for是循环对象,wx:key是给循环的每一项指定一个id,注意:循环的每一项的对象,默认都是用item来引用的:

<view class="box">
  <view class="item" bindtap="showInfo" data-id="{{item.id}}" hover-class="tapClass"
  wx:for="{{movies.subjects}}" wx:key="{{item.id}}">
    <image class="img" mode="aspectFit" src="{{item.images.large}}"></image>
    <view class="movie-info">
      <view class="movie-row">
        <span class="content">{{item.title}}</span>
      </view>
      <view class="movie-row">
        <span  class="label">导演:  </span>
        <span class="label" wx:key="{{item.id}}"  wx:for="{{item.directors}}"  
             wx:for-item="director">
             <text class="cast-name">{{director.name}}</text>
        </span>
      </view>
       <view class="movie-row">
        <span  class="label">主演:  </span>
        <span class="label" wx:key="{{item.id}}"  wx:for="{{item.casts}}"   
             wx:for-item="cast">
             <text class="cast-name">{{cast.name}}</text>
        </span>
      </view>
    </view>
  </view>
</view>
样式wcss文件:

.box{
  display: flex;
  flex-direction:  column;
  justify-content: flex-start
}
.item{
  display: inline-flex;
  margin-bottom: 3rpx;
  background-color:  aliceblue;
  justify-content: flex-start;
  padding-top: 30rpx
}
.movie-info{
  flex:2;
  display: flex;
  flex-direction: column
}
.img{
  flex:1;
  height:210rpx;
   140rpx;
}
.cast{
  display: inline-flex;
  flex-direction:  row
}
.tapClass{
  background-color: blanchedalmond
}
.movie-row{
  display: inline-flex;
  flex-direction: row;
  flex-wrap: wrap
}
.label{
   font-size:28rpx;
  color: slategrey
}
.content{
   font-size: 36rpx
}
.cast-name{
  font-size: 28rpx;
  margin-right: 16rpx
}
js文件:

Page({
  /**
   * 页面的初始数据
   */
  data: {
      //页面显示的信息
      movies:{}
  },
  showInfo:function(e){
    //接收页面传递过来的参数:电影的ID
    let movieId=e.currentTarget.dataset.id;
    //跳转到页面详情页页面
    wx.navigateTo({
      url: '/pages/moviedetail/moviedetail?id='+movieId
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //将this存到that变量中,不然在success回调中使用this.setData()的话,此时的this指向已经改变
    let that=this;
    //加载时显示正在加载的loading动画(微信API自带的)
    wx.showLoading({
      title: '加载影片信息中...',
    })
    //发送请求,其中data是参数,header要指定,不然会有问题
    wx.request({
      url: "https://api.douban.com/v2/movie/in_theaters",
      data:{
        apikey:'0b2bdeda43b5688921839c8ecb20399b',
        city:'上海'
      },
      header: {
        "Content-Type": "json"
      },
      //请求成功的回调
      success: function (res) {
        //将相应数据赋给data里面的movies属性
        that.setData({movies:res.data});
        //关闭(隐藏)加载动画
        wx.hideLoading()
      }
    })
  },

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

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

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

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

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

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

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

3.开发电影详情页

同理在pages目录下新建一个moviedetail目录,在moviedetail目录中新建一个page。

页面wxml文件,注意这里scroll-view水平滚动图文信息的实现:

<!--pages/moviedetail/moviedetail.wxml-->
<view class="detail-container">
  <view class="img-container">
    <image mode="aspectFit" src="{{detail.images.large}}"/> 
  </view>
  <view class="info-container">
      <view class="info-row">
          <text>{{detail.title}}</text>
          <br/>
      </view>
      <view class="info-row">
          {{detail.genres}} | {{detail.durations[0]}}
      </view>
      <view class="info-row">
          {{detail.mainland_pubdate}} 在中国大陆上映
      </view>
    </view>
</view>
<view class="movie-intr">
    {{detail.summary}}
</view>
<view class="person-container">
  <view class="act-info">演员</view>
  <scroll-view scroll-x class="scroll-header" >
      <view class="act-img" wx:for="{{detail.casts}}"  wx:key="{{item.id}}">
      <view>
          <image mode="aspectFill" src="{{item.avatars.large}}">
          </image>
          <text class="actor-name">  
              {{item.name}}
          </text>
      </view>
      </view>
</scroll-view>
</view>
<view>
    <button class="btn-like" type="primary" bindtap="addToLikes" 
    data-id="{{detail.id}}">加入想看清单
    </button>
</view>
样式wcss文件:
/* pages/moviedetail/moviedetail.wxss */
.detail-container{
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  background-color: darkslategrey
}
.img-container{
  flex: 1;
}
.img-container image{
  320rpx;
  height: 220rpx
}
.info-container{
  flex: 2;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin: 20rpx 0 20rpx 0
}
.info-row{
  font-size: 24rpx;
  color: white
}
.movie-intr{
  background-color:  ghostwhite;
  font-size: 24rpx;
  padding: 40rpx;
  line-height: 40rpx
}
.scroll-header{
display: flex;
flex-direction: column;
white-space: nowrap;   
}
.scroll-header view{
border:none;
display: inline-block;  
}
.scroll-header image{
  200rpx;
  height: 300rpx;
  margin: 6rpx 6rpx 6rpx 6rpx
}
.act-info{
  font-size: 28rpx;
  margin-left: 10rpx
}
.act-img{
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-left: 10rpx
}
.actor-name{
  font-size: 26rpx
}
.btn-like{
  margin: 30rpx 40rpx 20rpx 40rpx
}
js文件中修改以下代码:

  /**
   * 页面的初始数据
   */
  data: {
    detail:{}
  },
  /**
   * 添加到想看清单
   */
  addToLikes:function(e){
    let movieId = e.currentTarget.dataset.id;
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //接收其他页面传递过来的参数
    let movieId=options.id,that=this;
    wx.showLoading({
      title: '加载影片信息中...',
    })
    wx.request({
      url: "http://api.douban.com/v2/movie/subject/" + movieId,
      data: {
        apikey: '0b2bdeda43b5688921839c8ecb20399b'
      },
      header: {
        "Content-Type": "json"
      },
      success: function (res) {
        that.setData({ detail : res.data});
        wx.hideLoading()
      }
    })
  },

4.我的主页

这里还没有编写任何的逻辑信息,本来是想加入一些常用的表单控件和一些其他的组件综合使用的,但是。。。我得去看白夜追凶了。下次更吧。

这里配置了navigationBar的文字显示,在pages/my/my.json中写入:

{
  "navigationBarTitleText": "我的主页"
}


以上,如有错误,欢迎指正,不胜感激。










原文地址:https://www.cnblogs.com/jerryyj/p/9621565.html