Skip to content

Instantly share code, notes, and snippets.

@honlyHuang
Last active July 2, 2018 12:41
Show Gist options
  • Save honlyHuang/72d41817c04ad4482a799ed53416e6a3 to your computer and use it in GitHub Desktop.
Save honlyHuang/72d41817c04ad4482a799ed53416e6a3 to your computer and use it in GitHub Desktop.
使用过wepy和taro的toplife小程序项目

使用过wepy和taro的toplife小程序项目

toplife项目背景

TOPLIFE是京东旗下独立运营的全生态精品电商,集创新尊崇的用户体验与领先的电商布局于一身,致力于打造奢侈品牌的线上精品旗舰,成为中国新精英消费者的精致生活指南。

简介太长了,关键词“独立”,“全生态”,“精品”,“领先”,独立意味着全新一套体系,可以抛弃祖传代码;全生态,则是APP之后就是M站,PC站,小程序,未来还可能是快应用或者……

TOPLIFE PC站上我们使用了Nerv,Nerv在完美兼容React语法的同时,具有着出众的性能表现,在Gzip后也只占用9Kb的体积。最重要的是按React的方式再加ESLint+Husky,让团队里的其他成员随时参入这个项目来撸码,人力抽走的时候别的同学轻易接手,参与过PC站的开发有10来个同学,一切是那么完美和谐。

小程序之路

1.0

TOPLIFE PC之后,得知3月份就要进入小程序开发,那时候还在迭代PC站,匆忙之间还是把小程序文档和wepy文档看了一遍。至于为什么使用wepy而不是直接写原生代码呢,因为轮子总是比双脚走得快一些,而且还是这么多人在使用的轮子呢,就它了。

嘿嘿,其实没有那么草率啦,大概以下那么几点:

  • 有同学使用过wepy来做过自研项目,有一些积累,其推荐使用
  • 支持使用第三方 npm 资源
  • 支持ES2015
  • 支持样式编译器:Less/Sass/Styus
  • 腾讯家出的,他自家好多业务都使用

有时候其实不需要太多理由,因为可以选择的本来就很少,mpvue,wepy,原生小程序。

上手撸小程序比较简单:

  • 申请账号,根据指引填写信息和提交资料,开通账号

Toplife小程序最后的目录大致的如下:

.
├── actions
   └── index.js
├── app.wpy
├── asset
   └── toplife_icon.png
├── components
   ├── gb
      └── popup.wpy
├── constants
   └── apis.js
├── pages
   └── index.wpy
├── reducers
   └── index.js
├── store
   └── index.js
└── utils
    └── util.js

一个页面是这样的

<style lang="scss">
	.container { ... }
	.index_list { ... }
	.index_brands_go {...
		&_hover { ... }
	}
</style>

<template>
  <view class="container">
    <view class="index_list">
      ...
      </view>
    </view>
    <button @tap="goToBrandList" class="index_brands_go" hover-class="index_item_go_hover"></button>
  </view>
</template>

<script>
  import wepy from 'wepy'
  import { connect } from 'wepy-redux'
  import { fetchIndexList } from '../actions/index'

  @connect({
    homeData (state) {
      return state.home
    }
  }, {fetchIndexList})

  export default class Index extends wepy.page {
    config = {
      navigationBarTitleText: 'TOPLIFE',
      enablePullDownRefresh: true,
      backgroundTextStyle: 'dark'
    }
    data = {
      shouldIndexHidden: false
    }
    methods = {
      async goToBrandList () {
        await wepy.navigateTo({
          url: './brand/brand_list'
        })
      }
    }
    onShareAppMessage (options) { ... }
    async onLoad (options) {
      // 填充首页的数据
      await this.methods.fetchIndexList()
    }
    onShow () { ... }
    onReady () { ... }
  }
</script>

简单介绍一下这个版本吧,大概就只有9个页面,产品的定位是用于营销,所以就比较简单了,首页、品牌页、店铺页、文章页、登陆相关的页面,现在回忆起来好像很简单,比较麻烦的就是首页里还有一个浮层页,浮层页里可以操作发新人券;还有就是文章页,有一个签到三天和七天发放优惠券的功能。

虽然简单几个页面,考虑到后续扩展,本来想简单撸撸地我们还是使用了数据流管理,采用Redux,有个wepy-redux,上面的目录结构就知道了。

接口放在了constants文件夹下的api.js里,图片放在asset文件夹里。

1.0版本里的一些问题和感受:

在撸业务的过程中印象比较深刻的是以下一些问题:

  • 登陆功能,这一部分代码从账号体系的同学手里给过来的,热乎的原生代码,zip格式的压缩包啊,热乎得很,我把它转化成wepy的形式顺便请教他好像有几个地方参数对不上,他也改得迅速,改完那个文件直接扔过来,我接住还得问他是只改了X地方吗?两次之后挺麻烦的,索性建了个项目扔内部git平台上,他再更新代码我就对比一下看哪里改动了,其实他们要是搞个NPM包或者上传内部git多方便呀。
  • 首页,显示的两种不同的banner,但是链接可能有三种,我直接wx:if三个判断,结果就是IOS9下出现了一些不兼容的情况,一些banner重复显示。改一些wx:ifwx:elifwx:else就好了。
  • 文章页,从首页到文章页或者店铺页,如果之前访问过就会发现,进来先是显示上一个页面,接着才被刷成当前页面,这里需要在上一个页面卸载的时候把数据清一下。
  • 小程序生命周期的问题,页面(onReady)里命名和组件(ready)里的不一致,也许是为了区分,但对于刚上手来说还是需要费一些力气去记的。
  • 小程序请求默认超时时间和最大超时时间都是60s,不能自己定义。

使用wepy的感受

  • 组件化,支持ES6/7,支持NPM,支持LESS预编译,开发起来很方便
  • 第一次使用的时候发现编译后引用的某个包没有到dist目录里,手工复制了,但别的机器好像没有这个问题,神奇。
  • 像Vue一样写代码,上手很简单。
  • 原生的代码改成wepy的代码还是挺方便的,也支持混用。
  • 把WXML、WXSS、JS 放在一个.wpy文件里,搜索和修改起来还是挺方便,很直观,以致于后来转换到Taro的时候一时没有适应过来。
  • 事件绑定:@tap=“function”; function写在methods方法集合中,这点我也挺喜欢的,感觉看其他同学的代码舒服了。
  • 脏数据处理带来一些好处,但触发脏数据检测的 wepy.$apply()在写动画的时候会带来一些困扰。
  • 经过两年积累,一些问题也是可以在issue里找到答案。

2.0

两三周搞定版本1.0以后,四月中旬产品就已经把二期排上了,说要5月中旬搞定,定位也变了,不再是一期的营销和导流,要形成闭环,同时还要联合奢侈品牌做一些合作活动。 购物的黄金流程、品牌店铺、活动页、个人中心、五月大促活动、埋点上报,当时的感觉是要一个月搞定很困难,和产品商量后,砍掉了部分需求,剩下的必做的,但是心里还是没有多少底气,终须一拼,boss说给5个人一起做。 彼时初出茅庐的Taro一脉相承于Nerv,未试牛刀,而之前toplife PC版使用了Nerv开发,大家都熟悉了像react一样开发,现在说要5个人一起开发小程序,那当然是Taro啦。 最后我们成功上线了,有时候从事后往回看,并不能说明孰是孰非,在向着目标行进的两条路上的不同风景而已。

项目结构

.
├── actions
   └── index.js
├── app.js
├── app.scss
├── asset
   └── toplife_icon.png
├── components
   └── gb
       └── popup
           ├── popup.js
           └── popup.scss
├── constants
   └── apis.js
├── pages
   └── index.js
       ├── index.js
       └── index.scss
├── reducers
   └── index.js
├── store
   └── index.js
└── utils
    └── util.js

一个页面是这样的

import Taro, { Component, eventCenter } from '@tarojs/taro'
import { View, Image, Button } from '@tarojs/components'
import { connect } from '@tarojs/redux'

import './index.scss'
import { jumpUrl, gotoPage } from '../../utils/util'
import { fetchIndexList } from '../../actions/index'

class Index extends Component {
  config = {
    navigationBarTitleText: 'TOPLIFE',
    enablePullDownRefresh: true,
    backgroundTextStyle: 'dark'
  }

  constructor() {
    super(...arguments)
    this.state = {
      shouldIndexHidden: false
    }
    this.$app = this.$app || {}
  }
  onShareAppMessage (options) { ... }
  async onPullDownRefresh() { ... }
  async componentWillMount() {
    // 填充首页的数据
    await this.props.fetchIndexList()
  }
  componentDidMount() { ... }
  componentDidShow () { ... }
  componentWillUnmount () { ... }

  render () {
    const { shouldIndexHidden } = this.state
    const { homeData } = this.props
    return (
      <View className={indexClassNames}>
			...
      </View>
    )
  }
}

export default connect(({ home }) => ({
  homeData: home
}), (dispatch) => ({
  fetchIndexList() {
    dispatch(fetchIndexList())
  }
}))(Index)

文件目录上看还是比较清晰的,同V1的时候没有太多的区别,只是增加了很多页面,这里为了方便,我简化了。 个人开始比较喜欢.wpy单文件,后期文件比较长的时候我就很纠结了,把样式从头部放到了尾部,切到Taro后,倒是不用纠结了。

2.0版本里的一些问题和感受:

首先是迁移问题,1.0的时候使用了Wepy,比较规范,整个迁移过程还是比较顺畅的,一两天就搞定了。2.0版成功地试水发布后,另一个内部项目玲珑小程序的开发者决定从wepy迁移到了Taro,11个页面大概用了3天。

关于迁移的意义,如果是从原生到Wepy或者Taro,个人还是觉得值得的,毕竟带来了一些方便,但同时也会带来一些问题,毕竟框架自己也有一些坑,但他们都比较成熟稳定的话,那还是很完美的。单纯从Wepy迁移到Taro,如果你不是更喜欢React或者想同时生成H5,写Wepy或者Taro都是差不多的。

第一版的时候使用了redux,第二版业务要搞复杂很多,也不用去重构第一版的代码,所以一贯不怕麻烦是可以省去很多麻烦的。大家都会react,几个人开发上手还是比较快的。

和第一版一样很多页面还是需要在页面unload的时候去reset数据,要不返回后再进入会先显示上次访问的数据,然后再渲染成这次的数据,这个是Wepy和Taro都会有的,而使用原生小程序没有这个问题。

这一版toplife后台接口验证了Referer ,小程序不允许改Referrer,开发者工具里是https://servicewechat.com/{appid}/devtools/page-frame.html,线上是https://servicewechat.com/{appid}/{version}/page-frame.html

整个项目几乎是输出一些页面就提测,几乎和测试同学并行,在开发过程中还是有一些顾及不到的地方只能等发布后再优化了。

使用Taro的感受

  • 同样是支持组件化和可以使用NPM包及ES 6/7语法,支持样式编译器,开发起来很便利。
  • 页面和组件统一的生命周期,不用去理会页面是onReady而组件是ready这种细节。
  • 从像Vue一样开发小程序到像React一样开发小程序,个人还是喜欢react一些,Taro使用React的生命周期,例如componentDidMount使得小程序的页面onReady和组件的ready接口统一了,不用费心去记,上手难度低了一些,很方便有React基础的同学加入项目里。
  • 获取页面的参数在Taro里使用this.$router.params这个对象,例如/pages/detail?id=543则是this.$router.params.id就可以拿到了543,在小程序里好像就只能在onLoad里的option取到了,例如:
Page({
  onLoad: function(option){
    console.log(option.id)  
  }
})
  • Taro引用组件的时候都是大写开头的,例如Image,在写样式的时候如果想用标签应该是使用image,不过个人觉得还是取个类名会比较明智一下,万一以后改标签呢。
  • Taro对不支持的语法和特性单独写了 ESLint 规则,我们只管写代码,写到不支持的语法/特性编辑器会报错,并给出报错信息和一个文档地址描述。
  • 因为是试水,所以Taro还是会遇到一些问题的,不过好在反馈后,主创们一顿操作猛如虎,版本更新快得飞起,没有影响到开发进度。我们开发的toplife第二版完成的时候,taro的版本是0.0.39,现在已经是0.0.60,这速度也是没谁了。

最后

有些人觉得前端变化太快了,前些日子deno出来的时候,一人去刷deno的issue「求不要更新了,老子学不动了」,想来可笑。Toplife我们尝试了很多东西,从PC使用Nerv到小程序使用Wepy,然后又是Taro,在永远做不完的需求面前,至少是越来越愉悦了,开发越来越便利了,代码越来越规范,合作比以前轻松,接手别人的代码也没有以前那么抗拒了。

现在写小程序的框架还是非常多的,我们实践过的tarowepy,以及没有试过的mpvuetina,都为了让我们更快更爽地搞定需求,早点回家陪家人,或者世界杯年的时候可以有时间早点回家看球。

要写小程序,选一个框架肯定比直接写原生小程序方便,如果你手里恰好有把锤子(会react或vue),那么选择相应的加强工具taro或wepy。如果想一套代码多端使用,那必然是taro了,目前小程序和H5都支持了,下一步是RN和快应用。

最后如果有同学问我“如果要在wepy和taro中选择一个,选择哪个呢?”我的回答是taro。“如果是你的最好的朋友要这众多的框架中推荐一个呢?” 答案还是一样的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment