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 相关文章推荐
JS模拟面向对象全解(二、类型与赋值)
Jul 13 Javascript
浅析ES6的八进制与二进制整数字面量
Aug 30 Javascript
微信小程序 教程之wxapp 视图容器 view
Oct 19 Javascript
JavaScript制作弹出层效果
Dec 02 Javascript
js仿QQ邮箱收件人选择与搜索功能
Feb 10 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
Aug 22 Javascript
浅谈如何使用 webpack 优化资源
Oct 20 Javascript
Vue 创建组件的两种方法小结(必看)
Feb 23 Javascript
electron + vue项目实现打印小票功能及实现代码
Nov 25 Javascript
详解js加减乘除精确计算
Mar 19 Javascript
Vue 2.0双向绑定原理的实现方法
Oct 23 Javascript
从原生JavaScript到React深入理解
Jul 23 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读取本地json文件的实例
2018/03/07 PHP
Laravel框架实现文件上传的方法分析
2019/09/29 PHP
Javascript 表单之间的数据传递代码
2008/12/04 Javascript
javascript 控制input只允许输入的各种指定内容
2014/06/19 Javascript
jquery实现的鼠标下拉滚动置顶效果
2014/07/24 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
jquery带动画效果幻灯片特效代码
2015/08/27 Javascript
jquery实现左右滑动菜单效果代码
2015/08/27 Javascript
JS返回只包含数字类型的数组实例分析
2016/12/16 Javascript
Vue组件库发布到npm详解
2018/02/17 Javascript
微信小程序—setTimeOut定时器的问题及解决
2019/07/26 Javascript
JS求解两数之和算法详解
2020/04/28 Javascript
5个你不知道的JavaScript字符串处理库(小结)
2020/06/01 Javascript
[01:32]dota2拉比克至宝(222)
2018/12/20 DOTA
[00:05]ChinaJoy现场 DOTA2玩家高呼“CN DOTA BEST DOTA”
2019/08/04 DOTA
使用基于Python的Tornado框架的HTTP客户端的教程
2015/04/24 Python
Python中的sort()方法使用基础教程
2017/01/08 Python
python实现感知器
2017/12/19 Python
python+mysql实现个人论文管理系统
2019/10/25 Python
python中图像通道分离与合并实例
2020/01/17 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
Docker如何部署Python项目的实现详解
2020/10/26 Python
详解如何使用rem或viewport进行移动端适配
2020/08/14 HTML / CSS
白兰氏健康Mall:BRAND’S
2017/11/13 全球购物
美国主要的特色咖啡和茶公司:Peet’s Coffee
2020/02/14 全球购物
统计员岗位职责
2013/11/14 职场文书
工程部主管岗位职责
2013/11/17 职场文书
庆祝教师节活动方案
2014/01/31 职场文书
社团活动总结
2014/04/28 职场文书
五四青年节优秀演讲稿范文
2014/05/28 职场文书
学校献爱心活动总结
2014/07/08 职场文书
2014年教学工作总结
2014/11/13 职场文书
关于清明节的演讲稿2015
2015/03/18 职场文书
升学宴家长答谢词
2015/09/29 职场文书
读完《骆驼祥子》的观后感!
2019/07/05 职场文书
CSS中calc(100%-100px)不加空格不生效
2023/05/07 HTML / CSS