两天写一个电影资讯速览微信小程序(附源码)

31 篇文章 0 订阅
14 篇文章 0 订阅

简介

基于原生小程序精仿猫眼电影,数据API都是在网上抓取的,仅供学习和参考。

有人提供了一个城市列表接口可以获取城市ID:https://maoyan.com/ajax/cities

另外此小程序没有选座功能。选座功能需要页面的缩放、座位的生成、座位的选择、座位的推荐等等,没有实现。网上有很多例子可以参考

关注同名公众号【码农园区】,回复「电影」,获取项目源码

实现的功能

  • 页面滚动到底部加载更多
  • 电影详情页面、影院详情页面
  • 电影购票功能、小吃购买功能
  • 显示历史订单,可删除、可添加
  • 电影显示所有评论功能
  • 影院地图
  • 电影预告播放页面
  • 城市选择页面
  • 客服功能
  • 页面分享功能
  • 用户拒绝地理位置授权情况处理

项目目录结构

总共18个page、3个component、6个template

├── assets                               
│   ├── font                                 # 项目的icon文件
│   ├── images                               # 图片资源
│   └── libs                    	     # 三方支持库
├── components
│   ├── filter-nav                           # 筛选条件组件
│   ├── select-movie                         # 选择电影组件
│   └── select-time                          # 选择时间组件
├── pages
│   ├── subPages                             # 非tab页面
│   │   ├── about-page                       # “关于”页面
│   │   ├── buy-snack                        # “购票确认订单”页面
│   │   ├── buy-ticket                       # “小吃确认订单”页面
│   │   ├── cinema-detail                    # “影院详情”页面
│   │   ├── cinema-map                       # “影院地图”页面
│   │   ├── city-select                      # “选择城市”页面
│   │   ├── comment-page                     # “评论”页面
│   │   ├── movie-detail                     # “电影详情”页面
│   │   ├── movie-order                      # “电影订单”页面
│   │   ├── movie-order-detail               # “电影订单详情”页面
│   │   ├── search-page                      # “搜索”页面
│   │   ├── select-cinema                    # “选择影院”页面
│   │   ├── snack-order                      # “小吃订单”页面
│   │   ├── snack-page                       # “小吃详情”页面
│   │   └── video-page                       # “电影预告”页面
│   └── tabBar                               # tab页面
│       ├── cinema                           # “影院”页面
│       ├── movie                            # “电影”页面 
│       └── user                             # “我的”页面
├── templates
│   ├── cinemaMap                            # 影院地图section样式模板
│   ├── cinemaSection                        # 影院section样式模板
│   ├── commentSection                       # 评论section样式模板
│   ├── loadingMore                          # 加载更多功能样式模板
│   ├── movieSection                         # 电影section样式模板
│   └── nothing                              # 查询空值样式模板
├── utils                                    
│   └── util.js                              # 工具函数
├── app.js                                   # 小程序逻辑
├── app.json                                 # 小程序公共配置
├── app.wsxx                                 # 小程序公共样式表
└── project.config.json                      # 项目配置文件

首页效果图

image.png

数据请求

      url: 'https://m.maoyan.com/ajax/movieOnInfoList?token=',
      success(res) {
        const movieList0 = _this.formatImgUrl(res.data.movieList)
        wx.hideLoading()
        _this.setData({
          movieIds0: res.data.movieIds,
          movieList0
        })
        if (res.data.movieList.length >= res.data.movieIds.length) {
          _this.setData({
            loadComplete0: true
          })
        }
      }
    })

完整wxml

<import src='../../../templates/movieSection/movieSection.wxml' />

<view>
  <view class='topbar'>
    <navigator class='city-entry' url='../../subPages/city-select/city-select'>
      <text class='city-name'>{{city}}</text>
      <text class='city-entry-arrow'></text>
    </navigator>
    <view class='switch-hot'>
      <view class='hot-item {{switchItem===0 ? "active" :""}}' bindtap='selectItem' data-item='{{0}}'>正在热映</view>
      <view class='hot-item {{switchItem===1 ? "active" :""}}' bindtap='selectItem' data-item='{{1}}'>即将上映</view>
    </view>
    <navigator class='search-entry' url='../../subPages/search-page/search-page?stype=-1'>
      <text class='iconfont icon-sousuo'></text>
    </navigator>
  </view>
  <view class='switch-content'>
    <view hidden="{{switchItem===1}}">
      <template is='movieSection' wx:for='{{movieList0}}' wx:for-item='movie' wx:key='{{movie.id}}' data='{{movie:movie}}'/>
      <view wx:if='{{!loadComplete0 && movieList0.length}}'>
        <template is="loadingMore" />
      </view>
    </view>
    <view hidden="{{switchItem===0}}">
      <view class='most-expected' wx:if='{{mostExpectedList.length}}'>
        <view class='title'>近期最受期待</view>
        <scroll-view class='scroll-view_H' scroll-x bindscrolltolower='lower'>
          <navigator url='/pages/subPages/movie-detail/movie-detail?movieId={{movie.id}}' wx:for='{{mostExpectedList}}' wx:for-item='movie' wx:key='{{id}}' class='expected-item'>
            <image src='{{movie.img}}' class='poster'></image>
            <view class='name line-ellipsis'>{{movie.nm}}</view>
            <view class='data line-ellipsis'>{{movie.wish}}人想看</view>
            <view class='data'>{{movie.comingTitle}}</view>
          </navigator>
        </scroll-view>
      </view>
      <block wx:for='{{movieList1}}' wx:for-item='movie' wx:key='{{movie.id}}'>
        <block wx:if='{{index===0||movieList1[index-1].comingTitle!==movie.comingTitle}}'>
          <view class='title'>{{movie.comingTitle}}</view>
          <template is='movieSection' data='{{movie:movie,rt:true}}' />
        </block>
        <template wx:else is='movieSection' data='{{movie:movie,rt:true}}' />
      </block>
      <view wx:if='{{!loadComplete1 && movieList1.length}}'>
        <template is="loadingMore" />
      </view>
    </view>
  </view>
</view>

附近影院效果图

image.png

可根据商圈或者地铁站进行直接查询附件影院,效果图如下

image.png

可根据影院名进行直接查询附件影院,效果图如下

image.png

还可根据其他具体需求进行直接查询附件影院,效果图如下

image.png

获取影院列表

    const _this = this;
    return new Promise((resolve, reject) => {
      wx.request({
        url: 'https://m.maoyan.com/ajax/cinemaList',
        data: params,
        success(res) {
          resolve(res.data.cinemas)
          _this.setData({
            cinemas: _this.data.cinemas.concat(res.data.cinemas),
            loadComplete: !res.data.paging.hasMore
          })
        }
      })
    })
  },

当过滤条件变化时调用的函数

    const obj = e.detail
    wx.showLoading({
      title: '正在加载...'
    })
    this.setData({
      params: { ...this.data.params,
        ...obj
      },
      cinemas: [],
      nothing: false
    }, () => {
      this.getCinemas(this.data.params).then((list) => {
        if (!list.length) {
          this.setData({
            nothing: true
          })
        }
        wx.hideLoading()
      })
    })
  },

导航下拉框状态变化时的处理

    const item = e.detail.item
    this.setData({
      isShow: item !== -1
    })
  },

完整wxml

<import src='../../../templates/loadingMore/loadingMore.wxml' />
<import src='../../../templates/cinemaSection/cinemaSection.wxml' />

<view class='container' style='position:{{isShow?"fixed":""}}'>
  <view class='topbar'>
    <navigator class='city-entry' url='../../subPages/city-select/city-select'>
      <text class='city-name'>{{city}}</text>
      <text class='city-entry-arrow'></text>
    </navigator>
    <navigator url='../../subPages/search-page/search-page?stype=2' class='search-input'>
      <text class='iconfont icon-sousuo'></text>搜影院</navigator>
  </view>
  <view class='nav-wrapper'>
    <filter-nav city-cinema-info='{{cityCinemaInfo}}' bindchange='changeCondition' bindtoggleShow='toggleShow'></filter-nav>
  </view>
  <view class='cinema-list'>
   <template is="cinemaSection" wx:for='{{cinemas}}' wx:for-item='cinema' wx:key='{{cinema.id}}' data='{{cinema}}'/>
  </view>
  <view wx:if='{{!loadComplete && cinemas.length}}'>
    <template is="loadingMore" />
  </view>
  <view hidden='{{!nothing}}'>
    <template is='nothing' data='{{message:"暂无符合条件的影院"}}' />
  </view>
</view>

我的效果图

image.png

关于信息效果图

image.png

其他

其他代码细节,不再赘述,具体可查看源码。

关注同名公众号【码农园区】,回复「电影」,获取项目源码

问题

  • 数据全部是线上抓取的,由于没有获得猫眼城市ID的API,所有数据接口没有添加城市ID参数,仅靠IP定位,所以数据可能不准确。猫眼电影的票价经过加密了,返回的数据为&#xe4d9;&#xf2dc;其实这就是电影的票价,不过猫眼通过动态生成@font-face来将数据还原成正常的数字。小程序有wx.loadFontFace来动态添加字体,但是需要字体链接,而猫眼电影只给了字体文件名,缺少具体的链接
  • 城市选择页面需的一些事件进行了事件优化
  • 滚动穿透问题,并自己编写了watch功能,监听遮罩的状态
  • 对于tabBar的页面onLoad生命周期只会触发一次,切换tab或从非tab进入都不会触发onLoad。只有第一次进入tab页面时才会触发。对于非tabBar页面来说,每次进入页面都会触发onLoad生命周期,每次都可以在此拿到路由参数。
  • 关于template和component的使用。复用样式用template,复用功能用component,外部样式不能作用到组件中,需要externalClasses设置(我设置了也不管用,就在组件中又写了一遍样式)

做的过程中遇到了很多问题,并没有一一记录。总之只用自己写一遍才能更好的发现、理解和解决问题

运行本项目

  1. 克隆项目到本地后用微信开发者工具打开
  2. 关闭安全域名的校验(设置 --> 项目设置 --> 不校验合法域名)

其他代码细节,不再赘述,具体可查看源码。

在这里插入图片描述

▲关注 同名 公众号【码农园区】▲
▲回复「电影」,获取项目源码▲

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦之归途

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值