介紹

2020-04-28 10:19 更新

跨平臺(tái)開(kāi)發(fā)的挑戰(zhàn)

小程序作為一項(xiàng)非標(biāo)準(zhǔn)的技術(shù),各個(gè)小程序平臺(tái)之間雖然大體上相似,但依然有非常多的差異?!耙淮伍_(kāi)發(fā)多端運(yùn)行”當(dāng)然是非常美好的愿望,但我們?cè)谠O(shè)計(jì) Remax 之初就意識(shí)到各個(gè)小程序平臺(tái)之間的差異是無(wú)法被抹平的,因?yàn)闆](méi)有一個(gè)標(biāo)準(zhǔn)來(lái)指導(dǎo)我們?cè)撊绾文ㄆ竭@些差異。

所以我們?cè)谧铋_(kāi)始,為每個(gè)小程序平臺(tái)提供了獨(dú)立的基礎(chǔ)組件。開(kāi)發(fā)者如果要做跨平臺(tái)開(kāi)發(fā),需要自己去封裝基礎(chǔ)組件。但很快,我們也意識(shí)到這對(duì)開(kāi)發(fā)者來(lái)說(shuō)是一件很麻煩的事情,特別是后面我們要支持更多平臺(tái)的話。

受 CSS 屬性名前綴的啟發(fā),我們重新設(shè)計(jì)了 Remax 的跨平臺(tái)方案。我們非??酥频剡x取了 9 個(gè)基礎(chǔ)組件,抹平了他們之間非平臺(tái)私有的屬性,并且以屬性名前綴的方式來(lái)支持各個(gè)平臺(tái)私有的特性。我們希望開(kāi)發(fā)者在做跨平臺(tái)開(kāi)發(fā)時(shí)能清楚地意識(shí)到你寫(xiě)下的這行代碼只會(huì)在特定的平臺(tái)上生效。

Remax One

Remax One 就是我們提供的跨平臺(tái)解決方案。通過(guò) remax/one 我們提供了跨平臺(tái)的組件。

import * as React from 'react';
import { View, Button } from 'remax/one';
export default () => {
const [count, setCount] = React.useState(0);
return (
<View alipay-onAppear={() => console.log('Aha!')}>
<View>{count}</View>
<Button onTap={() => setCount(count + 1)}>+1</Button>
</View>
);
};

可以看到,對(duì)于 onTap 這樣通用的屬性我們進(jìn)行了統(tǒng)一,而支付寶獨(dú)有的 onAppear 屬性,則需要加上 alipay- 的前綴。

remax/one 是 1.19.0 以后引入的特性。

使用

從模板創(chuàng)建:

$ npx degit remaxjs/template-one my-app
$ cd my-app

或者在已有的項(xiàng)目中引入:

在 remax.config.js 中設(shè)置 one: true 來(lái)開(kāi)啟 Remax One。

// remax.config.js
module.export = {
one: true,
// 通過(guò)環(huán)境變量區(qū)分不同平臺(tái)的輸出目錄
output: 'dist/' + process.env.REMAX_PLATFORM,
};

小程序配置

app.config.js 以及頁(yè)面的 config.js 配置文件支持多端配置方式:

// app.config.js
const title = '小程序標(biāo)題';
const bgColor = '#fff';
const pages = ['pages/index/index'];
// 支付寶
exports.alipay = {
pages: ['pages/alipay/index', ...pages],
window: {
defaultTitle: 'Alipay Todo App',
titleBarColor: backgroundColor,
},
};
// 微信
exports.wechat = {
pages: ['pages/wechat/index', ...pages],
window: {
navigationBarTitleText: title,
navigationBarBackgroundColor: backgroundColor,
},
};

如果沒(méi)有默認(rèn)導(dǎo)出,remax-cli 就會(huì)去讀取對(duì)應(yīng)平臺(tái)的配置信息。

使用文件名后綴區(qū)分不同平臺(tái)代碼

你可以通過(guò)創(chuàng)建不同平臺(tái)的同名文件來(lái)封裝跨平臺(tái)組件和 API。例如:

// src/api/showToast/index.js
import { showToast } from 'remax/alipay';
export default showToast;
// src/api/showToast/index.wechat.js
import { showToast } from 'remax/wechat';
export default options => {
showToast({
...options,
title: options.content,
});
};
// src/pages/index.js
import { View } from 'remax-one';
import showToast from '@/api/showToast';
export default () => {
return (
<View
onClick={() => {
showToast({ content: 'Hello World!' });
}}
>
CLICK ME!
</View>
);
};

remax-cli 會(huì)優(yōu)先讀取 [target].js 文件,這個(gè)規(guī)則針對(duì) CSS 等其他文件同樣有效。

注意:上面的例子中的 src/api/showToast/index.js 是必須的,也就是說(shuō)不能只提供帶有平臺(tái)后綴的文件。

組件

如上面所說(shuō),我們非??酥浦?jǐn)慎地對(duì) remax/one 中提供的組件做了篩選和重新設(shè)計(jì),只保留了我們能保證在各個(gè)平臺(tái)之間行為一致的組件和屬性。

如果需要使用某個(gè)平臺(tái)特有的組件,可以直接從對(duì)應(yīng)平臺(tái)導(dǎo)入。如:

import * as React from 'react';
import { View, Text } from 'remax/one';
import { ScrollView } from 'remax/wechat';
export default () => {
return (
<ScrollView>
<View>view</View>
<Text>text</Text>
</ScrollView>
);
};

如果需要使用某個(gè)平臺(tái)特有的屬性,可以通過(guò) {平臺(tái)前綴}-{平臺(tái)原生屬性名稱} 來(lái)設(shè)置,例如:

import * as React from 'react';
import { View, TapEvent } from 'remax-one';
export default () => {
return (
<View
id="id"
className="class"
alipay-onAppear={() => {}}
wechat-bindanimationend={() => {}}
wechat-disable-scroll={true}
onTap={(event: TapEvent) => {
console.log(event);
}}
>
view
</View>
);
};


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)