vue 與 jsx

零、序言

  6 月的時候冒出了用 jsx 的來寫 vue 項目的念頭,以回憶回憶放下好長一段時間的 jsx,奈何項目時間卡得很緊,一些簡單的頁面的還可以寫寫,遇到一些資料少的問題時就很頭疼,所以複雜頁面仍然採用 <template /> 的形式寫了過去。7 月時間沒那麼緊張,於是就把原來的一箇中等複雜度的子項目(jquery) 用 vue-jsx 重寫了遍。

  此文記錄在 vue 中寫 jsx 的幾處頭疼地方的處理。

 

參考資料:

  1.在Vue中使用JSX的正確姿勢;

  2.學Vue,就要學會 vue JSX 系列: && 作者主頁

 

一、v-model 的替換

  根據官網資料, v-model="variable"  這種形式是(官方提供)一種簡寫,因此,在 jsx 中我們就不能使用了(不過好像有 babel 插件支持),那麼還原成一般的寫法就是:

<el-input 
    value={this.oldPass.value}  // value - props 
    onInput={e => this.handleInput(e)} // onInput - this.$emit
    ...
></el-input>

// 需要注意的是,我這裏直接用的 element-ui 組件,因此 e 就是輸入事件中的值,如果用的是原生的 input 標籤, 這個 e 會是整個輸入事件(對象),諸位可以在 handleInput 中打印看看。

 

二、自定指令

  當初最大的攔路虎就是這個自定指令如何插入到具體代碼中去。6 月份找資料的時候 資料2 還沒有出來,所以當初並沒有完全用 jsx 寫項目。

  因此,在 jsx 中,對於 ElementUI 中的 v-loading 指令, 我們可以這樣操作:

data() {
    tableLoading: false,
}

render(h) {
    /**
     * 一個組件上面可以使用多個指令,所以是一個數組
     * name 對應指令的名稱, 需要去掉 v- 前綴
     * value 對應 `v-loading="value"`中的value
     */
  const directives = [{ name: 'loading', value: this.tableLoading }]
  return (
    <div {...{ directives }}></div>
  )
}

// 如果需要修飾符,則
render(h) {
    /**
     * modifiers指定修飾符,如果使用某一個修飾符,則指定這個修飾符的值爲 true
     * 不使用可以設置爲false或者直接刪掉
     */
  const directives = [
    {
      name: 'loading',
      value: this.loading,
      modifiers: { fullscreen: true, lock: false }
    }
  ]
  return (
    <div {...{ directives }}></div>
  )
}

 

三、事件

1.  常規(原生)事件:

  如第一條中的 input 事件, 在 jsx 中一般需要寫成  onEvent  的形式, 並採用駝峯命名規則,如 onChange 等, 或者寫成  on-event  的形式;

2. 自定義的(組件)事件:

  我們自定的組件,在內部通過 this.$emit 來向上提交事件及參數,在 <template /> 中,只需要加上  @  即可,而在 jsx 中,則建議寫成  on-event  這樣的形式。

 

四、屬性的綁定

1. 常規屬性

  大部分屬性的綁定由原來的  :key="false"  這種形式變成了  key={false}  這樣。

2. 傳遞函數

  有時,我們也會通過 props 傳遞一些自定的函數以在子組件的某個運行期間執行某些操作,大多數時候,函數的傳遞和常規屬性的傳遞一樣,沒啥需要注意的,但是當遇到以 on 開頭的函數屬性時,我們就不能採用  key={this.onEvent}  這種形式,原因可在參考資料的那篇文章中找到。

  因此,我們應該採用下面的形式(以 ElementUI 中的 Upload 爲例 ):

<el-upload
    action={this.upLoadApiUrl}
    data={this.uploadData}
    show-file-list={false}
    
    // 因爲是以 before 開頭的而非以 on 開頭的屬性,故編譯時會當成 props 處理
    before-upload={ this.beforeImgUpload }

    // 這裏是重點
    {...{ props: { onSuccess: this.handleImgSuccess, onError: this.handleImgError } }}
>
    ...
</el-upload>

/**
*  on-success && on-error 是 ElementUI 文檔中提供的 Attribute,
*  在 <template /> 形式中, 我們只需要按照 :on-success="handleSuccess" 這樣的形式來處理即可,
*  而在 render(h) {...} 這種方法下, 我們必須以上面代碼中所示的那樣,指明其是作爲 props 屬性傳遞的,避免被解析成自定義的事件。
*/

 

五、最後

  參考資料中的一些點沒有完全涉及到, 如有興趣,請移步至相應文章。

  零零散散的資料與實踐, 如有錯誤,望斧正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章