製品要件製品要件会議の後、私たちはある要件に遭遇しました。まず、ページが 2 つの列に分割され、データ コンポーネントが左側に表示され、ドラッグ アンド ドロップによる並べ替えがサポートされ、ボタンをクリックしてコンポーネントをクリアできるというものでした。右側では、コンポーネントのサムネイルを左側にドラッグして新しいコンポーネントを生成することができます。 アイデア動的に生成されるコンポーネントの場合、そのコンポーネントを関数に入れて返すことができるように、毎回新しいコンポーネントを生成する必要があります。 JSX で関数を呼び出すと、関数の呼び出しごとにまったく新しいコンポーネントが返されます。これは React では非常に簡単ですが、Vue ではコンポーネントを直接返すことは不可能です。この return の書き方は Vue には適していませんが、考え方が非常に正しいことは否定できないので、別の書き方を検討する必要があります。動的に生成されるコンポーネントに関しては、データを使用してコンポーネントの生成を駆動する必要があります。ドラッグ コンポーネントのソートには、ドラッグ ライブラリを使用するだけです。 ! 問題
ライブラリ選択をドラッグドラッグ ライブラリには、プロジェクト内に存在するドラッグ ライブラリである Vue.Draggable を選択しました。ここをクリックすると、Start 14.9K が表示されます。これはかなり良いです。 Vue プロジェクトでこのドラッグ ライブラリを使用しない場合は、この記事のデザイン アイデアを参照できます。 コンポーネントを生成する方法ここでは Vue.extend() を使用します。使い方がわからない場合は、この記事の Vue.extend を学習する前に公式ドキュメントを確認してください。 次に、コンポーネントを作成するためのコードを記述する js ファイルを作成します。 コンポーネントを生成する/* generateComponents.js ファイル名 */ 「vue」からVueをインポートします。 // コンポーネントを動的に生成する場合は、まずこのファイルをインポートします。 「./components/TestCom1.vue」からcomponents1をインポートします。 「./components/TestCom2.vue」からcomponents2をインポートします。 // コンポーネント名とコンポーネント間の対応するマップを作成します 定数comMap = { コンポーネント1、 コンポーネント2、 }; // コンポーネントを生成するために必要なコンポーネント名と、コンポーネントに渡すプロパティとイベントを受け取ります。const ReturnNewCom = function ({ props, on }) { 定数{ comItem: {名前}, } = プロパティ; const newComponent = Vue.extend({ レンダリング(要素を作成) { // 渡されたコンポーネント名を使用して、レンダリングするコンポーネントを決定します。 createElement(comMap[name], { を返します。 小道具、 の上、 }); }, }); 新しい newComponent() を返します。 }; デフォルトのReturnNewComをエクスポートします。 コンポーネントここでは、このデモを示すために、components1.vue と components2.vue という 2 つのコンポーネントを記述します。 /*components1.vue*/ <テンプレート> <div class="widget-wrapper"> <header class="header">{{ comDetail.name }}--{{ comDetail.id }}</header> <h1>クエリ条件: {{ queryObj }}</h1> <button @click="handleDelete">クリア</button> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ データ() { 戻る { comDetail: this.comItem、 _queryObj: this.queryObj、 }; }, 小道具: { comアイテム: { タイプ: オブジェクト、 デフォルト() { 戻る { id: 0, 名前: ""、 }; }, }, クエリオブジェクト: { //親コンポーネントから渡された選択条件を受け取ることができます。オブジェクトである必要があります タイプ: オブジェクト、 デフォルト() { // デフォルトのクエリ条件を定義します。 戻る { 番号: 0, }; }, }, }, 時計: comItem(val) { this.comDetail = val; 戻り値: }, クエリオブジェクト(val) { this._queryObj = val; 戻り値: }, }, 作成された() { console.log("データ -> this.comItem", this.comItem); }, メソッド: { 削除処理() { // コンポーネントメソッドを削除します this.$el.remove(); // 親コンポーネントの関数を呼び出します。親コンポーネントの leftComList 配列のデータを変更します。 this.$emit("handleDelete", this.comDetail); }, }, }; </スクリプト> <スタイルスコープ> .ウィジェットラッパー{ 背景: #ff7b7b; 境界線の半径: 12px; オーバーフロー: 非表示; 幅: 200ピクセル; } .ヘッダー{ 高さ: 50px; パディング: 0 15px; } </スタイル> 実際、components2.vue ファイルのコードは components1.vue ファイルのコードと似ています。唯一の違いは背景色です。 データ駆動による動的コンポーネントの生成次に、ドラッグ ライブラリ Vue.Draggable を使用してデータをドラッグおよび変更する必要があります。 App.vue ファイルに直接書き込むことができます。 /* アプリ.vue */ <テンプレート> <div class="dragCom"> <h1>{{ 左ComList }}</h1> <button @click="queryObj.num++">クエリ条件を変更する</button> <div class="body"> <div class="left"> <ドラッグ可能なクラス="left" :list="leftComList" :group="'people'"> <div ref="comBody" v-for="({ name, id }, index) が leftComList 内にあります" :key="id" クラス="comCard" > <!-- leftComList 配列をループし、そのデータを使用してコンポーネントをレンダリングします。 動的に生成された配列をこの DOM 要素に追加します。 --> {{ ハンドルAddCom({ プロパティ: { comItem: { 名前、ID }、クエリオブジェクト }、 索引、 }) }} </div> </ドラッグ可能> </div> <div class="right"> <ドラッグ可能 クラス="ドラッグエリア" :list="右ComList" :group="{ name: 'people', pull: 'clone', put: false }" :clone="ハンドルCloneDog" > <div class="card" v-for="rightComList 内の要素" :key="element.id"> {{要素名}} </div> <!-- 右側のカードデータ、rightComList配列オブジェクト内の名前はgenerateComponents.jsに対応します ComMap 内の属性 --> </ドラッグ可能> </div> </div> </div> </テンプレート> <スクリプト> 「vuedraggable」から draggable をインポートします。 「./generateComponents」からCreateComをインポートします。 エクスポートデフォルト{ コンポーネント: ドラッグ可能、 }, データ() { 戻る { 右ComList: [ { id: Math.random(), 名前: "components1", }, { id: Math.random(), 名前: "components2", }, ]、 leftComList: [], //動的に生成されたコンポーネントを駆動するデータを格納します。 comMap: new Map(), // 主な機能は、コンポーネントが class="comCard" の DOM にレンダリングされるかどうかを記録することです。 // レンダリングされると、これ以上子要素を追加できなくなります。 クエリオブジェクト: { // メイン関数は、クエリ条件をサブコンポーネント num: 0 に渡すことです。 }, }; }, 破棄する前に() { // 記録されたデータをクリアします this.comMap.clear(); }, メソッド: { handleAddCom({ インデックス、 on = {}、 props = { comItem: { 名前: "", id: 0 } } }) { 定数{ comItem: { id }, } = プロパティ; this.$nextTick(() => { // このノードの子ノードの長さを取得します。const childNodesLength = this.$refs.comBody[index].childNodes.length; // DOM 配列 comBody の長さを取得します。const comLine = this.$refs.comBody.length; if (!this.comMap.get(id)) { // コンポーネントがレンダリングされていない場合 // 1. CreateCom メソッドを呼び出してコンポーネントを作成します。 そして、propsとイベントを渡します。const com = CreateCom({ 小道具、 の上: { ハンドル削除: this.handleDeleteCom、 ...の上、 }, }); // 2. コンポーネント com.$mount() を生成します。 子ノードの長さが 2 の場合 // 2 つのコンポーネントの間に追加する場合。次に、新しく生成されたコンポーネントの DOM の位置を変更し、中央に配置します。 // 最終コンポーネントDOMを正しい場所に追加します this.$refs.comBody.splice( 索引、 0, this.$refs.comBody[comLine - 1] ); } // 3. 生成されたコンポーネントを DOM に追加します。 this.$refs.comBody[index].appendChild(com.$el); // 4. コンポーネントがレンダリングを実装していることを記録します。 this.comMap.set(id, true); } それ以外 { // この位置のコンポーネントはレンダリングされているため、再度レンダリングする必要はなく、そのまま返します。 } }); }, handleDeleteCom({id}) { // コンポーネント ID に従ってデータを削除するために子コンポーネントに渡されるメソッド const index = this.leftComList.findIndex((item) => item.id === id); if (~インデックス) { // この ID を持つコンポーネントが存在する場合は削除します this.leftComList.splice(index, 1); } }, ハンドルクローンドッグ(アイテム) { // leftComList配列にデータを追加する return { ...アイテム、 id: Math.random(), }; }, }, }; </スクリプト> <スタイル> .dragCom{ フォントファミリー: Avenir、Helvetica、Arial、sans-serif; -webkit-font-smoothing: アンチエイリアス; -moz-osx-font-smoothing: グレースケール; テキスト配置: 中央; 色: #2c3e50; 上マージン: 60px; } 。体 { 幅: 100%; 高さ: 800ピクセル; ディスプレイ: フレックス; コンテンツの両端揃え: スペースの間; } 。左 { フレックス: 1; 高さ: 800ピクセル; 境界線: 1px ピンク } 。右 { 幅: 20%; 高さ: 800ピクセル; } .カード{ 高さ: 50px; 背景色: #40cec7; マージン: 12px 0; フォントサイズ: 12px; 行の高さ: 50px; カーソル: ポインタ; } .comカード{ マージン: 12px; 表示: インラインブロック; } </スタイル> これにより、動的なコンポーネントのレンダリングとドラッグソートが可能になります。 効果ソースコード試してみたい学生は、この記事のソースコードをgithubからダウンロードできます。 上記は、Vue のドラッグと動的コンポーネント生成の要件の詳細な内容です。Vue のドラッグと動的コンポーネント生成の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
目次最初のステップステップ2ステップ3ステップ4 Alipay 決済インターフェースへの接続に関する...
CSS3 border-image プロパティを使用すると、要素の周囲に画像の境界線を設定できます。...
背景:サイトはフロントエンドとバックエンドから分離されています: vue+springbootフロン...
目次序文スタイル機能説明初期化コードイベントリスナーの追加リスナーツールバーモニターテーブル行ツール...
JavaScriptでの検索二分木実装は参考までに。具体的な内容は以下のとおりです。バイナリ検索木 ...
これは、VPS サーバー用の一般的なワンクリック パフォーマンス テスト スクリプトです。マシンの構...
div または span に同時に CSS を適用する必要があります。コードをコピーコードは次のとお...
ページをレイアウトする際、ユーザーに異なる視覚効果を与えるために、div の背景色を半透明の状態に設...
脆弱性の詳細VSFTP は、GPL に基づいてリリースされた Unix ライクなシステムで使用される...
1. mysql-5.7.17-winx64.zip インストール パッケージをダウンロードします ...
目次可変タイプとストレージスペーススタックメモリとヒープメモリ基本的なデータ型参照タイプグラフィック...
MySQLに何がインストールされているか確認する rpm -qa | grep -i mysql n...
目次序文Toastコンポーネントをカプセル化する方法ユースケース具体的な実装要約する序文ビジネスが発...
目次インストール環境の説明MySQLデータベースサービスをインストールするメインライブラリを構成する...
マウスを動かしたときにDIVが消えるように手ぶれ補正を使用するdiv タグ自体は onblur イベ...