Годовая практика Weex в Daren Store
Эта статья от команды мобильных терминалов Shang Zhuang.Луффи
Опубликовано в блоге Shangzhuang github, добро пожаловать на подписку!
Также прошел год с момента подключения магазина Shangzhuangdaren к weex, за это время одна за другой были опубликованы некоторые статьи:
«Android» Подробный и всеобъемлющий процесс доступа на основе vue2.0Weex (с точки зрения Android)
Параметры "внешней" страницы weex
«Большой интерфейс» в weex, нативная инициатива по отправке событий для реализации решения JS
Трехтерминальная реализация Weex компонента Pager (ViewPager) — Ben Ren Notes
Запишите моменты, требующие особого внимания в процессе командной тренировки weex.
Вот подробное резюме, в надежде принести вам некоторую ссылку. Наша команда также относительно небольшая, масштаб приложения невелик, и есть много вещей, которые недостаточно хороши, и я надеюсь, что Бог даст мне какой-нибудь совет.
1. Что такое Weex
Weex — это набор простых в использовании кроссплатформенных решений для разработки, которые могут создавать высокопроизводительные и масштабируемые нативные приложения с опытом веб-разработки.Для достижения этого Weex сотрудничает с Vue, использует Vue в качестве фреймворка верхнего уровня, и соответствует стандартной реализации W3C. Благодаря унифицированному API JSEngine и DOM вы даже можете использовать другие платформы, чтобы управлять Weex для создания согласованных нативных приложений с тремя терминалами.
В предисловии цитируетсяОфициальный сайт ВексОпределение , мы действительно испытали это в процессе практики. Вот несколько извлеченных ключевых слов:
Для учащихся, которые не были в контакте с weex, если вы хотите сначала увидеть эффект, вы можете посетить веб-сайт, предоставленный Weex.Онлайн игровая площадка, для редактирования и просмотра, загрузка приложенияplaygroundИгровая площадка сканирует код, чтобы просмотреть эффект.
Видно, что Weex может написать страницу приложения с vue через DSL, разработанную им самим, точно так же, как написать веб-страницу.Вся страница разделена на 3 абзаца.template
,style
,script
, опирается на идею зрелого MVVM.
Как будет сказано позже, теоретически также можно горизонтально поддерживать использование React, angular и других фреймворков для написания страниц. Rax с открытым исходным кодом от Али основан на стандарте React и поддерживает рендеринг в Weex.Подробности см. в предыдущих вопросах и ответах на Zhihu.Что вы думаете о фреймворке Rax с открытым исходным кодом от Ali?
в то время как игровая площадка объединяетWeex SDK
, после сканирования кода скомпилированныйJS Bundle
, а затем анализируется на уровне JS Framework для вывода в формате Json.Visual Dom
, то черезJS-Native Bridge
Он рендерится в Native интерфейс, а доставка событий Js-Native также осуществляется через Bridge. Ниже приведена схема архитектуры, представленная на официальном сайте:
С помощью отладки точки останова вы можете видеть, что инструкции рендеринга, переданные JSFramework в SDK, похожи на эти, и SDK будет отображать соответствующие собственные компоненты в соответствии с различными типами и параметрами.
В традиционном приложении собственный пользовательский интерфейс может напрямую получать мощность устройства, в то время как в приложении Weex собственный пользовательский интерфейс и мощность устройства связаны через JavaScript, как показано на рисунке (рисунок взят с официального сайта weex):
Прежде чем вы начнете получать доступ, вам необходимо узнать о структуре страницы Weex.Подробности вы можете найти на официальном сайте Weex.Структура страницы Weex. Для удобства чтения следующая прямая цитата:
Структура страницы Weex
Отображение интерфейса, логическая обработка, использование возможностей устройства, управление жизненным циклом и другие части.
модель дом
Страницы Weex управляют интерфейсом аналогично HTML DOM. Во-первых, страница будет разложена на дерево DOM, и каждый узел DOM представляет собой относительно независимую единицу собственного представления. Затем различные единицы просмотра объединяются вместе с помощью древовидной структуры для формирования полной страницы.
компоненты
Weex поддерживает компоненты на основе контента, такие как текст, изображение и видео, а также компоненты на основе контейнеров, такие как div, список и прокрутка, а также различные специальные компоненты, такие как ползунок, ввод, текстовое поле и переключатель. Этими компонентами построен интерфейс Weex в виде DOM-дерева.
система компоновки
Компоненты на странице Weex будут расположены в соответствии с определенными спецификациями макета.Мы предоставляем три модели макета в CSS: блочная модель, флексбокс и абсолютный/относительный/фиксированный/адсорбированный макет.
Функция
Weex предоставляет очень богатый API-интерфейс системных функций, включая всплывающее хранилище, сеть, навигацию, всплывающее диалоговое окно и тост и т. д. Разработчики могут импортировать и вызывать эти API-интерфейсы клиентских функций, получив собственный модуль на странице Weex.
Жизненный цикл
Каждая страница Weex имеет свой жизненный цикл, и страница будет проходить весь процесс от начала создания до окончательного уничтожения. Это определяется и реализуется SDK в маршрутизации путем создания и удаления страницы Weex.
Weex обладает хорошей масштабируемостью.Он может расширять сеть, изображения, хранилище, UT, компоненты, интерфейсы и т. д. в соответствии с потребностями собственного приложения и бизнеса. Даже если компоненты, предоставляемые weex, имеют проблемы, их можно напрямую переписать и заменить.
Для доступа к новой технологии мы сначала рассмотрим преимущества и недостатки этой технологии, и какую пользу она может принести команде и бизнесу, затем рассмотрим стоимость доступа, в том числе стоимость обучения членов команды, стоимость изменение проекта и время, стоимость, опыт разработки, мониторинг производительности, аварийное восстановление и т. д. После рассмотрения этого, хорошо, мы начали принимать решение о доступе к Weex.
2. Магазин Daren получает доступ к Weex
В настоящее время Daren Store представляет собой относительно небольшое приложение, в котором за год просматривается 46 страниц. В настоящее время он в целом относительно стабилен, и все последующие страницы также будут разрабатываться с помощью weex.
Потому что преимущества Weex очевидны:
- 3 человека/день -> 1 человек/день
- Избавьтесь от ограничений обновления приложений в значительной степени
- Родной опыт
В процессе доступа мы сделали много вещей в различных аспектах, включая скаффолдинг, распределение конфигурации, правила перехода, относительные адреса, предварительную загрузку, даунгрейд, мониторинг ошибок, построение библиотек компонентов, параметры страницы и так далее. Процесс подробно описан ниже.Если у вас есть лучший метод, добро пожаловать на обсуждение и обмен.
(1) передняя часть
Первое, что нужно сделать, это создать проект Weex, который можно рассматривать как интерфейсный проект, Weex также предоставляет инструменты для формирования шаблонов.
Семейный ковш для строительных лесов, рекомендованный weex:
-
weex-toolkit
: Используется для инициализации проекта, компиляции, запуска и отладки всех инструментов. -
weexpack
: Он используется для упаковки JSBundle, который на самом деле является упаковкой Webpack. -
playground
: приложение на полках, его можно использовать для отображения фактической страницы на мобильном телефоне в режиме реального времени путем сканирования кода. -
code snippets
: Это онлайн-игровая площадка. -
weex devtools
: это инструмент отладки для интерфейсных и нативных разработчиков weex. -
weex-loader
: загрузчик для Webpack, ориентированный на платформы Android и iOS, для компиляции однофайловых компонентов в формате .vue.
Daren Store не использовал структуру, предоставленную weex, но наши одноклассники определили структуру проекта, подходящую для нашего бизнеса.Ниже приведена часть структуры проекта Weex для магазина Daren.Каждая страница имеет папку, содержащую html, js , вид:html文件
: доступ к странице h5 weexjs文件
: входной файл, скомпилированный webpackvue文件
: редактировать страницу weex
Ниже приведен пример среды разработки, поэтому у импортированного js нет номера версии, а в пути официальной среды будет номер версии.
HTML-примерСреди них /dist/weex.js представляетweex-vue-render
, был расширен, включая регистрацию модулей, регистрацию новых пользовательских компонентов.weex-vue-render
Его можно понимать как SDK weex в H5. Подробнее см.HTML-расширение
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
</head>
<body>
<div id="weex"></div>
<!-- entry -->
<script src="//assets.showjoy.net/joyf2e/vendor/weex-extend/dist/weex.js" type="text/javascript"></script>
<script src="./register-weex.min.js" type="text/javascript"></script>
</body>
</html>
Js-пример#weex — соответствующий html<div id="weex"></div>
, Vue зависнет на этом div после рендеринга.
import weexComponent from './register-weex.vue';
weexComponent.el = '#weex';
export default new Vue(weexComponent);
Пример Vue
<template>
<div class="wrapper">
<div>
</template>
<style scoped>
.wrapper {
background-color: #fff;
flex: 1;
}
</style>
<script>
</script>
При сборке определяются два набора webpackConfig, которые используются для компиляции JS для h5 и Native соответственно. Причина, по которой его необходимо компилировать отдельно, связана с требованиями weex.Официальный сайт Векс, мы реализовали удаленные сборки на Jenkins.
Различия в среде компиляции
Чтобы использовать Vue.js в Weex, необходимо обратить внимание на операционные платформы Android и iOS в дополнение к Интернету, и существуют некоторые различия в средах разработки и компиляции. Существует два разных способа компиляции исходных файлов проекта Vue в объектные файлы для веб-платформ и нативных платформ:
- Для веб-платформы, как и для обычных проектов Vue 2.X, вы можете использовать любой официально рекомендованный способ компиляции исходных файлов, например, Webpack + vue-loader или Browserify + vueify.
- Для платформ Android и iOS мы предоставляем инструмент weex-loader для поддержки компиляции однофайловых компонентов в формате .vue, то есть в настоящее время для создания нативных пакетов js можно использовать только Webpack + weex-loader.
(2) Собственный доступ
Пожалуйста, обратитесь к официальному сайту напрямуюИнтегрируйте Weex в существующие приложения, описаны зависимости SDK, инициализация и отрисовка.
В конце концов, окончательный результат рендеринга возвращаетView
, по идее, согласно потребностям бизнеса, представление можно разместить в любом месте страницы.我们达人店,都是整个页面的形式来引入weex。
На стороне Android мы поместили доступ к weex в пользовательский WeexFragment. Кроме того, создайте новую активность WeexActivity и ссылку на WeexFragment. Это делает его более гибким в использовании.
На стороне iOS мы помещаем доступ к weex в пользовательский WeexViewController.
(3) Правила перехода
Когда Native отображает страницу weex, ему необходимо передать сконструированный пакет js, то есть файл js. Однако, независимо от того, является ли это ежедневным методом написания Native или обычным методом внешнего интерфейса, он не будет напрямую переходить к файлу js. Поэтому, учитывая, что это соответствует ежедневному методу написания внешнего интерфейса, при переходе переходите к URL-адресу равномерно, как показано на следующем рисунке:
Будь то weex, нативный или веб-просмотр, переходы — это все URL-адреса, а затем сопоставление выполняется в соответствии с определенными правилами.В соответствии с результатом сопоставления решается, использовать ли для открытия weex, нативное или веб-просмотр.
- Чтобы достичь скачка в weex, native и webview — все это URL-адреса, здесь необходимо сделать два момента:
- 1. Прыжок должен вызвать унифицированный openUrl, href тега a в weex может напрямую написать целевой URL-адрес, а затем перехватить переход тега a на нативной стороне;
- 2. Переход в webview перехватывается, и каждый url должен соответствовать правилам
- Определить правила, встроенную копию приложения, которые могут быть выпущены динамически.
- 1. Соответствующая связь между URL-адресом и исходной нативной страницей, страница может быть определена в соответствии с дизайном маршрутизатора в исходном приложении.
- 2. Соответствие между url и weex js,
hideTitleBar
: скрыть ли родной заголовок;v
: Поддержите минимальную версию приложения, если нет, понизьте версию;page
: имя страницы, как локальное предварительно загруженное имя файла;h5
: адрес h5;url
: js-путь;md5
: md5 файла js, используемого для проверки целостности
Пример соответствия между URL и нативной страницей
[
{
"page":"chat",
"url":"(.*)//shop.m.showjoy.net/shop/chat\?type=1",
"v":"1.7.0"
},
{
"page":"main",
"url":"(.*)//shop.m.showjoy.net/shop/seller_home",
"v":"1.12.0"
}
]
Пример соответствия между url и страницей weex
[
{
"hideTitleBar": "",
"v": "1.7.0",
"page": "order",
"h5": "http://shop.m.showjoy.com/u/trade.html",
"url": "http://cdn1.showjoy.com/assets/f2e/showjoy-assets/shop-weex-m/0.8.1/order-list-weex/order-list-weex.weex.min.js",
"md5": "8b3268ef136291f2e9b8bd776e625c6b"
},
{
"hideTitleBar": "",
"v": "1.7.0",
"page": "shoporder",
"h5": "http://shop.m.showjoy.com/user/tradePage",
"url": "http://cdn1.showjoy.com/assets/f2e/showjoy-assets/shop-weex-m/0.1.1/shop-order-weex/shop-order-weex.weex.min.js",
"md5": "ca818a24588509bfe083cd4b99855841"
}
]
(4) Платформа конфигурации
Для настройки правил перехода мы создали собственную платформу конфигурации, предоставляющую различные конфигурации для полной, предварительной и автономной версии. параметр:
- appType: 1 для Android 2 для iOS
- preTest: true означает предварительный выпуск, false означает полный объем
- appVersion: номер версии приложения.
Платформа предоставит конфигурацию js-страницы, которую текущее приложение поддерживает рендеринг, в соответствии с тремя параметрами.
(5) Поддержка относительных адресов
Согласно обычному методу написания внешнего интерфейса переход и метка в основном являются относительными адресами, поэтому нет необходимости выполнять специальную обработку для офлайн- и онлайн-сред. следующим образом:
Когда мы начали вмешиваться, версия была, вероятно, около 0.8.В то время относительные адреса не поддерживались по умолчанию, и мы уже начали это делать сами. Начиная с версии weex sdk 0.9.4, относительные адреса поддерживаются по умолчанию, но при тестировании и просмотре исходного кода хост, который он принимает, является хостом пакета js, как показано на рисунке:
И мы помещаем пакет js на cdn, доменное имя ежедневной страницы — shop.m.showjoy.com, они несовместимы, поэтому на нативной стороне мы переписалиURIAdapter
(Андроид) иWXURLRewriteProtocol
(iOS) обрабатывается url, если это относительный адрес, плюс ежедневная страница h5host
, запрос тот же. Это поддерживает относительные адреса.Andoird
//这里还可以配置其他的adapter,比如image,storage等
WXSDKEngine.initialize(application,
new InitConfig.Builder()
.setURIAdapter(new SHCustomURIAdapter())
.build());
iOS
[WXSDKEngine registerHandler:[WXSJNetworkDefaultlmpl new] withProtocol:@protocol(WXURLRewriteProtocol)];
При реализации перепишите интерфейс перезаписи, мы настроим разные хосты в соответствии с офлайн, онлайн, предварительной доставкой и другими средами, а также поддержим собственные протоколы, такие как: sms://, weixin://dl/privacy
PS: Переход тега A, реализация Native SDK, заключается в вызове интерфейса openURL модуля «событие». Однако по умолчанию для «события» не зарегистрирован ни один модуль, поэтому вам необходимо зарегистрировать событие самостоятельно или повторно реализовать тег a самостоятельно. Обработка скачка тега в sdk
Пользовательский модуль событий.
(6) Схема предварительной загрузки
Как показано на рисунке, пакет захватывается во время локальной разработки.Хотя загруженный пакет js невелик, продолжительность также очень мала. Но для того, чтобы сделать скорость еще дальше, мы все же делаем схему предзагрузки.
Схема разработана следующим образом:
- 1) После каждого обновления конфигурационного файла, траверс, проверьте md5 файла pagename.js
- 2) Если локально есть файл, совместимый с md5, пропустите его, иначе скачайте
- 3)После завершения загрузки формат сохранения - pagename.js.Если он уже существует, то будет перезаписан.Проверьте md5, чтобы убедиться в целостности файла:
- Если то же самое, запишите время последней модификации файла;
- Если он отличается, удалите загруженный файл, загрузите его снова и повторите процесс проверки.
- 4) Каждый раз при открытии указанной страницы:
- Сначала проверьте, есть ли соответствующий файл подкачки локально
- Если он не существует, используйте удаленный URL-адрес в конфигурации напрямую.
- Если он существует, проверьте, соответствует ли время модификации записи времени последней модификации файла (это делается для
防篡改
; Не вычисляйте md5 напрямую для проверки, потому что вычисление md5 требует времени)- Загрузите его
- Если он несовместим, используйте удаленный URL-адрес в конфигурации.
- Сначала проверьте, есть ли соответствующий файл подкачки локально
(7) Общение с Native-JS
1. JS вызывает Native
- Weex предоставляет интерфейс расширения модуля, разработчики могут зарегистрировать модуль самостоятельно, а модуль определяет интерфейс;
2. Нативные вызовы JS
-
Интерфейс модуля может установить обратный вызов.После обработки реализации интерфейса обратный вызов может быть вызван непосредственно для обратного вызова JS.
-
WXSDKInstance.fireEvent находится на уровне элемента, fireEvent является функцией-членом экземпляра, и необходимо передать elementRef.
-
WXSDKInstance.fireGlobalEventCallback находится на уровне страницы и должен передать instanceID
(8) Контроль ошибок
*Нативная сторона может быть обработана через метод onException в интерфейсе IWXRenderListener, включая ошибку рендеринга, исключение js, сетевую ошибку и т. д.
- Слой Weex, пользовательский интерфейс loge для реализации мониторинга ошибок
(9) Параметры страницы
О ссылке на страницу наша команда одноклассников Nanyang написала статью (ссылка на страницу Weex) [https://juejin.cn/post/6844903491299704840], для удобства чтения я повторю ее здесь.
1. Переадресовать параметр: x.com/a.html перейти к x.com/b.html?age=12При рендеринге Native помимо передачи в JS Bundle также есть параметры options.Мы сохраняем параметры за URL-адресом в options, а затем передаем их на страницу weex.
[_instance renderWithURL:[NSURL URLWithString:mstrURL] options:[self SHWeexOptionsWithH5URL:mstrH5URL withURL:mstrURL] data:nil];
Этот параметр при написании weex можно передать черезweex.config.age
Получать.
Чтобы получить единообразие параметров, то же самое верно для страниц H5.При открытии URL-адреса сначала получите параметры за URL-адресом и сохраните их в window.weex.config.
for (let key in urlParamObj) {
window.weex.config[key] = encodeURIComponent(urlParamObj[key]);
}
2. Обратный перенос параметра: x.com/b.html возвращается к x.com/a.html, возвращая параметр age=2.Это необходимо для реализации функции, аналогичной onActivityResult в Android, которая может передавать параметры на предыдущую страницу. Чтобы реализовать такую функцию, для реализации iOS Native нужно только добавить делегата.
Для достижения этого эффекта в weex нет метода, который можно было бы использовать напрямую.В настоящее время мы используем следующее решение.
-
Сначала определите модуль, добавьте интерфейс setResult, а затем вызовите weex, параметры имеют вид k-v. Реализация интерфейса заключается в том, чтобы сначала хранить данные локально;
-
Вернитесь на предыдущую страницу, когда возобновится/появится, получите сохраненный k-v и передайте данные на страницу weex через fireGlobalEventCallback. и удалить данные.
-
Мониторинг и обработка на странице weex
(10) План перехода на более раннюю версию
Так называемый даунгрейд означает, что рендеринг текущей новой страницы завершается сбоем или текущая версия приложения недостаточно нова для поддержки новой страницы, поэтому будет осуществляться доступ к странице h5. Здесь мы различаем два случая:
- 1. Ошибка рендеринга: постоянный переход на страницу h5
- 2. Контроль версий:
- Новая страница: понизить версию для доступа к странице h5, если версия приложения не поддерживает новую страницу.
- Модификация старой страницы: версии приложений, которые не поддерживают новую страницу, получат доступ к старой странице.
(11) Экранизация
Экранизация всегда была неизбежной темой в мобильной разработке. В мире Weex размер экрана по умолчанию определяется для адаптации к различным размерам экрана iOS и Android. Фреймворк weex выполнил адаптацию нижнего слоя для различных экранов.Конкретная формула расчета такова:实际高宽 = 代码高宽 * (屏幕宽度 / 750)
В настоящее время визуальный эскиз, который мы разработали, равен 375, и нам нужно только получить значение x2 при его разработке. Существует общее место, где встречается требуемый расчет, который подробно описан здесь.
При использовании списка и прокрутки необходимо установить высоту, и эта высота должна быть рассчитана в соответствии с разными страницами.В качестве примера возьмем изображение выше, первое, что приходит на ум:высота списка = высота экрана - высота заголовка
Weex может пройти
$getConfig().env.deviceHeight
а также$getConfig().env.deviceWidth
форма для получения высоты экрана телефона Но на самом деле это неточно, потому что общая высота Android Native на самом деле является полноэкранной высотой, доступной для отображения, а не обязательно высотой физического экрана, потому что есть строки состояния, виртуальные панели кнопок, Smartbar и т. д. Android фрагментации вводятся дополнительные элементы отображения, фактическая полноэкранная высота, скорее всего, будет меньше физической высоты экрана. Таким образом, реальная высота контейнера должна быть передана снаружи,
Фактическая высота списка = ContainerHeight - литерал высоты titleBar * коэффициент конверсииКоэффициент конверсии = this.$getConfig().env.deviceWidth / 750
ps: входящий ContainerHeight передается через интерфейс модуля
list的字面量高度 = list实际高度 / 转换比例ratio = ContainnerHeight / ratio - titleBar的高度字面量
Кроме того, weex также предоставляетthis.$getConfig().env.scale
, который при необходимости можно использовать для вычисления dp2px.
3. Некоторые проблемы и решения, с которыми мы столкнулись
1) Android weex sdk 0.13.1, когда начальное значение компонента ввода пусто, событие @input не может быть вызвано при вставке设置初始值,点击时,如果初始值与placeholder一致,就清空
2) Текст обрезается в системе iOS9.x在iOS9.x系统中不支持line-height,被强行绘制,存在兼容性问题,暂时不要使用font-size和line-height相同大小
3) Динамическая привязка классаvue的写法 :class={'header': true} weex的写法 :class=“[true ? 'header' : '']"
4) Анимация анимации недействительна на странице H5 iOS 8 и ниже.对于webkit不兼容的css样式(transform)进行兼容
5) элементы устройства iOS не могут располагаться горизонтально, когда скроллер прокручивается горизонтально需要给scroller设置样式 flex-deriction: row,这样可以确保三端显示一致。
6) Время преобразования Js Date, разница в Android 8 часовdateConfigTimeZone(timeValue, offset) { const date = new Date(timeValue); // UTC时间 (1970-1-1至今毫秒数 + 本地时间与GMT分钟差) const utc = date.getTime() + (date.getTimezoneOffset() * 60 * 1000); // 返回 (UTC时间 + 时区差) return new Date(utc + (60 * 60 * 1000 * offset)); }
4. Чем мы еще занимаемся
(1) библиотека компонентов weex
После года практики мы также накопили некоторые базовые компоненты и бизнес-компоненты, такие как описание, импорт, пример, предварительный просмотр, qrcode и т. д., как показано на рисунке.
Взгляните на структуру каталогов проекта библиотеки компонентов spon-ui.
|- spon-ui
||-- build
||-- docs
||-- examples
||-- packages
|||--- weex-field
||||---- index.js
||||---- field.vue
||||---- example.vue
||||---- readme.md
||||---- package.json
||-- src
- Некоторые файлы выполнения скриптов хранятся в сборке для отладки и публикации проекта.
- Сценарий для отладки документов хранится в документах, и создается сервер отладки документов.
- Сценарии для отладки компонентов хранятся в примерах, и создается сервер отладки компонентов. (без хранения примеров компонентов)
- В пакетах хранятся реальные компоненты, а также документация и примеры компонентов.
- src содержит общедоступные методы, которые может использовать компонент.
Подробнее см. в том, что написал наш фронтенд-одноклассник Наньян.«Большой внешний интерфейс» Shangzhuang Daren Store Практика проектирования компонентов пользовательского интерфейса
(2) Другие
- Поддержка файлов cookie
- HttpDNS-доступ
- Изображение поддерживает обрезку, webp
- мониторинг производительности, выполнение
- Инкрементное обновление, делаем это
Вышеизложенное является нашим подведением итогов года, и я надеюсь, что оно может послужить вам справочным материалом. Приветствуется обсуждение пробелов в общении.
Спасибо всем членам команды, это результат наших совместных усилий.
@Li He, старший специалист по iOS,github
@mickey, богиня фронтенда, прошу вниманияВейбо
@南阳, бог интерфейса, добро пожаловать на вниманиеВейбо, выход технических статей высок,
Спасибо за помощь, предоставленную следующими замечательными статьями: (я прочитал много статей, если не добавлено, пожалуйста, дайте мне знать)
Самая полная стратегия weex step on the earth - от большой практики и осадков