首页 > 课堂 > 小程序 > 正文

taro开发微信小程序的实践

2020-03-21 15:55:52
字体:
来源:转载
供稿:网友

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

开发环境

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

运行效果

 

目录分析

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表