视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001 知道1 知道21 知道41 知道61 知道81 知道101 知道121 知道141 知道161 知道181 知道201 知道221 知道241 知道261 知道281
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
taro开发微信小程序的实践
2020-11-27 21:56:23 责编:小采
文档

在京东凹凸实验室开发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

下载本文
显示全文
专题