Vue から React への変換入門ガイド

Vue から React への変換入門ガイド

新会社は、Umi、Dva、Ant-design などの一連のソリューションを含む React テクノロジー スタックを使用しているためです。少し慣れてきた後、いくつかの違いはあるものの、それでも非常に異なることに気付きました。以下では、デザイン、記述方法、API、ライフサイクル、人気のエコロジーの観点から、2 つの人気フレームワークである react16 と vue2 (現在 vue3 を学習中) を簡単に比較します。

デザイン

反応するビュー例示する
位置ユーザーインターフェースを構築するための js ライブラリプログレッシブフレームワークReactはライブラリに重点を置き、Vueはフレームワークに重点を置いています
レンダリングsetStateは状態値を更新してビューを再レンダリングしますレスポンシブデータレンダリングでは、変更されたレスポンシブデータに対応するビューもレンダリングされます。 ReactはいつsetStateし、いつレンダリングするかを考慮する必要がありますが、Vueはデータの変更のみを考慮する必要があります。
書き方jsxテンプレートReact は機能的で、すべて js で記述されています。Vue はテンプレート、スクリプト、スタイルを区別し、構文シュガーを提供し、vue-loader を使用してコンパイルされます。

コンポーネント通信

react: 厳密に一方向のデータフロー

  • 下向き支柱
  • アッププロパティ関数
  • マルチレベルコンテキスト転送

すべてがpropsになるという原則に従ってください。onChange/setState()

Vue: 一方向データフロー

  • 支柱を下ろす
  • イベントアップ(公開するには購読してください)
  • $attrs と $listeners のマルチレベル受け渡し

コンポーネントインスタンス (VueComponent) を取得する方法もいくつかあります。たとえば、$refs、$parent、$children などです。親コンポーネントまたは子コンポーネントを再帰的に取得する方法もあります。たとえば、findComponentUpward、findComponentsUpward などです。高レベルコンポーネント: provide/reject、dispatch/broadcast

反応するビュー例示する
サブコンポーネントデータ転送小道具小道具すべて宣言的である
コンポーネントステートマシンデータコンポーネントのステータスを管理するために、React は setState を使用して変更し、Vue は値を直接割り当て、新しいプロパティに $set を使用します。Vue は関数クロージャ機能を使用してコンポーネント データの独立性を確保し、React は関数です。

ライフサイクル

反応するビュー例示する
データの初期化コンストラクタ作成された
マウントコンポーネントマウントマウントされたDOMノードが生成されました
更新するコンポーネントの更新更新されましたreact: コンポーネントが更新されると、react は最初の初期化が成功した後にのみ componentDidmount に入り、再レンダリングのたびにこのライフサイクルに入ります。ここでは、更新前の props と state である prevProps と prevState を取得できます。 vue: データの変更により仮想DOMが再レンダリングされ更新された後に呼び出されます
アンインストールコンポーネントのマウントを解除する破壊された破壊イベント

イベント処理

反応する

  • React イベントの名前は小文字ではなくキャメルケースで付けられます。
  • JSX 構文を使用する場合は、文字列ではなく関数をイベント ハンドラーとして渡す必要があります。
  • false を返すことでデフォルトの動作を防ぐことはできません。明示的にpreventDefaultを使用する必要があります
  • 要素以外のタグではアンインストールできません。そうでない場合は、プロパティとして渡されます。
関数フォーム() {
  関数handleSubmit(e) {
    e.preventDefault();
    console.log('送信をクリックしました。');
  }
  戻る (
    <フォームonSubmit={handleSubmit}>
      <button type="submit">送信</button>
    </フォーム>
  );
}

ビュー

通常の要素で使用する場合、ネイティブ DOM イベントのみをリッスンできます。カスタム要素コンポーネントで使用すると、子コンポーネントによってトリガーされるカスタムイベントをリッスンすることもできます。

//ネイティブ イベント <form v-on:submit.prevent="onSubmit"></form>
//カスタム イベント <my-component @my-event="handleThis(123, $event)"></my-component>

Vue イベント修飾子:

  • .stop - event.stopPropagation() を呼び出します。
  • .prevent - event.preventDefault() を呼び出します。
  • .capture - イベント リスナーを追加するときにキャプチャ モードを使用します。
  • .self - コールバックは、リスナーがバインドされている要素からイベントが発生した場合にのみ実行されます。
  • .native - コンポーネントのルート要素のネイティブ イベントをリッスンします。
  • .once - コールバックを 1 回だけトリガーします。
  • .left - (2.2.0) マウスの左ボタンがクリックされたときにのみ発生します。
  • .right - (2.2.0) マウスの右ボタンがクリックされたときにのみ発生します。
  • .middle - (2.2.0) マウスの中央ボタンがクリックされたときにのみ発生します。
  • .passive - (2.3.0) {passive: true} モードでリスナーを追加します

品格とスタイル

クラス

反応する

与える() {
  className = 'menu';とします。
  if (this.props.isActive) {
    className += 'メニューアクティブ';
  }
  <span className={className}>メニュー</span> を返す
}

ビュー

<div
  クラス="static"
  :class="{ active: isActive, 'text-danger': hasError }"
</div>

 
<div :class="[{ active: isActive }, errorClass]"></div>

スタイル

反応する

<div style={{color: 'red', fontWeight: 'bold'}} />

ビュー

<div :style="[baseStyles, overridingStyles]"></div>

コンポーネントをスタイル設定する場合、スタイル タグにスコープ タグをコンポーネント スタイル分離注釈として宣言できます (例: <style lang="sass" scoped></style>)。パッケージ化の際、コンポーネント間のCSS汚染を避けるために、スタイルには実際に一意のハッシュ値が追加されます。

条件付きレンダリング

  • react: jsx 式、&& または三項式。false を返すとレンダリングされないことを意味します
  • vue: 式はレンダリングされるために true を返します。複数の v-else-if と v-else をネストできます。

リストレンダリング

react: .mapを使用する場合、要素のキーは、要素がリスト内で持つ一意の文字列であることが望ましい

<ul>
  {props.posts.map((投稿) =>
    <li キー = {投稿 ID}>
      {投稿タイトル}
    </li>
  )}
</ul>

vue: Vue にヒントを与えて各ノードの ID を追跡し、既存の要素を再利用して並べ替えることができるようにするには、各項目に一意のキー属性を提供する必要があります。

<li v-for="item in items" :key="item.message">
  {{アイテム.メッセージ}}
</li>

コンポーネントのネスト

反応する

デフォルトスロット

<div className={'FancyBorder FancyBorder-' + props.color}>
  {props.children}
</div>

名前付きスロット

<div className="SplitPane">
  <div className="SplitPane-left">
    {props.left}
  </div>
  <div className="SplitPane-right">
    {props.right}
  </div>
</div>

<SplitPane 左={<連絡先 />} 右={<チャット />} />

ビュー

デフォルトスロット

<メイン>
  <スロット></スロット>
</メイン>

名前付きスロット

<ヘッダー>
  <スロット名="ヘッダー"></スロット>
</ヘッダー>

DOMを取得する

react: フォーカス、テキスト選択、またはメディアの再生を管理します。強制アニメーションをトリガーします。サードパーティのDOMライブラリを統合する

クラスMyComponentはReact.Componentを拡張します。
  コンストラクタ(props) {
    スーパー(小道具);
    this.myRef = React.createRef();
  }
  与える() {
    <div ref={this.myRef} /> を返します。
  }
}

vue: 要素またはサブコンポーネントの参照情報を登録するために使用されます

<div ref="div">こんにちは</div>

this.$refs.p.offsetHeight

文書構造

うみ

├── config # ルーティング、ビルド、その他の構成を含む umi 構成│ ├── config.ts # プロジェクト構成.umirc.ts の方が優先度が高く、この方法では .umirc.ts を削除する必要があります
│ ├──routes.ts # ルーティング設定│ ├──defaultSettings.ts # システム設定│ └──proxy.ts # プロキシ設定├──mock # このディレクトリ内のすべてのjsおよびtsファイルは、モックファイルとして解析されます├──public # このディレクトリ内のすべてのファイルは出力パスにコピーされます。ハッシュが設定されていても追加されません├──src
│ ├── アセット # ローカル静的リソース│ ├── コンポーネント # ビジネス共通コンポーネント│ ├── e2e # 統合テストケース│ ├── レイアウト # 従来のルーティングのグローバルレイアウトファイル│ ├── モデル # グローバル dva モデル
│ ├── pages # すべてのルーティングコンポーネントはここに保存されます│ │ └── document.ejs # このファイルが存在する場合は、デフォルトのテンプレートとして使用することに同意します│ ├── services # バックエンドインターフェースサービス│ ├── utils # ツールライブラリ│ ├── locales # 国際リソース│ ├── global.less # グローバルスタイル│ ├── global.ts # グローバル JS
│ └── app.ts # ルートの変更、レンダリングメソッドの変更などのランタイム構成ファイル。 ├── README.md
└── package.json

vue_cli

├── mock # プロジェクトのモックシミュレーションデータ├── public # 静的リソース│ └── index.html # HTML テンプレート├── src # ソースコード│ ├── api # すべてのリクエスト│ ├── asset # テーマフォントとその他の静的リソース│ ├── components # グローバルパブリックコンポーネント│ ├── directive # グローバルディレクティブ│ ├── filters # グローバルフィルター
│ ├── レイアウト # グローバルレイアウト
│ ├── router # ルーティング│ ├── store # グローバルストア管理│ ├── utils # グローバルパブリックメソッド│ ├── views # 全ページのビュー│ ├── App.vue # エントリページ│ └── main.js # エントリファイルの読み込みコンポーネントの初期化など├── tests # テスト├── vue.config.js # プロキシ、圧縮画像などの vue-cli 設定└── package.json # package.json

ルーティング

動的ルーティングとルーティングパラメータ

反応ルーター

  • history.push(/list?id=${id})
  • history.push({パス名: '/list', クエリ: {id}})
  • history.push(/list/id=${id})
  • history.push({パス名: '/list', パラメータ: {id}})

props.match.query / props.match.params を取得する

vue-ルーター

  • this.$router.push({パス: '/list', クエリ: {id}})
  • this.$router.push({path: '/list', params: {id}})

this.$router.query / this.$router.params を取得します

ネストされたルート

-反応する

{
  パス: '/'、
  コンポーネント: '@/layouts/index',
  ルート: [
    { パス: '/list'、コンポーネント: 'list' },
    { パス: '/admin'、コンポーネント: 'admin' },
  ]、
}

<div style={{ padding: 20 }}>{ props.children }</div>

props.children を使用して子ルートをレンダリングする

vue-ルーター

{
  パス: '/user/:id',
  コンポーネント: ユーザー、
  子供たち: [
    {
      パス: 'プロファイル',
      コンポーネント: UserProfile
    },
    {
      パス: '投稿',
      コンポーネント: UserPosts
    }
  ]
}

<div id="アプリ">
  <ルータービュー></ルータービュー>
</div>

サブルートをレンダリングするには、vueネイティブコンポーネント/<router-view/>コンポーネントを使用します。

ルートジャンプ

うみ

<NavLink exact to="/profile" activeClassName="selected">プロフィール</NavLink>
履歴.push(`/list?id=${id}`)

ビュー

<router-link to="/about">について</router-link>
this.$router.push({パス: '/list', クエリ: {id}})

ルーティングガード(ログイン認証、特殊ルーティング処理)

  • うみ
  • vue-ルーター

グローバルルーティングガード

グローバル事前ガード: router.beforeEach

 const ルーター = 新しい VueRouter({...})
 router.beforeEach((to, from, next) => {
   // ...
 })

グローバルポストガード: router.beforeEach

 router.afterEach((to, from) => {
   // ...
 })

状態管理

複数のビューが同じ状態に依存している場合、または異なるビューの動作で同じ状態を変更する必要がある場合は、状態マネージャーが必要です。

ドヴァヴュークス例示する
モジュール名前空間モジュールアプリケーションのすべての状態が比較的大きなオブジェクトに集中し、ストアオブジェクトがかなり肥大化する可能性があります。
単一ステートツリー唯一のデータソース
ステートマシンの送信減速機突然変異同期操作を処理するために使用され、状態を変更できる唯一の場所です。
非同期操作の処理効果アクション状態ツリーを変更するには、送信状態マシンを呼び出します。

使用

dva: モデル接続UI

// 新しいモデル: models/products.js
エクスポートデフォルト{
  名前空間: '製品',
  州: []、
  リデューサー: {
    'delete'(状態、{ ペイロード: id }) {
      state.filter(item => item.id !== id) を返します。
    },
  },
};
//モデルを接続
エクスポートデフォルトconnect(({製品}) => ({
  製品、
}))(製品);

//ディスパッチモデルを減らす
ディスパッチモデルreduce({
  タイプ: 'products/delete'、
  ペイロード: ID、
})

Ajaxリクエスト、dispathモ​​デルエフェクトなどの非同期操作がある場合、エフェクトはモデル削減を呼び出します
ヴュークス

// 新しいモジュール
定数ストア = 新しい Vuex.Store({
  州: {
    カウント: 1
  },
  突然変異:
    増分(状態) {
      状態.count++
    }
  },
  アクション: {
    インクリメント(コンテキスト) {
      context.commit('増分')
    }
  }
})
//UIをバインド
<input v-model="$store.state[モデル名].name"/>
//モジュールの変更をコミットする 
store.commit('増分')

Ajaxリクエスト、dispathモ​​ジュールアクションなどの非同期操作があり、その後アクションがモジュールのミューテーションを呼び出す場合

ストア.ディスパッチ({
  タイプ: 'incrementAsync'、
  数量: 10
})

これで、Vue から React への変換入門ガイドに関するこの記事は終了です。Vue から React への変換に関する関連コンテンツをさらにご覧になりたい場合は、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続きご覧ください。今後も 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • ReactからVue開発への切り替えのためのプロジェクト準備の詳細な説明
  • React コンポーネントを Vue コンポーネントに変換するコマンドの書き方

<<:  Docker は 2003 年の問題を解決するために MySQL リモート接続を導入しました

>>:  HTMLでカスタムタグを使用する方法

推薦する

Linux で見つけるためのフレンドリーな代替手段 (fd コマンド)

fd コマンドは、Linux ファイル システムを検索するためのシンプルで簡単な方法を提供します。...

使用状況分析を備えたMySQL

持つことの使用法having 句を使用すると、グループ化後にさまざまなデータをフィルター処理できます...

Dockerを使用してRedisクラスターを構築する方法

目次1. Redis Dockerベースイメージを作成する2. Redisノードイメージを作成する3...

Tomcat クラスローダーの実装方法とサンプルコード

Tomcat は内部的に複数の ClassLoader を定義し、アプリケーションとコンテナーが異な...

JSコンストラクタとインスタンス化およびプロトタイプ導入の関係

目次1. コンストラクタとインスタンス化2. コンストラクターとインスタンス化の関係は何ですか? 3...

Nginx レベルで基本的なユーザー認証を構成する手順を完了します。

序文アプリケーション シナリオ: おそらく、内部 Web サイトは外部ユーザーにアクセス可能である必...

LinuxにDockerをインストールする(非常に簡単なインストール方法)

最近、かなり暇です。大学4年生として数か月間インターンをしていました。インターンとして、Docker...

JavaScript スクリプトが実行されるタイミングの詳細な説明

JavaScript スクリプトは HTML 内のどこにでも埋め込むことができますが、いつ呼び出され...

DIVマスクを使用して、マウスでチェックボックスを直接チェックすることが無効である問題を解決します

フロントエンドの開発過程で、チェックボックスが必要な状況が発生しました。ユーザー操作の利便性を考慮し...

Dockerボリュームコンテナ間のデータ共有の実装

ボリュームとは何ですか?ボリュームは英語で容量を意味し、Docker ではデータ ボリューム、つまり...

HTML ウェブページの基本コンポーネントの概要

<br />Web ページ上の情報は主にテキストベースです。 Web ページでは、フォン...

Bootstrap が人気な 11 の理由

序文最も人気のあるフロントエンド開発フレームワークである Bootstrap は、Web サイトの開...

CSS3入力ボックスの実装コードはGoogleログインのアニメーション効果に似ています

CSS3を使用して、Googleログインページと同様の入力ボックスをアニメーション化します。効果1 ...

Alibaba Cloud で静的ウェブサイトを素早く構築する方法

序文:ジュニアプログラマーとして、私は自分自身の個人ウェブサイトを構築し、それを他の人に見せることを...

jQueryはネストされたタブ機能を実装します

この記事では、ネストされたタブ機能を実装するためのjQueryの具体的なコードを参考までに紹介します...