Практика Таро - Опыт разработки мини-программ TOPLIFE

внешний интерфейс Vue.js React.js Redux
Практика Таро - Опыт разработки мини-программ TOPLIFE

Небольшой партнер из команды, которая поддерживает бизнес апплетов TOPLIFE, надеюсь, он будет вам полезен в использовании Таро.

предисловие

Некоторое время назад фолловинг от нашей Bump LabReactграмматическийМультитерминальный план развития - TaroНаконец-то открытый исходный код для внешнего мира, добро пожаловать на просмотрstar(Сначала воспроизведите волну рекламы). Используется в качестве первой партииTaroОдин из разработчиков апплета TOPLIFE разработал, естественно, много обходных путей, проложил много ям, помог найти много багов. Теперь, когда проект наконец-то онлайн, пришло время подвести итоги и поделиться им с вами.

Сравните с WePY

Когда была разработана первая фаза TOPLIFE, она фактически использоваласьWePY(Таро в то время еще не было разработано), а затем его полностью переоборудовали для использования во второй фазе.Taroразработка. Как человек, который использовал как небольшие среды разработки программ, так и применял их в производственной среде, естественно сравнивать сходства и различия между ними.

Та же точка

  • разработка компонента
  • поддержка пакетов npm
  • поддержка функций ES6+,Promise,Async FunctionsЖдать
  • Поддержка прекомпилятора CSS, Sass/Stylus/PostCSS и т. д.
  • Поддержка управления состоянием с помощью Redux
  •  …

Об одном и том же много говорить не надо, на дворе 2018 год.

разница

  • стиль разработки
  • Принцип реализации
  • WePY поддерживает слот, Taro не поддерживает прямой рендеринг дочерних элементов.

стиль разработки

Самая большая разница, естественно, это разница в стиле разработки,WePYИспользуя стиль разработки, похожий на Vue,Taroкласс используетсяReactСтиль разработки, можно сказать, что все равно будет большая разница в опыте разработки. Опубликуйте официальную демонстрацию для краткого объяснения.

WePY demo

<style lang="less">
    @color: #4D926F;
    .userinfo {
        color: @color;
    }
</style>
<template lang="pug">
    view(class='container')
        view(class='userinfo' @tap='tap')
            mycom(:prop.sync='myprop' @fn.user='myevent')
            text {{now}}
</template>

<script>
    import wepy from 'wepy';
    import mycom from '../components/mycom';

    export default class Index extends wepy.page {
        
        components = { mycom };
        data = {
            myprop: {}
        };
        computed = {
            now () { return new Date().getTime(); }
        };
        async onLoad() {
            await sleep(3);
            console.log('Hello World');
        }
        sleep(time) {
            return new Promise((resolve, reject) => setTimeout(resolve, time * 1000));
        }
    }
</script>

Taro demo

import Taro, { Component } from '@tarojs/taro'
import { View, Button } from '@tarojs/components'

export default class Index extends Component {
  constructor () {
    super(...arguments)
    this.state = {
      title: '首页',
      list: [1, 2, 3]
    }
  }

  componentWillMount () {}

  componentDidMount () {}

  componentWillUpdate (nextProps, nextState) {}

  componentDidUpdate (prevProps, prevState) {}

  shouldComponentUpdate (nextProps, nextState) {
    return true
  }

  add = (e) => {
    // dosth
  }

  render () {
    return (
      <View className='index'>
        <View className='title'>{this.state.title}</View>
        <View className='content'>
          {this.state.list.map(item => {
            return (
              <View className='item'>{item}</View>
            )
          })}
          <Button className='add' onClick={this.add}>添加</Button>
        </View>
      </View>
    )
  }
}

Это можно увидеть в WePY,css,template,scriptВсе в файле WPY,templateТакже поддерживает несколько синтаксисов механизма шаблонов, а затем поддерживаетcomputed,watcheretc, это типичный стиль Vue.

В Taro это совершенно стиль React, в том числеconstructor,componentWillMount,componentDidMountРеагировать, такие как жизненный цикл различных функций, а такжеreturnвернулся вjsx, люди, знакомые с React, могут очень быстро начать работу.

Помимо этого есть небольшие отличия:

  • Шаблоны в WePY илиwxml, используются все собственные компоненты апплета, то есть различные компоненты документа апплета; и каждый компонент, используемый в Taro, должен начинаться с@tarojs/componentsимпортные, в том числеView,TextИ другие основные компоненты (на самом деле это делается для того, чтобы преобразовать много раз в приготовлении)
  • обработка событий
    • В Таро используетсяclickсобытие вместоtapмероприятие
    • WePY использует сокращенное обозначение @+событие, а Таро — on+название события.
    • Чтобы предотвратить всплытие на WePY, используется @+event.stop, а Таро нужно использовать явноe.stopPropagation()перестать пузыриться
    • Параметр события WePY может передавать параметры непосредственно после функции, например@tap="click({{index}})"; в то время как Таро используетbindпередавать параметры, такие какonClick={this.handleClick.bind(null, params)}
  • WePY использует собственный жизненный цикл апплета, а компоненты имеютpageа такжеcomponentотличие; Taro реализует жизненный цикл, подобный React, и не имеетpageа такжеcomponentразличие, обаcomponent

В общем ведь есть два разных стиля разработки, и естественно будет много больших и маленьких отличий. Здесь с одной из популярных на данный момент сред разработки апплетовWePYПростое сравнение в основном для удобства всех, чтобы быстрее понятьTaro, чтобы выбрать наиболее подходящий для вас метод разработки.

Опыт практики

Taroофициально предоставленdemoЭто очень просто, в основном, чтобы все могли быстро приступить к работе и приступить к работе. Итак, когда мы хотим разработать масштабный проект, как мы должны его использовать?TaroСделать опыт разработки лучше и повысить эффективность разработки? Как один из сотрудников, активно вовлеченных в разработку апплета TOPLIFE, я хотел бы рассказать о своем практическом опыте и опыте.

Как организовать код

Используйте taro-cli для создания таких шаблонов

├── dist                   编译结果目录
├── config                 配置目录
|   ├── dev.js             开发时配置
|   ├── index.js           默认配置
|   └── prod.js            打包时配置
├── src                    源码目录
|   ├── pages              页面文件目录
|   |   ├── index          index页面目录
|   |   |   ├── index.js   index页面逻辑
|   |   |   └── index.css  index页面样式
|   ├── app.css            项目总通用样式
|   └── app.js             项目入口文件
└── package.json

Если вводится redux, например, в нашем проекте, каталог выглядит так:

├── dist                   编译结果目录
├── config                 配置目录
|   ├── dev.js             开发时配置
|   ├── index.js           默认配置
|   └── prod.js            打包时配置
├── src                    源码目录
|   ├── actions            redux里的actions
|   ├── asset              图片等静态资源
|   ├── components         组件文件目录
|   ├── constants          存放常量的地方,例如api、一些配置项
|   ├── reducers           redux里的reducers
|   ├── store              redux里的store
|   ├── utils              存放工具类函数
|   ├── pages              页面文件目录
|   |   ├── index          index页面目录
|   |   |   ├── index.js   index页面逻辑
|   |   |   └── index.css  index页面样式
|   ├── app.css            项目总通用样式
|   └── app.js             项目入口文件
└── package.json

TOPLIFE小程序整个项目大概3万行代码,数十个页面,就是按上述目录的方式组织代码的。 Наиболее важные папки в основномpages,componentsа такжеactions.

  • pagesВнутри находится входной файл каждой страницы.Простая страница может быть непосредственно входным файлом.Если страница более сложная, входной файл будет использоваться как совокупный файл компонента.reduxПривязка обычно осуществляется здесь.

  • компоненты размещеныcomponentsв. Каталог внутри такой, если естьcouponстраница с купоном, наpagesКонечно, естьcoupon, как запись страницы, а затем его компоненты сохраняются вcomponents/couponвнутри, то естьcomponentsОн также будет разделен на модули в соответствии со страницей, и может быть построен общий компонент.components/publicпапка для повторного использования.

    Преимущество этого в том, что между страницаминезависимо друг от друга,не влияют друг на друга. Поэтому некоторые наши разработчики также делят труд по размерам страницы, не мешая друг другу, что значительно повышает эффективность нашей разработки.

  • actionsЭта папка тоже важнее, здесь логика вытягивания данных и повторной обработки данных. Можно сказать, что если данные обрабатываются хорошо и поток понятен, весь проект наполовину успешен.Подробности см. в разделе *** Лучшее использование избыточности***. как указано выше, еслиcouponстраницыactions, то он будет помещен вactions/couponВнутри вы снова можете увидеть, что все модули различаются по размеру страницы.

Помимо,assetСтатические ресурсы, для хранения которых используется файл, например некоторые изображения класса значков, но рекомендуется не хранить слишком много, в конце концов, существуют ограничения на пакет. а такжеconstantsЭто место для хранения констант, напримерapiДоменное имя, конфигурация и т. д.

Если вы будете следовать вышеуказанным или подобным методам организации кода, а также следовать нормам и соглашениям, вы сможете повысить свою эффективность при разработке крупномасштабных проектов, по крайней мере, намного.

лучше использовать редукс

Каждый должен быть знаком с redux, библиотекой управления состоянием, которая обычно используется с некоторым промежуточным ПО. Наш проект в основном используетredux-thunkа такжеredux-loggerПромежуточное ПО, одно для обработки асинхронных запросов и одно для отладки, трассировкиactions.

предварительная обработка данных

Я считаю, что с таким моментом сталкивался каждый, данные, возвращаемые интерфейсом, и данные, отображаемые на странице, не полностью совпадают, и часто требуется слой предобработки. Итак, где должна управляться эта бизнес-логика, внутри компонента илиreduxобработать?

Например:

mage-20180612151609

Например, в модуле корзины покупок, показанном выше, данные, возвращаемые интерфейсом,

{
	code: 0,
	data: {
        shopMap: {...}, // 存放购物车里商品的店铺信息的map
        goods: {...}, // 购物车里的商品信息
        ...
	}
	...
}

Да, магазин товаров и товар в корзине размещены в двух объектах, но представление требует, чтобы они отображались вместе. В настоящее время, если вы напрямую сохраняете возвращенные данные вstore, то внутри компонентаrenderКогда придет время собрать воедино, сопоставить две информации, а затем отобразить ее, окажется, что логика внутри компонента очень хаотична и недостаточно чиста.

Поэтому я лично рекомендую, чтобы после того, как интерфейс вернул данные, они были непосредственно обработаны в данные, соответствующие отображению страницы, а затемdispatchОбработанные данные эквивалентны слою перехвата, а именно:

const data = result.data // result为接口返回的数据
const cartData = handleCartData(data) // handleCartData为处理数据的函数
dispatch({type: 'RECEIVE_CART', payload: cartData}) // dispatch处理过后的函数

...
// handleCartData处理后的数据
{
    commoditys: [{
        shop: {...}, // 商品店铺的信息
        goods: {...}, // 对应商品信息
    }, ...]
}

Видно, что процесс обработки данных перехватывается и обрабатывается перед рендерингом, а соответствующий товарный магазин и товар помещаются в один объект.

Есть несколько преимуществ для этого

  • Один из них — рендеринг компонентов.чище, вам не нужно заботиться о том, как изменить данные, чтобы они соответствовали требованиям представления внутри компонента,Просто позаботьтесь о логике самого компонента, такие как события кликов, взаимодействия с пользователем и т. д.

  • Во-вторых, поток данных.более контролируемый, если данные, возвращаемые последующим фоном, изменяются, все, что нам нужно сделать, это изменитьhandleCartDataЛогика в функции не требует изменения логики внутри компонента.

    Фоновые данные -> обработка перехвата -> ожидаемая структура данных -> компоненты

На самом деле, не только при возврате фоновых данных, но и при необходимости изменения других структур данных может выполняться слой перехвата данных, а время перехвата также может быть скорректировано в соответствии с бизнес-логикой.Соответствуют ли данные представлению, ориентируйтесь только на логику внутреннего взаимодействия, что тоже подходитReactЕго первоначальное намерение, представление, основанное на данных.

подключение может сделать больше

connectВсе знают, что он используется для подключенияstore,actionsИ компоненты, много раз просто скопируйте его в соответствии с шаблонным кодом и измените соответствующие компоненты компонентов.store,actions.实际上,我们还可以做一些别的处理,例如:

export default connect(({
  cart,
}) => ({
  couponData: cart.couponData,
  commoditys: cart.commoditys,
  editSkuData: cart.editSkuData
}), (dispatch) => ({
  // ...actions绑定
}))(Cart)

// 组件里
render () {
	const isShowCoupon = this.props.couponData.length !== 0
    return isShowCoupon && <Coupon />
}

Вышеупомянутое очень распространеноconnectпиши тогдаrenderфункционировать в соответствии сcouponDataБудут ли данные отображаться. В это время мы можемthis.props.couponData.length !== 0Это суждение потеряноconnect, чтобы достичьcomputedЭффект следующий:

export default connect(({
  cart,
}) => {
  const { couponData, commoditys, editSkuData  } = cart
  const isShowCoupon = couponData.length !== 0
  return {
    isShowCoupon,
    couponData,
    commoditys,
    editSkuData
}}, (dispatch) => ({
  // ...actions绑定
}))(Cart)

// 组件里
render () {
    return this.props.isShowCoupon && <Coupon />
}

можно увидеть вconnectопределено вisShowCouponпеременная, реализующаяcouponDataвыполнятьcomputedЭффект.

По сути, это тоже процесс перехвата данных. Кромеcomputed, и другие функции также могут быть реализованы, которые могут свободно выполняться чиновниками.

Ощущение проекта

Самое большое ощущение, что в процессе разработки,Иногда я забываю, что пишу небольшую программу, и мне кажется, что я пишу страницу React.. Да, когда-то я хотел привязать событие прокрутки к странице, только чтобы понять, что нет такой вещи, какdoucment.body.addEventListenerтакого рода вещи. В использованииWePYВ процессе те странные грамматики мне еще напомнили, что это маленькая программа, не страница h5, а использующаяTaro, эта дифференциация была стерта очень мало. Хотя есть определенныеограничение, но я в основном использую его с привычкой разработки ReactTaro, можно сказать, что это значительно улучшило мой опыт разработки.

Некоторые моменты, на которые следует обратить внимание

ЭтоTaro, или разработка небольшой программы, есть на что обратить внимание? Конечно, есть много обходных путей.

Стек страниц имеет только 10 слоев
  • Подсчитано, что данные каждой страницы кэшируются внутри апплета, поэтому существует ограничение в 10 слоев. Проблема в том, что если на странице есть круговой переход, то есть страница А может перейти на страницу Б, страница Б тоже может перейти на страницу А, а потом пользователи заходят на Б из А, а когда хотят вернуться на А , они часто ведут прямо на страницу B. Нажмите, чтобы перейти на страницу A,вместо точки возвратаНазад к А, в итоге 10 этаж быстро прорвался. Итак, мы самиnavigateToФункция инкапсулирована для предотвращения переполнения.
содержимое страницы кэшируется
  • Как упоминалось выше, содержимое страницы кэшируется. Поэтому, если страница отображает представления на основе других данных, при выполнении нового рендеринга будет кеш предыдущего рендеринга, что приведет к мерцающему изменению внешнего вида страницы и очень плохому взаимодействию с пользователем. На самом деле решение очень простое, каждый разcomponentWillUnmountПросто очищайте данные текущей страницы в течение жизненного цикла. Ведь апплет не х5.Здесь не сказано,что он будет обновляться каждый раз при входе на страницу,и не уничтожаться при выходе.Действия по обновлению и очистке данных нужно активно запускать в жизни циклическая функция.
Невозможно прослушивать события прокрутки страницы в любое время
  • Событие прокрутки страницы может быть передано только черезonPageScrollСлушать, поэтому, когда я хочу прослушать операцию в компоненте, логика этой части заранее.onPageScrollфункций, увеличивая стоимость абстракции. Например, мне нужно развить свиток до определенного положения на потолке.tab, мог быть вtabУсовершенствована логика внутренней обработки, что снижает возможность ее повторного использования.
На что обратить внимание при разработке Таро
  • Я изначально хотел его подробно описать, но стараниями наших больших начальников и сверхурочной работой был разработан плагин eslint, и Таро завершен.Документация. Пока вы следуете спецификации подключаемого модуля eslint и просматриваете документацию, серьезных проблем возникнуть не должно.Если у вас есть какие-либо вопросы, пожалуйста, задавайтеissue.

Суммировать

В общем, сTaroОпыт разработки небольших программ еще очень хороший.Самое главное, что вы можете использовать jsx для написания небольших программ! ! ! Как поклонник React, я могу сказать, что очень взволнован~

Наконец, добро пожаловать, чтобы следоватьgithub.com/nervjs/taro