白話說框架

robin發表於2020-11-22

如果你只會使用 Vue 或者 React,那麼這篇文章適合你。

本文不深入聊原理,只對比基礎功能的使用,先看下面這份資料,百度搜尋指數,很明顯 Vue 搜尋指數明顯高於 React 以及 Angular。

從簡單學起沒問題,你以為的技術之路這樣的

其實你是這樣的

想想自己除了 Vue, 你還有什麼?寫此文的目的就是讓大家領悟到使用框架的方法和技巧。

下面是擷取 react 與 vue 官方文件目錄,共通的基礎功能至少包含 9 項

  • 資料繫結
  • 模板
  • 條件
  • 列表
  • 表單繫結
  • 事件處理
  • 生命週期
  • 元件

以上包含了當下流行框架基本必備功能,先不去想框架具體實現細節,就以上七個功能,在不手動操作 DOM 的情況下如何實現?

三大框架都藉助 MVVM 的思想,其優勢就是擺脫手動操作 DOM 及節點資料獲取帶來的低效問題,往下看

MVVM

MVVM 旨在利用資料繫結函式,通過 ViewModal 自動去更新 DOM 的狀態,進而從檢視層中幾乎刪除所有 GUI 程式碼。

既然大家都受到 VM 思想的啟發,且基礎功能都大致相似,我們逐一對比 Vue 及 React 的基礎功能

資料繫結

vue 雙向繫結,react 單向繫結,程式碼比較

// vue

// 該物件被加入到一個 Vue 例項中
var vm = new Vue({
  data: { a: 1 },
  created: function () {
    this.a = 2;
  },
});

// react
var data = { a: 1 };
class HelloWorld extends React.Component {
  constructor(props) {
    super(props);
    this.state = { a: 1 };
  }

  componentDidMount() {
    // 須通過方法觸發
    this.setState({
      a: 2,
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
      </div>
    );
  }
}

ReactDOM.render(<HelloWorld />, document.getElementById("root"));

模板

  • 表示式
    JSX 用 {} ,vue 用 {{}}, 程式碼比較

    // vue
    <template>
        <div>
            <span>{{name}}</span>
            <span>{{name + 'abc'}}</span>
            <span>{{`${name}abc`}}</span>
            <span>{{isShow?'abc':'efg'}}</span>
            <span>{{()=>{return 'abc'})}}</span>
        </div>
    </template>
    
    // react
    <div>
        <span>{name}</span>
        <span>{name + 'abc'}</span>
        <span>{`${name}abc`}</span>
        <span>{isShow?'abc':'efg'}</span>
        <span>{()=>{return 'abc'})}</span>
    </div>
  • 指令

    vue 指令 v-ifv-else-ifv-elsev-showv-modal
    react 無指令

    程式碼比較

      // vue
      <template>
          <div>
              <p v-if="isA">我是A</p>
              <p v-else-if="isB">我是B</p>
              <p v-else>我是C</p>
              <p v-show="isShow">大魔王現世了</p>
              <input type="text" v-model="inputText"/>
              <ul>
                  <li v-for="(item, i) in list" :key="item.id">{{item.text}}</li>
              </ul>
          </div>
      </template>
    
      // react
      <div>
          {
              isA ?
              <p>我是A</p> :
              isB ?
              <p>我是B</p> :
              <p>我是C</p>
          }
          <p style={{display: isShow ? 'block' : 'none'}}>大魔王現世了</p>
          <input type="text" onChange={val => () => {this.setState({inputText:val})}
              value={this.state.inputText}/>
          <div className='btn' style={{marginLeft:'10px'}}></div>
          <ul>
              {
                  list.map((item, i) => <li key={item.id}>{item.text}</li>)
              }
          </ul>
      </div>

    有沒有發現 react 中透漏著表示式的芬芳,這也是我個人喜歡 react 的原因

  • 屬性
    繫結也就相當於元件傳參,方便把需要自定義的引數傳遞到子元件中,常見的繫結有:屬性繫結、class、style

    程式碼比較

      // vue
    
      // 仔細看了文件才看懂什麼意思,active 是 class, isActive是判斷條件,
      <div v-bind:class="{ active: isActive }"></div>
      <div
          class="static"
          v-bind:class="{ active: isActive, 'text-danger': hasError }"
      ></div>
      <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
      // react
      <div className={`static ${isActive?:'active':''}`}></div>
      <div style={{color: activeColor, fontSize: fontSize + 'px'}}></div>

    細品,表示式的芬芳

表單繫結

vue 用 v-modal,react 用 onChange, 程式碼比較

// vue
<input v-model="userName" />
<input v-bind:value="userName" v-on:input="userName = $event.target.value" />
第一行的程式碼其實只是第二行的語法糖。input 元素本身有個 oninput事件,這是 HTML5
新增加的,類似 onchange ,每當輸入框內容發生變化,就會觸發 oninput。

// react
<input value={userName} onChange={($event=>this.setState({userName:
$event.target.value}))}>

事件處理

vue 通過 v-on:*,react 通過 on*, 程式碼比較

// vue
<div id="example-2">
  <!-- `greet` 是在下面定義的方法名 -->
  <button v-on:click="greet">Greet</button>
</div>

var example = new Vue({
  el: "#example",
  data: {
    name: "Vue.js",
  },
  // 在 `methods` 物件中定義方法
  methods: {
    greet: function (event) {
      // `this` 在方法裡指向當前 Vue 例項
      alert("Hello " + this.name + "!");
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName);
      }
    },
  },
});

//react
class example extends Component {
  constructor(props) {
    super(props);
    this.state = { name: "React.js" };
  }

  greet(event) {
    // `this` 在方法裡指向當前 Vue 例項
    alert("Hello " + this.state.name + "!");
    // `event` 是原生 DOM 事件
    if (event) {
      alert(event.target.tagName);
    }
  }
  render() {
      <button onClick={this.greet}>Greet</button>
  }
}

生命週期

生命週期的存在,也是為了在合適的時機執行各自的操作,再加上使用 virtual DOM 的機制,需要把握好元件掛載的時機,生命週期鉤子就顯得非常有必要了。

不管是 vue 還是 react,生命週期都會經歷以下階段:

  • 初始化階段
  • 執行階段
  • 銷燬階段

vue

react(v16.3 版本之前,之後版本生命週期有所調整)

元件

元件的複用的高效不言而喻,元件設計、元件劃分,也是一門學問

vue 元件的介紹,花樣很多

react 元件

總結

通過對兩大框架基礎功能的對比,不難發現實現思路大同小異,只是在細節上各有各的考慮,其中 Vue 自定義了很多 api,而 react 則通過表示式玩出了新花樣,跳出框架本身,相信你對前端框架會看的更加透徹。

相關文章