image 微信小程序flex_微信小程序版豆瓣电影

f6b1d9fffac18a3ffeba8482a6011b34.png

最近,工作没有那么忙,终于有时间学习微信小程序的开发了。学习的过程还是比较顺利的,入门相对简单,即便没有多少前端开发经验的人也能很快上手。

现在微信小程序的资料还比较少,查看官方文档是很好的方式。微信小程序的官方文档还是很容易阅读的,并没有什么阅读障碍。在一个悠闲的午后,泡一杯清茶,开始了我的小程序之旅。花了一下午的时间把官方文档刷了一遍。接着,下载官方提供的 Demo,在微信开发者工具运行,查看每个组件的效果,使用方式,调试着看界面布局,学习API接口,顺便将弹性盒子模式复习了下。

在项目中学习才是最有效的学习方式。于是,我开始思考要做些什么项目。小程序适合开发低频使用,用完即走,业务不能太复杂的应用。工具类的应用首先被考虑,其次希望能把关注点放在微信小程序的开发,最好能有现成的后台接口。确认了方向之后,最终决定仿豆瓣电影的功能,开发一款微信小程序版的豆瓣电影。

准备工作:

数据来源:豆瓣电影API:https://developers.douban.com/wiki/?title=movie_v2

开发工具:微信开发者工具 0.14.140900

功能:

  • 电影榜单列表
  • 电影搜索
  • 电影条目信息
  • 影人条目信息

预览:

e8fdbf15375fa214e643e0eb7a6c3389.gif

电影首页:显示“影院热映”,“即将上映”以及“精选榜单”,测试之后发现精选榜单只有Top250的 API 接口能正常使用,于是,豆瓣Top250、口碑榜、新片榜、票房榜使用同一个 API 接口,只是请求的数据参数不一样。由于微信小程序的 request 的最大并发数是 5,所以用户进入程序时只加载“影院热映”、“即将上映”的数据,界面滑动之后再加载榜单数据。

  /** 滑动屏幕 */
  handleTouchMove: function (event) {
    var offsetTop = event.target.offsetTop;
    console.log("handleTouchMove offsetTop: " + offsetTop);
    if (offsetTop > 10 && !this.data.acquiredSelected) {
      this.getSelectedListData();
    }
  },

“更多”右侧的箭头这里并没有使用图标,而是使用样式来实现的。微信小程序对 app 的体积有限制,超过1M就不能上传。其实,不只是微信小程序,网页也一样。能用样式实现的就不用字体图标;能用字体图标实现的就不用 sprite 图;能用 sprite 图实现的就不用单一图标。样式 > 字体图标 > sprite 图 > 单一图标,不能说是绝对,但基本原则是这样。这样做的目的也是为了减少 app 的体积,减少 HTTP 的请求次数,减轻服务器的压力。

显示更多组件

<text class="session-header-more" bindtap="bindMore" data-type-id="intheaters">更多</text>

显示更多样式

.session-header-more {
  font-size: 28rpx;
  color: #32cd32;
  font-weight: 500;
  position: relative;
  padding-right: 20rpx;}.session-header-more::after {
  content: " ";
  display: inline-block;
  position: absolute;
  top: 50%;
  width: 12rpx;
  height: 12rpx;
  transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
  margin-top: -8rpx;
  border-width: 2rpx 2rpx 0px 0px;
  border-color: #32cd32;
  border-style: solid;}

微信小程序提供了模板功能,可以在模板中定义代码片段,在不同的地方调用。模板可以减少重复性代码,使代码结构更加清晰,增强代码的可读性,也方便以后维护代码。模板粒度的划分可以根据页面的复杂度跟组件被重用的频率。模板可以组合嵌套使用,大的功能组件可以利用模板划分成更小的功能组件。在电影首页中,“影院热映”,“即将上映”展示的是电影信息列表,可以将电影海报,电影名字,评分,想看人数作为一个大的“组件”抽象出来形成电影信息块模板组件。评分在首页电影,更多列表中多次被使用,可以抽象出评分模板组件。

评分模板

<!--pages/movie/movie-rating/movie-rating-template.wxml--><template name="rating-template">
  <view class="rating">
    <view class="rating-star allstar{{rating.average | 0}}"></view>
    <text class="rating-average">{{rating.average}}</text>
  </view></template>

电影信息块模板

<!--pages/movie/movie-grid/movie-grid-template.wxml--><import src="/pages/movie/movie-rating/movie-rating-template.wxml" /><template name="movie-grid-template">
  <view class="movie-wrapper" bindtap="bindMovieDetail" data-id="{{id}}">
    <view class="movie-content">
      <image class="poster" src="{{images.medium}}"></image>
      <text class="name">{{title}}</text>
      <template is="rating-template" data="{{rating}}" />
      <text class="wish-count">{{collect_count}}人想看</text>
    </view>
  </view></template>

评分用星星表示不同的分数,10分用5星表示,1分显示半星。这里使用 sprite 图,可以减少图片的数量。在组件样式中指定图片位置的偏移量,用于显示不同的图标。

ffdc2742da25b3fed3406a45a6d288c7.png

评分样式

.rating {
  display: flex;
  flex-direction: row;
  position: relative;
  margin-top: 10rpx;
  margin-bottom: 10rpx;}.rating-star {
  content: "";
  display: inline-block;
  width: 55px;
  height: 11px;
  position: absolute;
  background-repeat: no-repeat;
  background-image: url(/images/icon/ic_rating_s.png);}.allstar10 {
  background-position: 0px 0px;}.allstar9 {
  background-position: 0px -11px;}.allstar8 {
  background-position: 0px -22rpx;}.allstar7 {
  background-position: 0px -33px;}.allstar6 {
  background-position: 0px -44px;}.allstar5 {
  background-position: 0px -55px;}.allstar4 {
  background-position: 0px -66px;}.allstar3 {
  background-position: 0px -77px;}.allstar2 {
  background-position: 0px -88px;}.allstar1 {
  background-position: 0px -99px;}.allstar0 {
  background-position: 0px -110px;}.rating-average {
  margin-left: 120rpx;
  font-size: 20rpx;
  line-height: 22rpx;
  color: #878787;
  height: 22rpx;}

440a2213b8519193698003c1b1dd2f43.gif

电影列表:显示更多电影列表。这里使用标签页切换“正在热映”、“即将上映”。使用 wx:if 控制组件的显示与隐藏,电影列表可以抽象出电影信息模板。

<!--pages/movie/movie-list/movie-list.wxml--><import src="/pages/movie/movie-rating/movie-rating-template.wxml" /><template name="movie-list-template">
  <view class="movie-wrapper" bindtap="bindMovieDetail" data-id="{{id}}">
    <view class="movie-content">
      <image class="poster" src="{{images.medium}}"></image>
      <view class="movie-summary">
        <text class="name">{{title}}</text>
        <text class="directors">导演:{{directors}}</text>
        <text class="casts">主演:{{casts}}</text>
        <text class="genres">类型:{{genres}}</text>
        <template is="rating-template" data="{{rating}}" />
        <text class="wish-count" style="color:#9bdff9;">{{collectCount}}人想看</text>
      </view>
      <block wx:if="{{typeId == 'comingsoon'}}">
        <text class="wish-btn" style="color:#de9703;border-color:#de9703" catchtap="handleWishtap">想看</text>
      </block>
      <block wx:if="{{typeId == 'intheaters'}}">
        <text class="ticket-btn" style="color:#9bdff9;border-color:#9bdff9" catchtap="handleTickettap">购票</text>
      </block>
    </view>
  </view></template>

0bc9c1c7d34168e1c1367a3690a8c54b.gif

精选榜单:显示电影榜单列表。这里要说的是列表序号。列表序号左右两边有横线,这里也是使用样式实现。前三个序号显示的颜色不一样。

列表序号组件

<text class="selected-index">{{index + 1}}</text>

列表序号样式

.selected-index::before {
  content: "";
  width: 80rpx;
  border-bottom: 2rpx solid #e9e9e9;
  box-sizing: border-box;
  display: inline-block;
  margin-right: 15rpx;
  margin-bottom: 10rpx;}.selected-index::after {
  content: "";
  width: 80rpx;
  border-bottom: 2rpx solid #e9e9e9;
  box-sizing: border-box;
  display: inline-block;
  margin-left: 15rpx;
  margin-bottom: 10rpx;}.selected-wrapper:first-child .selected-index {
  color: #e14c63;}.selected-wrapper:nth-child(2) .selected-index {
  color: #fca167;}.selected-wrapper:nth-child(3) .selected-index {
  color: #f5c564;}

1e2a93070488d1889c53dcf3b0c498dd.gif

电影搜索:电影搜索没有太多要讲的。点击搜索区块跳到搜索界面,获取 input 的输入值,后台请求电影信息。当输入框有值时,显示 x,点击 x 之后可以清空输入框内容。

<icon class="search-icon" type="search" size="16"></icon><input class="search-content" placeholder-class="search-placeholder" bindinput="bindSearchInput" placeholder="搜索电影" value="{{searchValue}}" /><block wx:if="{{showDelete}}">
  <text class="search-delete" bindtap="bindSearchDelete">x</text></block><text class="search-cancel" bindtap="bindSearchCancel">取消</text>

使用bindinput获取输入框的值

/** 搜索影视 */bindSearchInput: function (event) {
  var value = event.detail.value;
  var readyData = { showDelete: false };
  if (value.length > 0) {
    readyData = { showDelete: true };
    this.handleSearchData(value);
  }
  this.setData(readyData);},/**清空输入框 */bindSearchDelete: function (event) {
  var readyData = { searchValue: "", showDelete: false, result: {} };
  this.setData(readyData);},

990ab22ea6d8dfbb2f37140034b4a3ae.gif

影片详情:可以查看影片信息,影人信息,给电影评分,但是评分 API 接口不支持,评分数据不能上传到服务器。影人信息的描述信息无法获取。这里要说一下评分,刚开始的想法是通过 sprite 图,手指在星星上滑动时可以显示不同的评分,但是,微信小程序是基于数据驱动的模式,没有 window、document 对象,不能使用 JavaScript 操作 DOM,无法获取组件的坐标值,这样就无法确定手指的坐标是在哪个星星上。于是,只好显示五个星星图标,通过获取 tap 事件来实现评分功能。评分描述则通过样式控制透明度实现显示与隐藏。

事件处理

  bindMark: function (event) {
    var id = event.target.dataset.id;
    this.setData({ "mark": id });
  },

<view class="rating">
  <view class="rating-desc">
    <text class="desc-text {{mark == 1 ? 'desc-text-show' : ''}}">很差</text>
    <text class="desc-text {{mark == 2 ? 'desc-text-show' : ''}}">较差</text>
    <text class="desc-text {{mark == 3 ? 'desc-text-show' : ''}}">还行</text>
    <text class="desc-text {{mark == 4 ? 'desc-text-show' : ''}}">推荐</text>
    <text class="desc-text {{mark == 5 ? 'desc-text-show' : ''}}">力荐</text>
  </view>
  <view class="rating-stars-wrapper" bindtap="bindMark">
    <block wx:for="{{[1,2,3,4,5]}}" wx:for-item="id">
      <image class="{{mark >= id ? 'star-HL' : 'star'}}" src="#" data-id="{{id}}"></image>
    </block>
  </view>
  <!-- Don't use sprite, can't give a mark -->

  <!--<image class="rating-star" bindtap="handleRating" src="#"></image>--></view>

评分组件样式

.desc-text {
  width: 32px;
  height: 22px;
  font-size: 15px;
  line-height: 22px;
  text-align: center;
  color: #9e9e9e;
  opacity: 0;}.desc-text-show {
  opacity: 1;}.star {
  width: 32px;
  height: 32px;
  background: url("/images/icon/ic_rating_star.png") no-repeat;}.star-HL {
  width: 32px;
  height: 32px;
  background: url("/images/icon/ic_rating_star_HL.png") no-repeat;}

这个项目还是比较简单的,前后花了5天的时间就完成了。所使用的接口是豆瓣电影的公开接口,限定40次请求/分钟。对于学习来说已经足够了。如果运行时出现400的错误,是请求过于频繁,稍等一会就好了。

最后,附上项目的Github地址:https://github.com/bruintong/wechat-webapp-douban-movie


作者:bruintong
来源:慕课网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值