JSX 簡介

2020-05-12 17:46 更新

在 Taro 中,我們使用 JSX 作為一種 DSL 進(jìn)而編譯成各端通用的語法。 JSX 是一種看起來很像 XML 的 JavaScript 語法擴(kuò)展,比起模板語言,它具有以下優(yōu)點:

  1. 各大編輯器和 IDE 都能提供非常良好的支持;
  2. 可以做到類型安全,在編譯期就能發(fā)現(xiàn)錯誤;
  3. 提供語義化并且可以移動的標(biāo)簽;
  4. 背后的社區(qū)支持非常強(qiáng)力;

如果你是一名新手的話,可能一開始學(xué)習(xí)一種新語法會產(chǎn)生一些抵觸。但當(dāng)你熟悉了之后,就能發(fā)現(xiàn) JSX 更符合程序語言的書寫邏輯,在處理一些精細(xì)復(fù)雜需求的時候也會比模板語言更為得心應(yīng)手。

使用 JSX

請觀察以下代碼:

import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'

class Home extends Component {
  render () {
    return (
      <View>Hello World!</View>
    )
  }
}

必須聲明 Taro 和組件

在這段代碼中,大寫開頭的 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 中有幾種不同的方式來指定屬性。

使用 JavaScript 表達(dá)式

你可以任意地在 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

如果你沒有給屬性傳值,它默認(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>
  )
}

布爾值、Null 和 Undefined 被忽略

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>


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號