taro开发微信小程序的实践


Posted in Javascript onMay 21, 2019

在京东凹凸实验室开发Taro跨平台早期之前,就已经进行Taro尝鲜了。开发这个实例 猫眼电影 已经过去几个月了。案例部分使用的是猫眼电影真实线上接口,关于订座的座位数据是自己模拟实现的,案例只供参考学习。

开发环境

操作系统:Window 10
Taro版本:v0.0.69
Node版本:v8.11.1
github地址: https://github.com/Harhao/miniProgram

运行效果

taro开发微信小程序的实践 

目录分析

src 是主要的开发目录,各个文件实现功能如下所示:

├─.idea
│ └─libraries
├─.temp
├─config
└─src
 ├─assets
 │ └─images
 ├─components (公用组件)
 │ ├─Brandbar
 │ ├─Selectbar
 │ ├─Specialbar
 │ └─Toptab(电影详情分类)
 └─pages
 | ├─cinema(影院列表)
 | ├─cinemaDetail(影院详情页)
 | ├─content(电影介绍)
 | ├─detail(电影详情页)
 | ├─map(影院地图定位页)
 | ├─movies(电影列表页)
 | ├─order(电影票订单页)
 | ├─person(用户登录页)
 | ├─position(地理位置选择页)
 | ├─search(电影/影院搜索页)
 | ├─seat(影院座位页)
 | └─user(用户中心)
 |__app.js(入口配置文件)
 |__app.scss
 |__index.html

入口配置文件 app.js 分析

Movies 列表页是微信小程序的首页,下面代码中config配置的是小程序中所有使用的页面定义路由。下面重点介绍几个比较重要的关键点微信小程序页。

import Taro, { Component } from "@tarojs/taro";
import Movies from "./pages/movies/movies";
import "./app.scss";
class App extends Component {
 config = {
 //访问路由文件定义
 pages: [
  "pages/movies/movies",
  "pages/person/person",
  "pages/cinema/cinema",
  "pages/position/position",
  "pages/search/search",
  "pages/detail/detail",
  "pages/content/content",
  "pages/cinemaDetail/cinemaDetail",
  "pages/map/map",
  "pages/seat/seat",
  "pages/user/user",
  "pages/order/order"
 ],
 //小程序顶部设置
 window: {
  backgroundTextStyle: "light",
  navigationBarBackgroundColor: "#e54847",
  navigationBarTitleText: "猫眼电影",
  navigationBarTextStyle: "white",
  enablePullDownRefresh: true
 },
 //底部tab导航栏配置
 tabBar: {
  color: "#333",
  selectedColor: "#f03d37",
  backgroundColor: "#fff",
  borderStyle: "black",
  list: [
  {
   pagePath: "pages/movies/movies",
   text: "电影",
   iconPath: "./assets/images/index.png",
   selectedIconPath: "./assets/images/index_focus.png"
  },
  {
   pagePath: "pages/cinema/cinema",
   text: "影院",
   iconPath: "./assets/images/themeOld.png",
   selectedIconPath: "./assets/images/theme.png"
  },
  {
   pagePath: "pages/person/person",
   text: "我的",
   iconPath: "./assets/images/person.png",
   selectedIconPath: "./assets/images/personSelect.png"
  }
  ]
 }
 };
 render() {
 // Movies小程序入口文件
 return <Movies />;
 }
}

Taro.render(<App />, document.getElementById("app"));

Movies 电影列表页

getCities() 是获取当前定位的城市的路由,因为在猫眼电影小程序抓包中没有抓取到获取当前定位的地址接口,所以在猫眼电影H5端获取到了所有城市的数据。之前用了 easyMock 模拟数据接口,现在不能使用了。不过现在在微信小程序的云开发,可以把数据模拟上去。其中TopTab是正在热映和即将上映的两个分类总的组件。

// movies页
export default class Movies extends Component {
 config = {
 navigationBarTitleText: "猫眼电影"
 };
 constructor(props) {
 super(props);
 }
 componentDidMount() {
 this.getCities();
 }
 getCities() {
 Taro.request({
  url:
  "https://www.easy-mock.com/mock/5ba0a7f92e49497b37162e32/example_copy/cities_copy_1541385673090",
  method: "GET",
  header: {
  Accept: "application/json, */*",
  "Content-Type": "application/json"
  }
 }).then(res => {
  if (res.statusCode == 200) {
  let data = res.data.data.data.data;
  Taro.setStorageSync("cities", data);
  }
 });
 }
 render() {
 return (
  <View className="movies">
  <Toptab />
  </View>
 );
 }
}

Toptab分类页

其中即将上映和正在热映,做了一个tab组件主要重点的代码是:

<View className="tabItemContent" hidden={this.state.currentNavtab === 0?false:true}>
 <!-- 正在热映情况-->
 </View>
 <View className="tabItemContent" hidden={this.state.currentNavtab === 1?false:true}>
 <!--即将上映情况-->
 </View>

其中 currentNavTab 控制即将上映和正在热映的 section 显隐, hidden 是taro官方案例提供的推荐实现tab标签组件的方式。使用其他方法亦可。该页主要实现电影列表的影评价和推荐指数,价格等。微信小程序中基本所有接口都依赖于 cityId ,也就是在 movies 页获取定位地址。下面 getMoviesOnList 是获取真实线上猫眼电影的接口,需要伪造请求 header

getMoviesOnList(){
 let cityId = this.state.id
 Taro.showLoading({
  title:"加载中"
 });
 Taro.request({
  url:"https://m.maoyan.com/ajax/movieOnInfoList?token=",
  method:"GET",
  header:{
  "Cookie":`_lxsdk_cuid=164b6cae2cac8-02b7b032f571b5-39614706-1fa400-164b6cae2cbc8; v=3; iuuid=1A6E888B4A4B29B16FBA1299108DBE9CA19FF6972813B39CA13A8D9705187374; revrev=76338a29; _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; webp=true; __mta=3463951.1532075108184.1533098338076.1533118040602.20; _lxsdk=1A6E888B4A4B29B16FBA1299108DBE9CA19FF6972813B39CA13A8D9705187374; from=canary; selectci=true; __mta=3463951.1532075108184.1533118040602.1533118773295.21; _lxsdk_s=164f4f4c9e9-45e-d1b-46%7C%7C50; ci=${cityId}`
  }
 }).then(res=>{
  if(res.statusCode == 200){
  Taro.hideLoading();
  res.data.movieList.forEach((value)=>{
   let arr = value["img"].split("w.h");
   value["img"] = arr[0]+"128.180"+ arr[1]
  });
  this.setState({
   onList:res.data.movieList,
   startIndex:res.data.movieList.length,
   lastIndex:res.data.total -1,
   movieIds:res.data.movieIds
  });
  }else{
  this.setState({
   onList:null,
   movieIds:null
  })
  }
 })
 }

seat (影院座位页)

自己模拟实现了一个推荐座位与选座功能。为了实现座位信息选择,使用了二维数组对座位信息已选和未选,其中0代表该处拥有座位、E代表该处为空。其中数组的行代表了影院的第几排,嵌套的数组的索引代表了第几列。

[
 [0,0,0,0,0,0],
 [E,0,0,E,0,0],
 [0,0,0,0,0,0],
 [E,0,0,E,0,0]
]

初始化座位信息, https://m.maoyan.com/ajax/seatingPlan?timestamp=${Date.now()} 获取猫眼电影线上座位信息接口, cityId 是当前定位城市ID, ci 是影院ID。 initParams 是获取线上座位信息接口, seatData 是获取到的影院座位信息,需要对座位信息做进一步的加工。遍历座位信息,如果字段 st 为N,则arr设置为0(代表具有座位并未选),为E则为该处不具有座位。

initParams(){
 const params = this.$router.params;
 const self = this;
 Taro.setNavigationBarTitle({
  title:params.cinemaName
 })
 Taro.showLoading({
  title:"加载中..."
 });
 Taro.request({
  url:`https://m.maoyan.com/ajax/seatingPlan?timestamp=${Date.now()}`,
  method:'post',
  header:{
  'Cookie': 'uuid_n_v=v1; iuuid=26F6BA50506A11E9A973FDD3C7EBDF0E29C7297EC72D4F77A53F9445EF0EE9F3; webp=true; ci=20%2C%E5%B9%BF%E5%B7%9E; _lxsdk_cuid=169be42cf28c8-098c7e821e63bd-2d604637-3d10d-169be42cf29c8; _lxsdk=26F6BA50506A11E9A973FDD3C7EBDF0E29C7297EC72D4F77A53F9445EF0EE9F3; from=canary; uid=124265875; token=9P1-5VoykD_qrpBxpTvSoVhMwzQAAAAAJwgAAE2za6eVZdI-oORrTHb8dP4JEMYCiza0zSSNoRkHx4qajm2Nu6ClhU00u5A1avIySg; __mta=250960825.1553675243337.1553675275840.1553675275842.6; user=124265875%2C9P1-5VoykD_qrpBxpTvSoVhMwzQAAAAAJwgAAE2za6eVZdI-oORrTHb8dP4JEMYCiza0zSSNoRkHx4qajm2Nu6ClhU00u5A1avIySg; _lxsdk_s=169be42cf2b-ca7-4ca-570%7C%7C14'
  },
  data:{
  cityId:params.cityId,
  ci:params.ci,
  seqNo:params.seqNo
  }
 }).then(res=>{
  if(res.statusCode ==200){
  Taro.hideLoading();
  const seatData = res.data.seatData;
  const seatArray = [];
  seatData.seat.sections[0].seats.map(item=>{
   let arr = [];
   item["columns"].map(seat=>{
   if(seat["st"] == "N"){
    arr.push('0');
   }else{
    arr.push('E')
   }
   })
   seatArray.push(arr);
  })
  self.setState({
   seatData:seatData,
   seatArray:seatArray
  });
  }
 })
 }

做了影院座位信息是否为空筛选之后,接下来就是选座功能。其中影院座位的选择与取消使用了 buySeat 进行保存。 selectSeat 函数是选择座位, row :代表选择第几行, column 代表第几列, item 是该座位是否被选的信息(0为未选表示可选择、2为已选表示不可再选)

selectSeat(row,column,item){
 const self = this;
 const arr = this.state.seatArray;
 // item代表该座位是否可选
 if(item == 0){
  if(self.state.buySeat.length ==4){
  Taro.showToast({
   title: '最多选择4个座位',
   duration: 2000
  })
  return false;
  }else{
  let buySeat = self.state.buySeat;
  arr[row][column]= '2';
  buySeat.push({
   "row":row,
   "column":column
  });
  self.setState({
   buySeat:buySeat,
   seatArray:arr
  })
  }
 }else{
  arr[row][column]= '0';
  const buySeat = this.state.buySeat;
  let tmpArr = this.state.buySeat;
  buySeat.map((value,index)=>{
  if(value["row"]== row && value["column"]== column){
   tmpArr.splice(index,1);
   self.setState({
   buySeat:tmpArr,
   seatArray:arr
   })
  }
  })
 }
 }

推荐座位功能实现, getRecomment 是推荐位实现,现在至于1人、2人、3人、4人推荐。情侣位实现没有抓取到猫眼的推荐接口信息。

selectAll(seats){
 const self = this;
 seats.map(item=>{
  let row = parseInt(item.rowId.split('0')[0]);
  let column = parseInt(item.columnId.split('0')[0]);
  let itemIndex = self.state.seatArray[row][column];
  self.selectSeat(row,column,itemIndex);
 })

 }
 getRecomment(recomment,num){
 switch(num){
  case 1:this.selectAll(recomment.bestOne.seats);break;
  case 2:this.selectAll(recomment.bestTwo.seats);break;
  case 3:this.selectAll(recomment.bestThree.seats);break;
  case 4:this.selectAll(recomment.bestFour.seats);break;
 }
 }

content电影详情页

电影详情是一部电影简略介绍。主要实现了,电影主要简略描述和预告片的播放关闭,实现比较简单。 getDetailData 是获取电影详情数据接口。其中获取到img路径直接获取不到图片数据,需要对路径进行改写,如下代码所示:

getDetailData(){
 Taro.showLoading({
  title:"加载中"
 });
 Taro.request({
  url:`https://m.maoyan.com/ajax/detailmovie?movieId=${this.state.params.id}`
 }).then(res=>{
  if(res.statusCode == 200){
  Taro.hideLoading();
  let data = res.data.detailMovie;
  let arr = data["img"].split("w.h");
  data["img"] = arr[0]+"128.180"+ arr[1];
  for(let index in data.photos){
   let photo = data.photos[index];
   let arr = photo.split('w.h');
   data.photos[index] = arr[0]+'180.140'+arr[1];
  }
  this.setState({
   detailMovie:data
  });
  }
 }).catch(err=>{
  console.log(err.message);
 })
 }

在今天这个充满恋爱酸臭味日子,满怀期待地水完这篇短文。如果觉得喜欢的话,可不可以给我new个对象。说错了,应该是new个star~。

github地址: https://github.com/Harhao/miniProgram

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
ArrayList类(增强版)
Apr 04 Javascript
javascript获取作用在元素上面的样式属性代码
Sep 20 Javascript
jQuery的控件及事件(输入控件及回车事件)使用示例
Jul 25 Javascript
jquery实现仿Flash的横向滑动菜单效果代码
Sep 17 Javascript
Bootstrap每天必学之按钮(Button)插件
Apr 25 Javascript
javascript遍历json对象的key和任意js对象属性实例
Mar 09 Javascript
前端自动化开发之Node.js的环境搭建教程
Apr 01 Javascript
vue template中slot-scope/scope的使用方法
Sep 06 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
Apr 26 Javascript
Vue使用localStorage存储数据的方法
May 27 Javascript
在微信小程序中使用vant的方法
Jun 07 Javascript
微信用户访问小程序的登录过程详解
Sep 20 Javascript
element-ui表格合并span-method的实现方法
May 21 #Javascript
详解关于表格合并span-method方法的补充(表格数据由后台动态返回)
May 21 #Javascript
浅谈React Native 传参的几种方式(小结)
May 21 #Javascript
JavaScript函数式编程(Functional Programming)声明式与命令式实例分析
May 21 #Javascript
JS判断数组里是否有重复元素的方法小结
May 21 #Javascript
JS计算两个数组的交集、差集、并集、补集(多种实现方式)
May 21 #Javascript
vue路由守卫+登录态管理实例分析
May 21 #Javascript
You might like
php抓取页面的几种方法详解
2013/06/17 PHP
利用php+mcDropdown实现文件路径可在下拉框选择
2013/08/07 PHP
PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例
2017/08/10 PHP
WHOOPS PHP调试库的使用
2017/09/29 PHP
基于jquery的表格排序
2010/09/11 Javascript
jtable列中自定义button示例代码
2013/11/21 Javascript
子页向父页传值示例
2013/11/27 Javascript
node.js实现多图片上传实例
2014/06/03 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
浅谈vue.js中v-for循环渲染
2017/07/26 Javascript
Mongoose实现虚拟字段查询的方法详解
2017/08/15 Javascript
关于Vue在ie10下空白页的debug小结
2018/05/02 Javascript
bootstrap table实现横向合并与纵向合并
2019/07/18 Javascript
vue实现多级菜单效果
2019/10/19 Javascript
初学vue出现空格警告的原因及其解决方案
2019/10/31 Javascript
python获取图片颜色信息的方法
2015/03/18 Python
python使用pil生成图片验证码的方法
2015/05/08 Python
Python数据类型详解(四)字典:dict
2016/05/12 Python
Python之re操作方法(详解)
2017/06/14 Python
对python tkinter窗口弹出置顶的方法详解
2019/06/14 Python
python 输入字符串生成所有有效的IP地址(LeetCode 93号题)
2020/10/15 Python
Skyscanner英国:苏格兰的全球三大领先航班搜索服务之一
2017/11/09 全球购物
加拿大城市本地限时优惠:Buytopia.ca
2018/09/19 全球购物
英语专业学生个人求职信
2014/01/28 职场文书
文员岗位职责范本
2014/03/08 职场文书
面试自我介绍演讲稿
2014/04/29 职场文书
党员民主生活会材料
2014/12/15 职场文书
前台文员岗位职责
2015/02/04 职场文书
2015年简历自我评价范文
2015/03/11 职场文书
小平您好观后感
2015/06/09 职场文书
2019年最新借条范本!
2019/07/08 职场文书
大学校园餐饮创业计划书
2019/08/07 职场文书
Python实现简单的猜单词
2021/06/15 Python
MongoDB安装使用并实现Python操作数据库
2021/06/28 MongoDB
使用Springboot实现健身房管理系统
2021/07/01 Java/Android
解决Laravel使用验证时跳转到首页的问题
2021/11/17 PHP