React與Vue模板使用比較(一、vue模板與React JSX比較)

barretem發表於2019-03-05

前言

本人原為React開發者,現在轉戰Vue。在這些天接觸Vue的日子裡,說說自己的感覺:同樣的登山活動,React就像父親,給你必要的登山工具就讓你出發了;Vue就像母親,在你登山之前為你準備好了所有東西,嘮嘮叨叨了一波,規劃了路線,給了你厚厚的導航指南,才讓你出發。

本文目的

  • 方便React開發者更快的上手Vue
  • 進行更加詳盡的React以及Vue的開發體驗比較

目標人群

有一定的React開發經驗,正在並行使用Vue的開發者

問題

  1. Vue的模板跟React中使用的jsx有什麼區別?
  2. 如何在React中實現Vue模板上帶有的功能?

vue模板與JSX比較

1. 表示式(expressions)

JSX表示式用{}包裹,vue模板表示式用{{}}包裹,其餘一致.

vue模板表示式:

表示式

程式碼比較:


<!--vue-->
<template>
    <div>
      <p>I have a {{ product }}</p>
      <p>{{ product + 's' }}</p>
      <p>{{ isWorking ? 'YES' : 'NO' }}</p>
      <p>{{ product.getSalePrice() }}</p>
    </div>
</template>

<!--react-->
<div>
    <p>I have a { product }</p>
    <p>{ product + 's' }</p>
    <p>{ isWorking ? 'YES' : 'NO' }</p>
    <p>{ product.getSalePrice() }</p>
</div>
複製程式碼

2.指令(directives)

Vue模板:小夥子,用你的頭髮記好了,有如下指令:

Vue模板指令:

Vue模板指令

JSX:啥啥啥,你自己實現不就好了嗎。。。

  • v-if, v-else-if, v-else JSX直接用萬能的三元表示式
  • v-show JSX在dom上新增如下程式碼,實現一樣的功能
style={ifShow ?{} : { display: 'none' }}
複製程式碼
  • v-model JSX在對應的dom上繫結事件,事件裡面自己愛怎麼處理怎麼處理

程式碼比較:

<!--vue指令-->
  <template>
    <div>
      <p v-if="container1">你現在看到container1了</p>
      <p v-else-if="container2">你現在看到container2了</p>
      <p v-else>你現在看到default了</p>
      <p v-show="ifShow">影響顯示的p</p>
      <input type="text" v-model="inputText"/>
    </div>
  </template>
  
  <!--react指令-->
  <div>
    {
      container1 ?
        <p>你現在看到container1了</p> :
        container2 ?
          <p>你現在看到container2了</p> :
        <p>你現在看到default了</p>
    }
    <p style={{display: ifShow ? 'block' : 'none'}}></p>
    <input type="text" onChange={val => () => {this.setState{inputText:val}}} 
           value={this.state.inputText}/>
  </div>
複製程式碼

3. 列表渲染(list rendering)

Vue模板列表渲染:v-for React JSX: 直接在dom中插入map函式,裡面直接用js來處理引數

<!--vue-->
  <template>
    <ul>
      <li v-for="(item, i) in list" :key="item.id">{{item.text}}</li>
    </ul>
  </template>
  
  <!--react-->
  <div>
    <ul>
      {
        list.map((item, i) => <li key={item.id}>{item.text}</li>)
      }
    </ul>
  </div>
複製程式碼

4. 繫結(binding)

繫結其實就是元件的傳參,通過繫結,將對應的引數傳遞到子元件。常見的繫結有:1、普通屬性繫結;2、style屬性繫結,3、class屬性繫結; Vue的資料繫結:

繫結(binding)
React JSX: 呵呵,style不是屬性啊?class不是屬性啊?弄那麼複雜幹嘛?!什麼?你們說我們style不支援陣列?你將陣列轉換成物件就好了嗎?你說我們class不支援物件以及陣列?classnames庫瞭解一下。

<!--vue繫結-->
<ul>
  <li :type="liType"></li>
  <!--style支援陣列傳入-->
  <li :style="[{backgroundColor: '#fff'}]"></li>
  <!--style支援物件傳入 如果變數active為true則新增對應的'active'類-->
  <li :style="{active}"></li>
  <!--class支援陣列傳入 如果變數active為true則新增對應的'active'類-->
  <li :class="[active]"></li>
  <!--class支援物件傳入 如果變數active為true則新增對應的'active'類-->
  <li :class="{active}"></li>
</ul>
<!--react繫結-->
<ul>
  <li type={liType}></li>
  <!--style需要支援陣列傳入??自己用函式(將陣列轉為物件)處理吧-->
  <li style={this.arrayToObj([{backgroundColor: '#fff'}])}></li>
  <!--style支援物件傳入-->
  <li style={{backgroundColor: '#fff'}}></li>
  <!--class需要支援陣列傳入??自己用函式處理吧,函式都懶得寫?classnames庫瞭解一下-->
  <li className={this.arrayToString([{backgroundColor: '#fff'}])}></li>
  <!--class需要支援物件傳入??自己用函式處理吧,函式都懶得寫?classnames庫瞭解一下-->
  <li className={classnames({active})}></li>
</ul>
複製程式碼

5. 事件處理(actions/events)

Vue模板:記住了,有以下事件處理

Vue模板事件處理
JSX:跟js事件名稱一致,直接放置在對應的節點進行事件繫結就好

<!--vue-->
  <template>
    <button v-on:click="handleBtn">我是一個點選按鈕</button>
  </template>
  
  <!--react-->
  <div>
    <button onClick={this.handleBtn}>我是一個點選按鈕</button>
  </div>
複製程式碼

總結

Vue模板與JSX的基本使用比較完了,Vue模板為你考慮了很多優化的東西,你只需要記住其中的規則就好,更大的降低了技術門檻。而JSX將更大的控制權留給了程式碼編寫者。

更新

  • 2019.03.06 17:29 將v-model.lazy的作用更正為:“當輸入框失去焦點後觸發change事件,才會更改對應的繫結值”(感謝“朝陽群眾-Leo”的指正)
  • 2019.03.07 12:51 將“style={{ display: ifShow ? 'block':'none' }}”更正為“style={ifShow ?{} : { display: 'none' }}”--需要考慮元素原來的display屬性,原來的方式會將原有的display屬性覆蓋,可能會影響佈局(感謝“Weijuer”的指正)

相關文章