От товарищей по команде - Аджи, статья о практической практике Таро, надеюсь будет полезна всем.
1. Введение в Таро
Taro
представляет собой набор следующихReact
Многотерминальная унифицированная среда разработки для спецификаций грамматики.
использоватьTaro
, мы можем написать только один набор кода, а затем передатьTaro
Инструмент-компилятор для компиляции исходного кода в код, который можно запускать на разных сторонах (апплет WeChat, H5, сторона приложения и т. д.). В настоящее времяTaro
Он поддерживает компиляцию кода, который поддерживает работу апплета WeChat и H5.Поддержка RN, быстрого приложения и апплета Alipay все еще находится в стадии разработки.
Подробности смотрите в статье"Многотерминальная унифицированная среда разработки - Taro 》и репозиторий GitHub https://github.com/NervJS/taro
2. Предисловие
Для того, чтобы изучить Таро, я нашел его на githubДемонстрация апплета Zhihu, В этой статье реализована версия Zhihu H5 для Таро и небольшая демонстрация программы путем изменения кода.Студенты, интересующиеся Таро, могут пометить или разветвить, чтобы учиться.Адрес GitHub.
3. Установка
УстановитьTaro
Инструменты разработки@tarojs/cli
использоватьnpm
илиyarn
Установить глобально
npm install -g @tarojs/cli
// 或
yarn global add @tarojs/cli
скачать код
git clone https://github.com/jimczj/taro_zhihu
# 安装依赖
cd taro_zhihu
npm i
4. Запустите код
Каталог файлов выглядит следующим образом:
├── dist 编译结果目录
├── config 配置目录
| ├── dev.js 开发时配置
| ├── index.js 默认配置
| └── prod.js 打包时配置
├── src 源码目录
| ├── pages 页面文件目录
| | ├── index index页面目录
| | | ├── index.js index页面逻辑
| | | └── index.css index页面样式
| ├── app.css 项目总通用样式
| └── app.js 项目入口文件
└── package.json
Войдите в каталог проекта, чтобы начать разработку, вы можете выбрать режим предварительного просмотра апплета или режим предварительного просмотра h5.Если вы используете режим предварительного просмотра апплета WeChat, вам необходимо загрузить и открыть его самостоятельно.Инструменты разработчика WeChat, выберите корневой каталог проекта предварительного просмотра.
Режим предварительного просмотра компиляции апплета WeChat:
# npm script
npm run dev:weapp
# 或 仅限全局安装
taro build --type weapp --watch
Режим предварительного просмотра компиляции H5:
# npm script
npm run dev:h5
# 或 仅限全局安装
taro build --type h5 --watch
5. Внимание перед разработкой
Если вы используете режим предварительного просмотра программы WeChat Mini, вам необходимо загрузить и использоватьИнструменты разработчика WeChatДобавьте проект для предварительного просмотра.В это время вам нужно обратить внимание на настройки проекта инструментов разработчика WeChat.
- Необходимо настроить функцию ES6 на ES5, чтобы она была отключена, и при ее включении может появиться сообщение об ошибке.
- Нужно настроить автоматическое завершение стиля при загрузке кода выключено, а при включении может выдаваться ошибка.
- Вам нужно установить код для сжатия и загрузки, чтобы закрыть, и вы можете сообщить об ошибке при его открытии.
6. Подробное объяснение реализации функции
6.1 Глобальная конфигурация мини-программы
app.json
Файл используется для глобальной настройки апплета WeChat, определения пути к файлу подкачки, производительности окна, установки времени ожидания сети, установки нескольких вкладок и т. д. из оригиналаapp.json
превратиться вTaro
Проектapp.js
Затрат почти нет, а конфигурация в основном такая же. Единственное, что следует отметить, это то, что папка ресурсов статического изображения должна быть помещена в каталог src, чтобы ресурсы изображения были скопированы и упакованы при компиляции и упаковке кода. Сначала я поместил папку ресурсов статического изображения на тот же уровень, что и src, а потом не мог найти ресурсы изображения, теряя много времени. Ну, нечего сказать, посмотрите на сравнение кода ниже, вы поймете, что эта миграция очень проста, расшифровывается какReact
Написание, это выглядит более приятным для глаз.
Оригинальный апплет WeChatapp.json(Сокращенный) код выглядит следующим образом:
{
'pages':[
'pages/index/index',
'pages/discovery/discovery',
'pages/more/more',
'pages/answer/answer',
'pages/question/question'
],
'window':{
'backgroundTextStyle':'light',
'navigationBarBackgroundColor': '#0068C4',
'navigationBarTitleText': '知乎',
'navigationBarTextStyle':'white',
'enablePullDownRefresh':true
},
'tabBar': {
'color': '#626567',
'selectedColor': '#2A8CE5',
'backgroundColor': '#FBFBFB',
'borderStyle': 'white',
'list': [{
'pagePath': 'pages/index/index',
'text': '首页',
'iconPath': 'images/index.png',
'selectedIconPath': 'images/index_focus.png'
}, {
'pagePath': 'pages/discovery/discovery',
'text': '发现',
'iconPath': 'images/discovery.png',
'selectedIconPath': 'images/discovery_focus.png'
}, {
'pagePath': 'pages/more/more',
'text': '我的',
'iconPath': 'images/burger.png',
'selectedIconPath': 'images/burger_focus.png'
}]
}
}
Код, записанный в Таро, выглядит следующим образом:
import Taro, { Component } from '@tarojs/taro'
import Index from './pages/index'
import './app.scss'
class App extends Component {
config = {
pages: [
'pages/index/index',
'pages/discovery/discovery',
'pages/more/more',
'pages/answer/answer',
'pages/question/question'
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#0068C4',
navigationBarTitleText: 'Taro知乎',
navigationBarTextStyle: 'white',
enablePullDownRefresh: true
},
tabBar: {
color: '#626567',
selectedColor: '#2A8CE5',
backgroundColor: '#FBFBFB',
borderStyle: 'white',
list: [{
pagePath: 'pages/index/index',
text: '首页',
iconPath: './asset/images/index.png',
selectedIconPath: './asset/images/index_focus.png'
},{
pagePath: 'pages/discovery/discovery',
text: '发现',
iconPath: './asset/images/discovery.png',
selectedIconPath: './asset/images/discovery_focus.png'
},
{
pagePath: 'pages/more/more',
text: '我的',
iconPath: './asset/images/burger.png',
selectedIconPath: './asset/images/burger_focus.png'
}]
}
}
render () {
return (
<Index />
)
}
}
Taro.render(<App />, document.getElementById('app'))
6.2 Главная
Эффект страницы выглядит следующим образом:
Описание функции: проведите вверх, чтобы обновить, потяните вниз, чтобы загрузить больше, запрос данных, нажмите, чтобы перейтиДействие обновления и продолжения загрузки зависит отScrollView
компонент и привязать к компонентуonScrolltoupper
иonScrolltolower
для привязки событий, вызванных прокруткой вверх и вниз, и в то же времяupperThreshold
иlowerThreshold
Возможность регулировать расстояние от границы при срабатывании.
использование API запроса данныхTaro.request
, иwx.request
Метод использования в основном такой же, разницаTaro.request
естественная поддержкаpromise
Имитация использования данныхeasy-mockпредоставлять .
Нажмите, чтобы перейти к использованиюTaro.navigateTo
,иwx.navigateTo
Это в основном то же самое.При написании прыжка я хотел сначала написать его в виде анонимной функции, и обнаружил, чтоTaro
Пока не поддерживается, но говорят, что будет поддерживаться.Taro
Скорость итерации по-прежнему очень высока.
При рефакторинге домашней страницы наиболее трудоемкой проблемой должна бытьwxss
превратиться вscss
,Taro
После того, как компоненты преобразованы в апплет WeChat и веб-сайт, метки меняются, напримерImage
компонент станетimage
илиimg
теги, однако оригиналwxss
Имя тега используется для обозначения css, что приводит к тому, что апплет WeChat ведет себя несовместимо с веб-стилем. Поэтому не рекомендуется использовать имя тега для имени css, рекомендуется использовать класс напрямую.
export default class Index extends Component {
config = {
navigationBarTitleText: '首页'
}
constructor() {
super(...arguments)
this.state = {
loading:true,
list:[]
}
}
componentDidMount () {
// 获取远程数据
this.updateList()
}
updateList() {
Taro.showLoading({title: '加载中'})
Taro.request({
url: 'https://easy-mock.com/mock/5b21d97f6b88957fa8a502f2/example/feed'
}).then(res => {
Taro.hideLoading()
if (res.data.success) {
this.setState({
loading:false,
list:res.data.data
})
}
})
}
appendNextPageList() {
Taro.showLoading({title: '加载中'})
Taro.request({
url: 'https://easy-mock.com/mock/5b21d97f6b88957fa8a502f2/example/feed'
}).then(res => {
Taro.hideLoading()
if (res.data.success) {
this.setState({
list: this.state.list.concat(res.data.data)
})
}
})
}
render () {
return (<ScrollView className='container'
scrollY
scrollWithAnimation
scrollTop='0'
lowerThreshold='10'
upperThreshold='10'
onScrolltoupper={this.updateList}
onScrolltolower={this.appendNextPageList}
>
<View className='search flex-wrp'>
<View className='search-left flex-item'>
<View className='flex-wrp'>
<View className='flex1'><Image src={searchPng}></Image></View>
<View className='flex6'><Input type='text' placeholder='搜索话题, 问题或人' placeholderClass='search-placeholder'/></View>
</View>
</View>
<View className='search-right flex-item'>
<Image src={lightingPng}></Image>
</View>
</View>
{
this.state.loading
? <View className='txcenter'><Text>加载中</Text></View>
: this.state.list.map((item,index)=>{
return <Feed key={item} />})
}
</ScrollView>
)
}
}
6.3 Компоненты Таро
На самом деле, я никогда не понимал апплет WeChat.Component
компонент сPage
Функцию жизненного цикла страницы следует выполнять по-другому.onLoad、onReady、onUnload
и так далее, а в компоненте этоcreated、attached 、ready
д., в отличие отTaro
Он более унифицирован, будь то страница или компонент, написаниеReact
Жизненный цикл постоянен, и разработка единого API проходит намного проще.
тем не мениеTaro
Компонент по-прежнему имеет много ограничений, например, он не поддерживает прямой рендеринг.children
, то есть не поддерживаетthis.props.children
;props
не может быть доставленjsx
;
При абстрагировании компонентов следует обратить внимание на следующие основные моменты:
- На письме,
Taro
Первая буква компонента должна быть заглавной и использоваться в верблюжьем регистре, например, вwxml
Этикетка внутри естьview、scroll-view、image
,существуетTaro
быть записано какView、ScrollView、Image
.Taro
привязки событий все привязки событий начинаются сon
начните с верблюжьего регистра
// 小程序代码
<scroll-view scroll-y='true' class='container' bindscrolltoupper='upper' upper-threshold='10' lower-threshold='5' bindscrolltolower='lower'>
</scroll-view>
// Taro 代码
<ScrollView className='container'
scrollY
scrollWithAnimation
scrollTop='0'
lowerThreshold='10'
upperThreshold='10'
onScrolltoupper={this.upper.bind(this)}
onScrolltolower={this.lower.bind(this)}
>
</ScrollView>
- Апплет ссылается на локальные статические ресурсы непосредственно в
src
Напишите относительный путь,Taro
Ссылка на локальные статические ресурсы требует сначалаimport
Зайди и воспользуйся еще раз.Чтобы путь к образу не ошибался при развёртывании h5, лучше всего поставить образ на сервер, а потом прописать путь http напрямую.
// 小程序 引用本地静态资源
<image src='../../images/search.png'></image>
// Taro 引用本地静态资源
import searchPng from '../../asset/images/search.png'
// ...此处省略无数代码
<Image src={searchPng}></Image>
// 最好把图片放在服务器上,然后写http 路径
<Image src='https://image.ibb.co/kUissy/search.png'></Image>
- Разница между обходом списка: апплет использует язык шаблонов, а
Taro
использоватьjsx
// 小程序
<block wx:for='{{feed}}' wx:for-index='idx' wx:for-item='item' data-idx='{{idx}}'>
<view class='feed-item'>
...
</view>
</block>
// Taro 代码
{
this.state.list.map((item,index)=>{
return <Feed {...item} key={index} />
})
}
В абстрактном процессе компонента ответа я хочу написать его прямо в чистой функциональной форме
// 暂不支持这种写法
const Text = ({ answer }) =>
<p>{answer}</p>
Я обнаружил, что он еще не поддерживается, поэтому я честно написал его в виде класса:
export default class Feed extends Component {
navigateTo(url) {
Taro.navigateTo({url:url})
}
render() {
return (
<View className='feed-item'>
<View className='feed-source'>
<View className='avatar flex1'>
<Image src={this.props.feed_source_img}></Image>
</View>
<View className='flex8'>
<Text className='feed-source-txt'>{this.props.feed_source_name}{this.props.feed_source_txt}</Text>
</View>
<View className='flex1'>
<Image className='item-more' mode='aspectFit' src={more}></Image>
</View>
</View>
<View className='feed-content'>
<View className='question' onClick={this.navigateTo.bind(this,'/pages/question/question')}>
<View className='question-link'>
<Text>{this.props.question}</Text>
</View>
</View>
<View className='answer-body'>
<View>
<Text className='answer-txt' onClick={this.navigateTo.bind(this,'/pages/answer/answer')} >{this.props.answer_ctnt}</Text>
</View>
<View className='answer-actions'>
<View className='like dot'>
<View>{this.props.good_num} 赞同 </View>
</View>
<View className='comments dot'>
<View>{this.props.comment_num} 评论 </View>
</View>
<View className='follow-it'>
<View>关注问题</View>
</View>
</View>
</View>
</View>
</View>
)
}
}
Во время использования пакета я хочу использовать{...item}
Способ разобрать задание, я обнаружил, что оно пока не поддерживается, и мое сердце немного разбито.
this.state.list.map((item,index) => {
return <Feed
feed_source_img={item.feed_source_img}
feed_source_txt={item.feed_source_txt}
question={item.question}
answer_ctnt={item.answer_ctnt}
good_num={item.good_num}
comment_num={item.comment_num}
key={index} />
})
6.4 Функция переключения вкладок «Страницы обнаружения»
Принцип переключения вкладок:Привязать к компонентуonClick
изменение событияthis.state.currentNavtab
значение, а затем реализовать через суждениеtab
Переключатель, метод передачи параметров функцииthis.switchTab.bind(this,index)
, конкретный код выглядит следующим образом:
export default class Discovery extends Component {
constructor() {
super(...arguments)
this.state = {
currentNavtab: 0,
navTab: ['推荐', '圆桌', '热门', '收藏'],
}
}
switchTab(index,e) {
this.setState({
currentNavtab: index
});
}
render () {
return (
<View>
<View className='top-tab flex-wrp flex-tab' >
{
this.state.navTab.map((item,index) => {
return (<View className={this.state.currentNavtab === index ? 'toptab flex-item active' : 'toptab flex-item' } key={index} onClick={this.switchTab.bind(this,index)}>
{item}
</View>)
})
}
</View>
<ScrollView scroll-y className='container discovery withtab'>
<View className='ctnt0' hidden={this.state.currentNavtab==0 ? false : true}>
...
</View>
<View className='txcenter' hidden={this.state.currentNavtab==1 ? false : true}>
<Text>圆桌</Text>
</View>
<View className='txcenter' hidden={this.state.currentNavtab==2 ? false : true}>
<Text>热门</Text>
</View>
<View className='txcenter' hidden={this.state.currentNavtab==3 ? false : true}>
<Text>收藏</Text>
</View>
</ScrollView>
</View>
)
}
}
6.5 Функция карусели
страница карусели используетсяSwiper
Компоненты, параметры и небольшие программы находятся во взаимно однозначном соответствии.Подробности можно посмотреть в подробной документации.В процессе рефакторинга основныеwxml
заменитьjsx
форма.
<Swiper className='activity' indicatorDots='true'
autoplay='true' interval='5000' duration='500'>
{this.state.imgUrls.map((item,index) => {
return (<SwiperItem key={index}>
<Image src={item} className='slide-image' width='355' height='375' />
</SwiperItem>)
})}
</Swiper>
7. Краткое описание проблем, обнаруженных при использовании
-
Taro
После того, как компоненты преобразованы в апплет WeChat и веб-сайт, метки меняются, напримерImage
компонент станетimage
илиimg
тег, поэтому не рекомендуется использовать имя тега для имени css, рекомендуется использовать класс напрямую - Текущая привязка события не поддерживает анонимные функции.
// 不支持
<View onClick={()=> this.navigateTo('/pages/answer/answer')} > </View>
-
Taro
Компоненты имеют много свойств и событий на веб-стороне, которые еще не поддерживаются. - В зависимости от операционной среды некоторые API должны обрабатываться по-разному в зависимости от среды, например
wx.getUserInfo
На веб-странице его нет, в настоящее время нам нужно оценить среду для выполнения кода.
if (Taro.getEnv() === Taro.ENV_TYPE.WEAPP) {
// 小程序环境
} else if (Taro.getEnv() === Taro.ENV_TYPE.WEB ) {
// WEB(H5)环境
}
-
Taro
В настоящее время не поддерживаетсяSVG
(ведь апплет его не поддерживает) В настоящее время сторонних библиотек все еще относительно немного (ведьTaro
Он только что вышел, я надеюсь, что в будущем сообщество выпустит различные библиотеки пользовательского интерфейса) -
Taro
Компонент в настоящее время не поддерживает чистые функции и не поддерживает присваивание деструктурирования.{...item}
8. Резюме
Перенести проект наTaro
Стоимость не высока, и большая часть работы заключается в преобразовании синтаксиса.Taro
использоватьReact
Метод написания апплета WeChat, общее впечатление очень хорошее, естьReact
Небольшие партнеры с опытом разработки считают, что они могут быстро приступить к работе. Удивительно, что один и тот же код может поддерживать как веб-сторону, так и апплет.Хотя текущая поддержка веб-стороны еще не улучшена, направление верное, и следующий шаг — лишь вопрос времени. ожидатьTaro
в следующем спектакле. Наконец, студенты, заинтересованные в проекте, могут загрузить код и запустить его.Адрес GitHub.