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でカスタムタグを使用する方法

推薦する

MySQL における制限関数と合計関数の混在使用の問題の詳細な説明

序文今日、注文データを同期した後、同僚は、合計注文金額とデータソースの合計金額に差があったため、LI...

Vue/React シングルページ アプリケーションをリフレッシュなしで復元するソリューション

目次導入なぜわざわざ?落とし穴のあるコミュニティソリューション(Vue を例に挙げる)現時点では良い...

Linux環境で環境変数を設定する方法

JDKダウンロードアドレス: http://www.oracle.com/technetwork/j...

ローカルアイデアアクティベーションサーバーの構築に関する詳細なチュートリアル

序文ブロガーはアイデアIDEを使用しています。アイデア公式が最近サードパーティのアクティベーションサ...

きちんとした標準的なHTMLタグの書き方を学ぶ

優れた HTML コードは美しい Web サイトの基礎となります。私が CSS を教えるときは、まず...

vue3 キャッシュページキープアライブと統合ルーティング処理の詳細な説明

目次1. はじめに2. 使用1. vue2とvue3の違い2. ページ上の一部のデータはキャッシュす...

Linux プロセスが占有するポート番号を表示する 6 つの方法

Linux システム管理者にとって、サービスがポートに正しくバインドされているか、またはポートをリッ...

MySQL 実験: explain を使用してインデックスの傾向を分析する

概要インデックス作成は、MySQL で習得しなければならないスキルであり、MySQL クエリの効率を...

UIエンジニアのキャリアについての私たちの考え

私は長い間落ち込んでいます、なぜでしょうか?以前、お客様から、提供されたソフトウェアが正常に動作しな...

HTML+CSS+JavaScript でシンプルな三目並べゲームを作成する

目次HTMLの実装CSSを追加Javascript部分の実装デモアドレス HTMLの実装まず、hea...

MySQL 5.x の文字化け問題の解決方法

MySQL はよく使われるオープンソースのデータベース ソフトウェアですが、初めてのユーザーにはあま...

ORM を使用して MySQL にデータを追加する手順

【序文】 ORM を使用してデータベース内のデータを操作する場合、前提として、新しい ORM モデル...

時点に基づくMySQLクイックリカバリソリューション

なぜこのような記事を書いたかというと、数日前の夜、仕事が終わろうとしていたときに、業務側で突然、テー...

ES6 における Object.assign() の使い方の詳細な説明

目次2. 目的2.1 オブジェクトにプロパティを追加する2.3 オブジェクトの複製2.4 複数のオブ...

JavaScript は自由に移動するウィンドウのマウス制御を実装します

この記事では、フリーウィンドウのマウス制御を実現するためのJavaScriptの具体的なコードを参考...