序文フォームを使用して PC 側のプロジェクト、特に CRM システムを開発する場合、このような要件に頻繁に遭遇します。ユーザーは設定に応じて表示列をカスタマイズする必要があります。 要素の公式ドキュメントを確認しましたが、そのようなコンポーネントは見つからなかったので、そのようなニーズを開発するときに役立つことを期待して、単純なコンポーネントを手動でカプセル化しました。 レンダリング具体的な効果図は以下のとおりです。 表示列をカスタマイズします(ドラッグ アンド ドロップして並べ替え、クリックして選択、もう一度クリックしてキャンセルできます) ユーザーが設定したフィールドに従って各列を並べ替え/表示/非表示にする setTable コンポーネントまず、ドラッグ アンド ドロップによる並べ替えを実装するには、プラグインを使用する必要があります。 npm をインストール vuedraggable -S 具体的なコンポーネントコードは以下のとおりです。詳しいコメントはコード内に書かれているので、ここでは詳細は割愛します。 。 テーブルの設定 <テンプレート> <div> <el-dialog title="カスタム表示列" :visible.sync="dialogVisible" width="50%"> <div class="メニューを選択メニューボックス"> <p class="menus-title">ブロックをドラッグして表示順序を調整します</p> <div class="メニューコンテンツ"> <ドラッグ可能な v-model="選択済み" @update="datadragEnd" :options="{アニメーション:500}"> <遷移グループ> <div v-for="選択されたメニュー" :key="menu.field" class="drag-item item">{{menu.name}}</div> </トランジショングループ> </ドラッグ可能> </div> </div> <div class="メニューコンテナメニューボックス" v-if="フィールドの長さ"> <p class="menus-title">表示列を選択</p> <div class="メニューコンテンツ"> <div クラス="アイテム" :class="{active:menu.active}" v-for="フィールドのメニュー" :key="メニューフィールド" @click="onSelect(メニュー)" >{{メニュー名}}</div> </div> </div> <span slot="フッター" class="ダイアログフッター"> <el-button @click="dialogVisible = false">キャンセル</el-button> <el-button type="primary" @click="onSave">OK</el-button> </span> </el-ダイアログ> </div> </テンプレート> <スクリプト> 「vuedraggable」から draggable をインポートします。 "@/api/user" から { getFields、setFields、getFieldControl } をインポートします。 エクスポートデフォルト{ 名前: "setTable"、 挿入: ["リロード"], 小道具: { 型: 文字列、 }, コンポーネント: ドラッグ可能、 }, データ() { 戻る { ダイアログ表示: false、 fields: [], //すべてのメニューが選択されています: [], //選択されたメニュー}; }, 時計: 選択: { ハンドラ(古い値、新しい値) { if (this.fields.length === 0) { 戻る; } 新しいVal.map((i) => { this.fields.map((j) => { i.field === j.field の場合 { // 選択した配列に同じフィールドがすでに存在する場合、active は true になります。 Active は主に、すべてのメニューの選択/非選択スタイルを制御するために使用されます。j.active = true; } }); }); }, }, }, マウント() { //ドラッグ時にFirefoxが新しいタブを開かないようにするには document.body.ondrop = function (event) { イベントをデフォルトにしない(); イベントの伝播を停止します。 }; }, メソッド: { 非同期getData() { // すべてのメニューデータを取得する const { data: fields } = await getFields({ 型: this.types、 }); フィールド.map((アイテム) => { // サーバーはアクティブ フィールドを返さないため、選択されたスタイルを制御するには、各データにアクティブ フィールドを追加する必要があります。item.active = false; }); this.fields = フィールド; }, 非同期getFields() { // ユーザーが選択したメニューを取得します。これにより、設定を再度開いたときに最後に選択したメニューがページに反映され、ユーザーが再度変更できるようになります。let fields = await getFieldControl({ アカウントID: this.$store.state.user.token.account_id, ユーザーID: this.$store.state.user.token.userid, 型: this.types、 }); this.$nextTick(() => { this.selected.push(...フィールドデータ); }); }, 非同期onSave() { // 選択したメニューを保存する await setFields({ アカウントID: this.$store.state.user.token.account_id, ユーザーID: this.$store.state.user.token.userid, 型: this.types、 コンテンツ: this.selected、 }); this.reload(); //ページを更新する}, 非同期オープン(){ // 設定ウィンドウを開いたときにデータをクリアし、最新のデータを再度要求します。this.fields = []; this.selected = []; this.dialogVisible = true; this.getData() を待機します。 this.getFields() を待機します。 }, onSelect(アイテム) { // 選択されたメニューに選択されたメニューがあるかどうかを判定する let findex = this.selected.findIndex((i) => { item.field === i.field を返します。 }); (検索インデックス === -1)の場合{ // メニューに選択された項目がない場合は、最後の項目に追加します this.selected.push(item); } それ以外 { // すでに選択されている場合は、クリックすると選択が解除され、選択されたスタイルを変更するには active を false に設定する必要があります。item.active = false; this.selected.splice(findex, 1); } }, データドラッグ終了(evt) { // ドラッグソート evt.preventDefault(); }, }, }; </スクリプト> <style lang="scss" スコープ> /* すべてのメニュー */ .メニューコンテナ{ 上マージン: 20px; .メニューコンテンツ{ 。アイテム { 色: #575757; 背景: rgba(238, 238, 238, 1); 境界線: 1px実線 rgba(220, 220, 220, 1); 境界線の半径: 2px 0px 0px 2px; } } } /* メニューの一般的なスタイル*/ .メニューボックス{ .メニュータイトル{ 上マージン: 10px; 行の高さ: 32px; } .メニューコンテンツ{ ディスプレイ: フレックス; flex-wrap: ラップ; 。アイテム { カーソル: ポインタ; ディスプレイ: インラインフレックス; アイテムの位置を中央揃えにします。 コンテンツの中央揃え: 中央; パディング: 8px; マージン: 10px; 境界線の半径: 3px; } 。アクティブ { 色: #fff; 背景: rgba(72, 153, 229, 1); 境界線の半径: 2px 0px 0px 2px; } } } /* 選択されたメニュー */ .select-menus { .メニューコンテンツ{ 。アイテム { マージン: 0px; 境界線の半径: 0; 背景: rgba(255, 255, 255, 1); 境界線: 1px実線 rgba(220, 220, 220, 1); } } } </スタイル> 使用具体的な使い方は以下の通りです。ここでは皆さんに誤解を与えないよう、不要な業務コードは隠して、コアとなる実装コードのみを掲載しています。 <テンプレート> <div> <el-テーブル ref="複数のテーブル" :data="テーブルデータ" 高さ="60vh" :row-class-name="テーブル行クラス名" @selection-change="選択変更処理" @row-click="handleRead" > <el-table-column type="selection" min-width="55px;"></el-table-column> <template v-for="(item,index) フィールド"> <el-テーブル列 v-if="item.field==='名前'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='性別'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="8%;" オーバーフローツールチップを表示 > <template slot-scope="scope">{{scope.row.gender===1?'男':'女'}}</template> </el-table-column> <el-テーブル列 v-if="item.field==='corp_full_name'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="14%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='corp_name'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="12%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='up_date'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="14%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='位置'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='remark_mobiles'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="14%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='source_name'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='アドレス'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='detail_address'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='説明'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='コメント'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='recordContent'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="14%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='owner_name'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... <el-テーブル列 v-if="item.field==='follow_time'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="8%;" オーバーフローツールチップを表示 > <テンプレート スロット スコープ="スコープ"> <div v-if="scope.row.follow_time===scope.row.createtime">なし</div> <div v-else>{{scope.row.follow_time | formatDate}}</div> </テンプレート> </el-table-column> <el-テーブル列 v-if="item.field==='next_follow_time'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="8%;" オーバーフローツールチップを表示 > <テンプレート スロット スコープ="スコープ"> <div v-if="scope.row.next_follow_time===0">なし</div> <div v-else>{{scope.row.next_follow_time | formatDate}}</div> </テンプレート> </el-table-column> <el-テーブル列 v-if="item.field==='createtime'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="8%;" オーバーフローツールチップを表示 > <テンプレート スロット スコープ="スコープ"> <div>{{scope.row.createtime | formatDate}}</div> </テンプレート> </el-table-column> <el-テーブル列 v-if="item.field==='更新時間'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="8%;" オーバーフローツールチップを表示 > <テンプレート スロット スコープ="スコープ"> <div>{{scope.row.updatetime | formatDate}}</div> </テンプレート> </el-table-column> <el-テーブル列 v-if="item.field==='is_record'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 > <テンプレート スロット スコープ="スコープ"> <div>{{scope.row.is_record === 0 ? 'フォローアップされていません' : 'すでにフォローアップされています' }}</div> </テンプレート> </el-table-column> <el-テーブル列 v-if="item.field==='if_record'" :key="インデックス" :prop="アイテム.フィールド" :label="アイテム名" 最小幅="10%;" オーバーフローツールチップを表示 </el-table-column> ... </テンプレート> <el-table-column label="操作" min-width="8%;"> <テンプレート スロット スコープ="スコープ"> <el-button @click="handleRead(scope.row)" type="text">詳細</el-button> </テンプレート> </el-table-column> <el-table-column align="right" min-width="4%;"> <テンプレートスロット="ヘッダー"> <i class="iconfont icongengduo" @click="onMore"></i> </テンプレート> </el-table-column> </el-table> <set-table ref="setting" types="リード"></set-table> </div> </テンプレート> <スクリプト> 「@/components/setTable」からsetTableをインポートします。 "@/api/user" から getFieldControl をインポートします。 エクスポートデフォルト{ 名前: 「手がかり」、 コンポーネント: テーブルの設定、 }, データ() { 戻る { フィールド: [], }; }, 非同期マウント() { this.getFields() を待機します。 this.clues(); }, メソッド: { 非同期getFields() { フィールドをawait getFieldControl({ アカウントID: this.$store.state.user.token.account_id, ユーザーID: this.$store.state.user.token.userid, タイプ: 「リード」、 }); フィールドをデータに格納します。 }, オンモア() { this.$refs.setting.open(); }, }, }; </スクリプト> 実際、ここで固定の列幅を設定したり、サーバーを通じて特定のサイズを返したりすることもできます。このようにすると、多くの if ステートメントを書く必要がなくなり、より便利で簡潔になります。 結論実際、この要件を最初に受け取ったときは、サーバーから返されるさまざまなフィールドに応じてフォームの列をドラッグして並べ替える必要があったため、非常に複雑に感じました。 しかし、全体的には思ったほど面倒ではありませんでした。 必要に迫られたときは、あまり考えすぎず、まずは試してみると、思ったほど難しくないかもしれません。 これで、vue カスタム テーブル列に関するこの記事は終了です。より関連性の高い vue カスタム テーブル列については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: Linux 上での MySQL データベースのインストールと Java プロジェクトの構成に関する詳細なグラフィック説明
1. レンダリング 2. ソースコードhtml < 本文 > < div クラス ...
<br />多くのウェブサイト デザイナーが犯す最も一般的な間違いは、ウェブページが I...
この記事では、画像拡大鏡効果を実現するためのJSの具体的なコードを参考までに紹介します。具体的な内容...
目次1. ノード、ツリー、仮想DOM 2. 仮想DOM 2.1 データオブジェクトの詳細2.2 制約...
目次MySQL 結果のソート - 集計関数環境クエリ結果の並べ替えクエリのグループ化と集約生徒の平均...
XHTML CSS ページ制作中に遭遇する問題の解決策は、解決策と呼ぶには少々大げさです。せいぜい、...
1つ。 tomcat を使用したリモート展開1.1 発生した問題:プロジェクトでは、サードパーティの...
CSS レイアウト - position プロパティposition 属性は、要素に適用する配置方法...
この記事では、MySQL マスターとスレーブ データ間の不一致の解決方法と、プロンプト「Slave_...
MySQL データ型における DECIMAL の使用法の詳細な説明MySQL のデータ型には、INT...
ここ2日間Javaを復習するつもりなので、練習にdubboを使ってショッピングモールプロジェクトを書...
目次1. beforeCreate & created 2. マウント前とマウント済み3. ...
目次実装のアイデア:ステップ 1: TabBar と TabBarItem のコンポーネント カプセ...
置換を削除したり文字列を削除したりできる tr コマンドは、誰もがよく知っています。 英語では、英語...
この記事では、例を使用して、MySQL トランザクション、分離レベル、およびロックの使用について説明...