事件處理

2020-05-12 17:46 更新

Taro 元素的事件處理和 DOM 元素的很相似。但是有一點(diǎn)語(yǔ)法上的不同:

Taro 事件綁定屬性的命名采用駝峰式寫(xiě)法,而不是小寫(xiě)。 如果采用 JSX 的語(yǔ)法你需要傳入一個(gè)函數(shù)作為事件處理函數(shù),而不是一個(gè)字符串 (DOM 元素的寫(xiě)法)。 例如,傳統(tǒng)的微信小程序模板:

<button onclick="activateLasers">
  Activate Lasers
</button>

Taro 中稍稍有點(diǎn)不同:

<button onClick={this.activateLasers}>
  Activate Lasers
</button>

在 Taro 中另一個(gè)不同是你不能使用 catchEvent 的方式阻止事件冒泡。你必須明確的使用 stopPropagation。例如,阻止事件冒泡你可以這樣寫(xiě):

class Toggle extends Component {
  constructor (props) {
    super(props)
    this.state = {isToggleOn: true}
  }

  onClick = (e) => {
    e.stopPropagation()
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }))
  }

  render () {
    return (
      <button onClick={this.onClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    )
  }
}

向事件處理程序傳遞參數(shù)

通常我們會(huì)為事件處理程序傳遞額外的參數(shù)。例如,傳入欲刪除行的 id:

<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

當(dāng)你通過(guò) bind 方式向監(jiān)聽(tīng)函數(shù)傳參,在類組件中定義的監(jiān)聽(tīng)函數(shù),事件對(duì)象 e 要排在所傳遞參數(shù)的后面。

class Popper extends Component {
  constructor () {
    super(...arguments)
    this.state = { name:'Hello world!' }
  }

  // 你可以通過(guò) bind 傳入多個(gè)參數(shù)
  preventPop (name, test, e) {    //事件對(duì)象 e 要放在最后
    e.stopPropagation()
  }

  render () {
    return <Button onClick={this.preventPop.bind(this, this.state.name, 'test')}></Button>
  }
}

使用匿名函數(shù)

自 v1.2.9 開(kāi)始支持
注意:在各小程序端,使用匿名函數(shù),尤其是在 循環(huán)中 使用匿名函數(shù),比使用 bind 進(jìn)行事件傳參占用更大的內(nèi)存,速度也會(huì)更慢。

除了 bind 之外,事件參數(shù)也可以使用匿名函數(shù)進(jìn)行傳參。直接寫(xiě)匿名函數(shù)不會(huì)打亂原有監(jiān)聽(tīng)函數(shù)的參數(shù)順序:

class Popper extends Component {
  constructor () {
    super(...arguments)
    this.state = { name: 'Hello world!' }
  }

  render () {
    const name = 'test'
    return (
      <Button onClick={(e) => {
        e.stopPropagation()
        this.setState({
          name
        })
      }}>
        {this.state.name}
      </Button>
    )
  }
}
注意: 使用通過(guò) usingComponents 的第三方組件不支持匿名函數(shù)

柯里化

自 v1.3.0-beta.1 開(kāi)始支持
在各小程序端,使用柯里化 Taro 會(huì)在編譯后多生成一個(gè)匿名函數(shù)。

除了 bind 和匿名函數(shù)之外,事件參數(shù)也可以使用柯里化傳參。

class Title extends Component{

  handleClick = (index) => (e) => {
    e.stopPropagation()
    this.setState({
      currentIndex: index
    })
  }

  render() {
    const { currentIndex } = this.props;
    return (
      {/* 調(diào)用 `this.handleClick(currentIndex)` 會(huì)返回一個(gè)函數(shù),這個(gè)函數(shù)可以訪問(wèn)到 `currentIndex` 同時(shí)也能滿足 `onClick` 的簽名 */}
      <View onClick={this.handleClick(currentIndex)}>
      </View>
    )
  }
 }
注意: 使用通過(guò) usingComponents 的第三方組件不支持匿名函數(shù)

函數(shù)式組件

在函數(shù)式組件中,事件傳參可以傳入事件的引用也可以傳入匿名函數(shù),以下是函數(shù)式組件配合 useCallback 的一個(gè)例子:

const App = () => {
  const [c1, setC1] = useState(0);
  const [c2, setC2] = useState(0);
  const [c3, setC3] = useState(0);

  const increment = c => c + 1

  // 只有 useCallback 對(duì)應(yīng)的 c1 或 c2 的值改變時(shí),才會(huì)返回新的函數(shù)
  const increment1 = useCallback(() => setC1(increment), [c1]);
  const increment2 = useCallback(() => setC2(increment), [c2]);

  return (<View>
    <Text> Counter 1 is {c1} </Text>
    <Text> Counter 2 is {c2} </Text>
    <Text> Counter 3 is {c3} </Text>
    <View>
      <Button onClick={increment1}>Increment Counter 1</Button>
      <Button onClick={increment2}>Increment Counter 2</Button>
      <Button onClick={() => setC3(increment)}>Increment Counter 3</Button>
    </View>
  </View>)
}

任何組件的事件傳遞都要以 on 開(kāi)頭

在 v1.3.0-beta.0 之后,自定義組件間的事件傳遞可以不用 on 開(kāi)頭,但內(nèi)置組件的事件依然是以 on 開(kāi)頭的,為了一致性我們?nèi)匀煌扑]你以 on 開(kāi)頭命名你的事件。

在微信小程序中,可能你會(huì)看到像 bindTap 這樣的用法,但在 Taro 中,事件參數(shù)(props)都以 on 開(kāi)頭:

// 錯(cuò)誤
const element = <View bindtap={this.onTag} />
const element2 = <Input bindfocus={this.onFocus} />
const element3 = <CustomElement animationEnd={this.props.onAnimationEnd} />

只要當(dāng) JSX 組件傳入的參數(shù)是函數(shù),參數(shù)名就必須以 on 開(kāi)頭:

// 正確
const element = <View onClick={this.onTag} />
const element2 = <Input onFocus={this.onFocus} />
const element3 = <CustomElement onAnimationEnd={this.props.onAnimationEnd} />


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

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)