在 Taro 中,我們使用 JSX 作為一種 DSL 進(jìn)而編譯成各端通用的語法。 JSX 是一種看起來很像 XML 的 JavaScript 語法擴(kuò)展,比起模板語言,它具有以下優(yōu)點:
如果你是一名新手的話,可能一開始學(xué)習(xí)一種新語法會產(chǎn)生一些抵觸。但當(dāng)你熟悉了之后,就能發(fā)現(xiàn) JSX 更符合程序語言的書寫邏輯,在處理一些精細(xì)復(fù)雜需求的時候也會比模板語言更為得心應(yīng)手。
請觀察以下代碼:
import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'
class Home extends Component {
render () {
return (
<View>Hello World!</View>
)
}
}
在這段代碼中,大寫開頭的 JSX 標(biāo)簽 View 表示它是一個 Taro 組件,盡管在整段代碼中,變量 View 看起來并沒有被調(diào)用,但也必須從 @tarojs/components 中引入聲明。變量 Taro 也是一個必須引入聲明的變量,因為我們在編譯期和運行時會依賴這個變量做一些特殊處理。當(dāng)你引入了組件時,一定要使用,不要出現(xiàn)沒有使用的變量。
當(dāng)你只用支持微信小程序時,可以不用引入組件例如 View 這樣的聲明。但我們?nèi)匀粡?qiáng)烈推薦你在頂部引入你將要使用的組件,這樣編輯器/IDE 能更好地提前發(fā)現(xiàn)可能出現(xiàn)的問題,也為將來可能需要的多端轉(zhuǎn)換留有余地。
在 Taro 中,所有組件都應(yīng)當(dāng)首字母大寫并且使用大駝峰式命名法(Camel-Case)。
例如,下面的代碼將無法按預(yù)期運行:
import Taro, { Component } from '@tarojs/taro'
// 引入一個自定義組件組件
import home_page from './page'
// 錯誤!組件名應(yīng)該首字母大寫:
class App extends Component {
render () {
return (
<home_page message="Hello World!" />
)
}
}
為了解決這個問題,我們將 home_page 重命名為 HomePage,然后使用 <HomePage /> 引用:
import Taro, { Component } from '@tarojs/taro'
// 引入一個自定義組件組件
import HomePage from './page'
class App extends Component {
render () {
return (
<HomePage message="Hello World!" />
)
}
}
和 React/Nerv 不一樣的地方在于,Taro 不支持使用 點表示法 和運行時指定類型來引用組件,例如 這樣的寫法在 Taro 中是無法正確編譯的。
在 JSX 中有幾種不同的方式來指定屬性。
你可以任意地在 JSX 當(dāng)中使用 JavaScript 表達(dá)式,在 JSX 當(dāng)中的表達(dá)式要包含在大括號里。例如,在這個 JSX 中:
<MyComponent foo={1 + 2 + 3 + 4} />
對于 MyComponent 來說, props.foo 的值為 10,這是 1 + 2 + 3 + 4 表達(dá)式計算得出的。
if 語句和 for 循環(huán)在 JavaScript 中不是表達(dá)式,因此它們不能直接在 JSX 中使用,所以你可以將它們放在周圍的代碼中。
import Taro, { Component } from '@tarojs/taro'
class App extends Components {
render () {
let description
if (this.props.number % 2 == 0) {
description = <Text>even</Text>
} else {
description = <Text>odd</Text>
}
return <View>{this.props.number} is an {description} number</View>
}
}
你可以將字符串常量作為屬性值傳遞。下面這兩個 JSX 表達(dá)式是等價的:
<MyComponent message="hello world" />
<MyComponent message={'hello world'} />
如果你沒有給屬性傳值,它默認(rèn)為 true。因此下面兩個 JSX 是等價的:
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
和 React/Nerv 的不同: React 可以使用 ... 拓展操作符來傳遞屬性,但在 Taro 中你不能這么做。例如:const props = {firstName: 'Plus', lastName: 'Second'} return 這樣的操作會報錯。你只能手動地把所有需要引用的 props 寫上去:
如果 JSX 標(biāo)簽是閉合式的,那么你需要在結(jié)尾處用 />, 就好像 XML/HTML 一樣:
const element = <Image src={user.avatarUrl} />;
JSX 標(biāo)簽同樣可以相互嵌套:
const element = (
<View>
<Text>Hello!</Text>
<Text>Good to see you here.</Text>
</View>
)
JavaScript 表達(dá)式也可以嵌套:
render () {
const todos = ['finish doc', 'submit pr', 'nag dan to review'];
return (
<ul>
{todos.map((todo) => <Text>{todo}</Text>)}
</ul>
)
}
false、null、undefined 和 true 都是有效的 children,但它們不會直接被渲染。下面的表達(dá)式是等價的:
<View />
<View></View>
<View>{false}</View>
<View>{null}</View>
<View>{undefined}</View>
<View>{true}</View>
這在根據(jù)條件來確定是否渲染 元素時非常有用。以下的 JSX 只會在 showHeader 為 true 時渲染 <Header /> 組件。
<View>
{showHeader && <Header />}
<Content />
</View>
更多建議: