摘要:作為兩個小程序開發框架都使用過,并應用在生產環境里的人,自然是要比較一下兩者的異同點。在這里與當前很流行的小程序開發框架之一進行簡單對比,主要還是為了方便大家更快速地了解,從而選擇更適合自己的開發方式。
前言
前陣子,來自我們凹凸實驗室的遵循 React 語法規范的多端開發方案 - Taro終于對外開源了,歡迎圍觀star(先打波廣告)。作為第一批使用了Taro開發的TOPLIFE小程序的開發人員之一,自然是走了不少彎路,躺了不少坑,也幫忙找過不少bug。現在項目總算是上線了,那么,也是時候給大家總結分享下了。
與wepy比較當初開發TOPLIFE第一期的時候,用的其實是wepy(那時Taro還沒有開發完成),然后在第二期才全面轉換為用Taro開發。作為兩個小程序開發框架都使用過,并應用在生產環境里的人,自然是要比較一下兩者的異同點。
相同點組件化開發
npm包支持
ES6+特性支持,Promise,Async Functions等
CSS預編譯器支持,Sass/Stylus/PostCSS等
支持使用Redux進行狀態管理
…..
相同的地方也不用多說什么,都2018年了,這些特性的支持都是為了讓小程序開發變得更現代,更工程化,重點是區別之處
不同點開發風格
實現原理
wepy支持slot,taro暫不支持直接渲染children
開發風格
最大的不同之處,自然就是開發風格上的差異,wepy使用的是類Vue開發風格, Taro使用的是類React開發風格,可以說開發體驗上還是會有較大的區別。貼一下官方的demo簡單闡述下
wepy demo
view(class="container") view(class="userinfo" @tap="tap") mycom(:prop.sync="myprop" @fn.user="myevent") text {{now}}
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 () } } {this.state.title} {this.state.list.map(item => { return ( {item} ) })}
可以見到在wepy里,css、template、script都放在一個wepy文件里,template還支持多種模板引擎語法,然后支持computed、watcher等屬性,這些都是典型的vue風格
而在taro里,就是徹頭徹尾的react風格,包括constructor,componentWillMount、componentDidMount等各種react的生命周期函數,還有return里返回的jsx,熟悉react的人上手起來可以說是非常快了
除此之外還有一些細微的差異之處:
wepy里的模板,或者說是wxml,用的都是小程序里原生的組件,就是小程序文檔里的各種組件;而taro里使用的每個組件,都需要從@tarojs/components里引入,包括View,Text等基礎組件(這種做其實是為了轉換多端做準備)
事件處理上
taro中,是用click事件代替tap事件
wepy使用的是簡寫的寫法@+事件;而taro則是on+事件名稱
阻止冒泡上wepy用的是@+事件.stop;而taro則是要顯式地使用e.stopPropagation()來阻止冒泡
事件傳參wepy可以直接在函數后面傳參,如@tap="click({{index}})";而taro則是使用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
比較常見的一種項目目錄組織方式,相比初始模板多了幾個文件夾,用于存放redux相關的內容及其他的一些東西,整個項目結構相信還是比較直觀,簡單明了的
更好地使用reduxredux大家應該都不陌生,一種狀態管理的庫,通常會搭配一些中間件使用。我們的項目主要是用了redux-thunk和redux-logger中間件,一個用于處理異步請求,一個用于調試,追蹤actions
相信大家都遇到過這種時候,接口返回的數據和頁面顯示的數據并不是完全對應的,往往需要再做一層預處理。那么這個業務邏輯應該在哪里管理,是組件內部,還是redux的流程里?
舉個例子:
例如上圖的購物車模塊,接口返回的數據是
{ 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: {...}, // 對應商品信息 }, ...] }
可以見到,處理數據的流程在render前被攔截處理了,將對應的商品店鋪和商品放在了一個對象了.
這樣做有幾個好處
一個是組件的渲染更純粹,在組件內部不用再關心如何將數據修修改改而滿足視圖要求,只需關心組件本身的邏輯,例如點擊事件,用戶交互等
二是數據的流動更可控,假如后續后臺返回的數據有變動,我們要做的只是改變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 &&}
上面是很普通的一種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 &&}
可以見到,在connect里定義了isShowCoupon變量,實現了根據couponData來進行computed的效果
實際上,這也是一種數據攔截處理。除了computed,還可以實現其它的功能,具體就由各位看官自由發揮了
一些需要注意的地方那taro,或者是小程序開發,有沒有什么要注意的地方?當然有,走過的彎路可以說是非常多了
估計是每個頁面的數據在小程序內部都有緩存,所以做了10層的限制。帶來的問題就是假如頁面存在循環跳轉,即A頁面可以跳到B頁面,B頁面也可以跳到A頁面,然后用戶從A進入了B,想返回A的時候,往往是直接在B頁面里點擊跳轉到A,而不是點返回回到A,如此一來,10層很快就突破了。所以我們自己對navigateTo函數做了一層封裝,防止溢出
上面說到,頁面內容有緩存。所以假如某個頁面是根據不同的數據渲染視圖,新渲染時會有上一次渲染的緩存,導致頁面看起來有個閃爍的變化,用戶體驗非常不好。其實解決的辦法也很簡單,每次在componentWillUnmount生命周期中清理一下當前頁面的數據就好了。小程序說到底不是h5,不會說每次進入頁面就會刷新,也不會離開就銷毀,刷新,清理數據的動作都需要自己再生命周期函數里主動觸發
頁面的滾動事件只能通過onPageScroll來監聽,所以當我想在組件里進監聽操作時,要將該部分的邏輯提前到onPageScroll函數,提高了抽象成本。例如我需要開發一個滾動到某個位置就吸頂的tab,本來可以在tab內部處理的邏輯被提前了,減少了其可復用性
本來也想詳細描述下的,不過在我們幾位大佬的努力,加班加點下,已經開發出eslint插件,及補充完整了taro文檔。大家只要遵循eslint插件規范,查看文檔,應該不會有太大問題,有問題歡迎提issue
總結總的來說,用taro來開發小程序體驗還是很不錯的,最重要的是,可以使用jsx寫小程序了!!!作為react粉的一員,可以說是相當的興奮了~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95813.html
摘要:多端統一開發框架優秀學習資源匯總官方資源項目倉庫官方文檔項目倉庫官方文檔微信小程序官方文檔百度智能小程序官方文檔支付寶小程序官方文檔字節跳動小程序官方文檔文章教程不敢閱讀包源碼帶你揭秘背后的哲學從到構建適配不同端微信小程序等的應用小程序最 Awesome Taro 多端統一開發框架 Taro 優秀學習資源匯總 showImg(https://segmentfault.com/img/r...
摘要:所以在小程序出現之后,一股框架之風也很快的出現,微信小程序剛推出之后,就出現了兩個比較出名的小程序開發框架,。 原文地址:https://ant-move.github.io/we... 這里說的去除小程序框架其實并不嚴謹,因為小程序本身也算是一個框架,而且是一個功能更加完善的框架系統。在前端的概念中,我們一般說一個框架是指一個用來幫助開發者構建用戶界面的框架,而小程序框架本身不僅僅包...
摘要:前言是一個可以很好實現一次開發,多端統一的框架,本文只介紹它小程序端開發的一些內容。 前言:taro是一個可以很好實現一次開發,多端統一的框架,本文只介紹它小程序端開發的一些內容。小程序項目搭建gitup已經有很清楚的說明:https://github.com/NervJS/taro 一.主要操作步驟及命令: 1.cnpm install -g @tarojs/cli 全局安裝taro...
閱讀 1246·2021-09-04 16:41
閱讀 2403·2021-09-02 10:18
閱讀 917·2019-08-29 16:40
閱讀 2614·2019-08-29 16:14
閱讀 898·2019-08-26 13:41
閱讀 1299·2019-08-26 12:24
閱讀 731·2019-08-26 10:24
閱讀 2869·2019-08-23 17:54