関数前回の記事では、element-ui フレームワークに基づいて、より便利なテーブル コンポーネントをカプセル化しましたが、今回はクエリ コンポーネントの作成を開始します。クエリ コンポーネントには何が必要でしょうか。以下に、クエリ コンポーネントが実装する必要のある機能を基本的に説明する大まかなプロトタイプを描きました。 基本的なクエリ機能 [条件を入力し、ドロップダウンデータを選択してクエリをクリック] クエリのドロップダウン パネルを追加します [クエリが多数ある場合は 1 行に収めることができず、さらにクエリのドロップダウン パネルが必要になります。デフォルトのクエリ条件を除いて、すべてをドロップダウン パネルに置きます。渡されたパラメータによって制御できる、いくつかの特定のデフォルトのクエリ条件を配置します] 条件付き表示を追加する [クエリパネルが複数ある場合、クエリパネルを開かないと、データがどのような条件に基づいているかわかりません。] 機能ボタンエリアを追加 [通常、追加、削除、変更などの一括操作用の機能ボタンを配置します] 基本的なクエリ関数クエリ機能については、入力ボックス、ドロップダウン ボックス、日付ボックス、および element-ui の他のコンポーネントを使用して実装する必要があります。コンポーネントを使用する場合は、配列を使用してクエリ条件を記述し、コンポーネントが配列に従って条件を識別してレンダリングするようにします。まず、この配列がどのようになっているかを定義する必要があります。 // メソッド initSearch() { const searchArr = this.searchArr if (searchArr && searchArr.length) { searchForm = {} とします。 searchArr.forEach((val) => { searchForm[val.key] = '' }) this.searchForm = 検索フォーム } } // マウント マウントされた(){ this.initSearch() }, 現時点では、最も基本的なのはこの 3 つのフィールドであり、フィールドの意味はコードコメントに明記されています。 このオブジェクトには、他にもフィールドがいくつかある場合があります。たとえば、ドロップダウン データは通常、バックグラウンド インターフェイスを介してフロント エンドに提供されます。ここで URL、パラメータ、メソッドを追加して、インターフェイスの名前、パラメーター、およびリクエスト メソッドを定義できます。もちろん、後で実装するときにこれについて説明します。それでは、開発を始めましょう。 クエリ条件の初期化外部から searchArr データを渡した後、マウント時にそれをトラバースし、コンテンツで定義されたクエリ条件 searchForm の応答データを設定する必要があります。 // メソッド initSearch() { const searchArr = this.searchArr if (searchArr && searchArr.length) { searchForm = {} とします。 searchArr.forEach((val) => { searchForm[val.key] = '' }) this.searchForm = 検索フォーム } } // マウント マウントされた(){ this.initSearch() }, ページのレンダリング私たちが設計したクエリページは、外側に表示されるクエリ条件と、内側に表示される追加のクエリ条件の 2 つの部分に分かれているためです。この場合、テンプレートで構造を定義すると、重複するコードを 2 回記述する必要があることがわかります。 後から新しい機能を拡張すると、また別の面倒な物理的作業になります。そこで、ここではレンダリング関数に jsx を記述します。これにより、構造がより柔軟になり、コードの再利用性が向上します。アイデアについて説明したので、コードを書き始めましょう。 // props はクエリ条件を記述する searchArr 配列を渡します/** * クエリ条件の説明 */ 検索Arr: { タイプ: 配列、 デフォルト: () => [] }, // データは 2 つの変数を定義します。searchForm: バックエンドに渡されるクエリ フィールド、selectOption: ドロップダウン データ searchForm: {}、 選択オプション: {} // マウントされたデータを初期化する initSearch() { const searchArr = this.searchArr if (searchArr && searchArr.length) { searchForm = {} とします。 searchArr.forEach((val) => { searchForm[val.__key] = '' // ユーザー定義フィールドを取り出してsearchFormに配置し、空の文字列を割り当てます this.setOption(val) // ドロップダウンデータの場合は、ドロップダウンリストをselectOptionに割り当てます }) this.searchForm = 検索フォーム } }, // メソッドはドロップダウンデータを設定します async setOption (val) { if (~['select', 'mulSelect'].indexOf(val.__type)) { // 最初のケースでは、ドロップダウンデータがローカルにハードコードされている場合 if (val.data && Array.isArray(val.data)) { this.$set(this.selectOption、val.__key、val.data) を設定します。 } それ以外の場合 (val.fetchUrl) { // 2番目のケースでは、プルダウンデータがバックグラウンドインターフェースから渡された場合、const result = await request({ url: val.fetchUrl、 メソッド: val.method || 'post' }) if (結果 && 結果データ && 結果データ.成功) { this.$set(this.selectOption, val.__key, result.data.list || []) } } } }, 初期化作業が完了したら、レンダリングを開始できます。先ほども述べたように、レンダリング関数内に jsx を記述すると柔軟性が増すので、この部分を書き始めましょう。 // レンダリング関数 <div class="searchTable"> <el-フォーム インライン={true} props={{モデル: this.searchForm}} ref="検索フォーム" クラス="検索フォーム"> { searchArr.map((o) => { components[o.__type] を返します ? components[o.__type](h, o, this) : '' }) } <el-form-item> <el-button size="small" type="primary" icon="el-icon-search" on-click={ queryTable }>クエリ</el-button> <el-form-item> <el-link スタイル="margin-left: 10px;" タイプ="プライマリ" 下線={ false } on-click={ () => { this.moreShow = !this.moreShow } }>その他のクエリ</el-link> </el-form-item> </el-form-item> <div class="more-search アニメーション" class={ this.moreShow ? 'fadeInDown' : 'fadeOutUp' } v-show={ this.moreShow }> // ...その他のクエリ</div> </el-form> </div> jsx での操作で注意すべき点が 1 つあります。最新の vue-cli では、jsx での v-model などの命令の使用はすでにサポートされていますが、element-ui での el-input の使用はエラーになります。以下で使用している v-show 命令は使用できます。しかし、実際には v-model は単なるシンタックスシュガーです。ここでは、input イベントを使用して最新の入力データを取得し、それを searchForm に割り当てています。このコードは、外部に表示されるクエリ条件と折りたたまれたクエリ条件の両方に使用されるため、抽出されています。抽出後は、繰り返しロジックを記述する必要はありません。 抽出された成分は以下のとおりです /** * 入力ボックスが削除されたのはなぜですか? ここではテーブルクエリを実行するだけです。 * 実際には、ポップアップ ウィンドウ フレームのようなフォーム送信コンポーネントをカプセル化したい場合です。 ここでもロジックを再利用することができます* @param { Function } h h Vue が提供する関数* @param { Object } ユーザーが記述した項目説明オブジェクト* @param { Object } vm Vue インスタンス*/ エクスポートconst input = function (h, item, vm) { const { searchForm } = vm 戻る ( <el-form-item ラベル={item.label}> <el-入力 サイズ="小" 入力時に={(v) => { searchForm[item.__key] = v }} 小道具={{ 値: searchForm[item.__key], プレースホルダ:「コンテンツ情報を入力」 ...アイテム }} > </el-input> </el-form-item> ) } /** * * @param { Function } h h Vue が提供する関数* @param { Object } ユーザーが記述した項目説明オブジェクト* @param { Object } vm Vue インスタンス*/ エクスポートconst select = function (h, item, vm) { 定数{ 検索フォーム = {}, 選択オプション = {}, } = vm /** * ドロップダウンの変更イベントをリッスンします* @param { String | Number | Boolean } value ドロップダウンデータの値を選択します* @param { Object } value */ const selectChange = 関数 (値、項目) { searchForm[item.__key] = 値 vm.$emit('変更時', 値) } 戻る ( <el-form-item ラベル={item.label}> <el-選択 小道具={{ 値: searchForm[item.__key], プレースホルダー: "===選択してください===", フィルタ可能: true、 クリア可能: true、 ...アイテム }} 変更時={ (val) => { selectChange(val, item) } } サイズ="小"> { selectOption[item.__key] && selectOption[item.__key].map((o) => { 戻る ( <el-オプション キー={ o.値 } ラベル={o.text} 値={ o.value } > </el-option> ) }) } </el-select> </el-form-item> ) } /** * * 複数選択ドロップダウン ボックスの場合、単一選択メソッドに基づいて 2 つのプロパティを追加できます。このメソッドを記述することで、ユーザーは選択できる単語の数を減らすことができます。 * @param { Function } h h Vue が提供する関数* @param { Object } ユーザーが記述した項目説明オブジェクト* @param { Object } vm Vue インスタンス*/ エクスポートconst mulSelect = function (h, item, vm) { アイテム['複数'] = true 項目['collapse-tags'] = true select(h, item, vm) を返す } 上記は、実際には要素の複数のコンポーネントを独立したコンポーネントに抽出する方法です。外部コンポーネントで使用する場合、ユーザーが渡したタイプに応じて、対応するコンポーネントのレンダリングを直接一致させることができます。 また、後で新しいクエリ コンポーネントを追加する場合は、他の場所を変更せずに、ここで拡張するだけで済みます。 メンテナンスが容易になります。 さらに、デフォルトのドロップダウン検索機能やデフォルトのクリアボタンなど、コンポーネント内にいくつかのデフォルトの動作があります。システムで必要ない場合は、searchArr に対応する属性オーバーライドを記述することもできます。 components[o.__type] を返します ? components[o.__type](h, o, this) : '' 基本的なレンダリングが完了したら、外部のコンポーネントを使用します 検索Arr: [ { __type: '入力'、 ラベル: '名前', __key: '名前' }, { __type: '選択'、 ラベル: '性別'、 __キー: '性別'、 フェッチURL: '/getSelect', メソッド: 'post' // データ: [ // { テキスト: '男', 値: '1' }, // { テキスト: '女性'、値: '0' }, // ] }, ] 対応する模擬データを書き込む Mock.mock(/\/getSelect/, 'post', () => { 戻る { ステータス: 200、 成功: true、 メッセージ: 「成功を手に入れよう」 リスト: [ { テキスト: '男性'、 値: '1' }, { テキスト:「女性」 値: '2' } ]、 合計: データリストの長さ } }) はい、上記は配列の記述を通じて条件を単純にレンダリングします。 次に、クエリ パネルのクエリ条件をさらに作成する必要があります。 クエリと表示の最適化をさらに強化外部に表示されるクエリ条件は、ユーザーが指定した数だけ表示されます。ユーザーが指定したパラメータに応じて、1 行に複数のクエリを表示することもできます。 ================ 小道具 ================ /** * 表示される外部クエリ条件の数*/ フロントカウント: { タイプ: 数値、 デフォルト: 2 }, /** * 表示されるクエリ条件の数*/ バックカウント: { タイプ: 数値、 デフォルト: 3 } ================= プロップ終了 ================ =============== 計算 ================ // ページに表示されるクエリ条件 frontSearchArr: function () { this.searchArr.slice(0, this.frontCount) を返します }, // より多くのクエリに表示される条件 backSearchArr: function () { this.searchArr.slice(this.frontCount, this.searchArr.length) を返します }, // 幅を返す getSpan: function () { const yu = this.backSearchArr.length % this.backCount // 残り const duan = 24 / this.backCount // 各条件の幅 if (yu === 0) { 戻る 24 } それ以外 { リターン 24 - ドゥアン } } ================ 計算終了 ================ ============== レンダリング =============== <div スタイル={`幅: ${this.backCount * 265 + 30}px`} class={ this.moreShow ? `${className} fadeInDown` : `${className} fadeOutUp` } v-show={ this.moreShow }> <el-行> { バックサーチArr.map((o) => { 戻る ( <el-col span={24 / this.backCount}> { components[o.__type] ? components[o.__type](h, o, this) : '' } </el-col> ) }) } <el-col class="searchBtn" span={ getSpan } > <el-button size="small" type="primary" icon="el-icon-search" on-click={ queryTable }>クエリ</el-button> <el-button size="small" type="default" icon="el-icon-upload2" on-click={ () => { this.moreShow = !this.moreShow } }>縮小</el-button> </el-col> </el-row> </div> =============== レンダリング終了 =============== 計算プロパティに外部表示データと内部表示データを設定します。 データを 2 つの部分に分割します。検索コンポーネントの長さは 265 に固定されています。次に、条件に基づいてクエリ パネルの幅を計算し、getSpan 計算プロパティに基づいて各データ行のスパンの幅を計算します。クエリ ボタンと縮小ボタンは、クエリ条件の数に基づいて計算され、配置場所が決定されます。 テストの結果、効果は基本的に要件を満たしています。 プルダウンコンポーネントリンククエリたとえば、クエリ コンポーネントを使用して 3 レベルのリンクを記述する必要がある場合、どのように実装すればよいでしょうか。 州を選択したら、選択した州に基づいて対応する都市のドロップダウンデータを読み込む必要があります。 州を削除する場合は、対応する州と都市のドロップダウンをクリアする必要があります。 連携は主にこれら 2 つの機能に重点を置いています。 1 つは対応するデータをロードすること、もう 1 つは対応するデータをクリアすることです。では、何をする必要があるかがわかったので、実行してみましょう。 { __type: '選択'、 __key: '州'、 __fetchUrl: '/getProvince', __メソッド: 'get'、 __nextKey: '都市', __nextFetch: '/getCity', __nextParam: ['州'], __nextMethod: 'get'、 __emptyArr: ['都市', '地区'], ラベル: '州'、 ラベル幅: '40px', }, { __type: '選択'、 __キー: '都市', __メソッド: 'get'、 __nextKey: '地区', __nextFetch: '/getDistrict', __nextParam: ['州', '都市'], __nextMethod: 'get'、 __emptyArr: ['地区'], ラベル: '都市', ラベル幅: '40px', }, { __type: '選択'、 __key: '地区', ラベル: '地区', ラベル幅: '40px', } 州のデータを取得するには、__fetchUrl: '/getProvince' と __method: 'get' を記述してリクエスト インターフェイスを定義するだけで、ドロップダウン データを取得できます。 次に、州を選択してドロップダウンすると、変更イベントで選択した州に基づいてデータを要求する必要があります。この時点で、データの変更時に何を行う必要があるかを定義する必要があります。以下のコードを見てみましょう。 __nextKey: 'city', // どのドロップダウン データに値が割り当てられるか__nextFetch: '/getCity', // 割り当てのリクエスト インターフェイス__nextParam: ['province'], // リクエスト パラメータ__nextMethod: 'get', // リクエスト メソッド__emptyArr: ['city', 'district'] // ドロップダウン データが変更された場合、どのドロップダウン カテゴリをクリアする必要があるか/** * ドロップダウンの変更イベントをリッスンします* @param { String | Number | Boolean } value ドロップダウンデータの値を選択します* @param { Object } value */ const selectChange = 非同期関数 (値、項目) { searchForm[item.__key] = 値 // ドロップダウンリストとドロップダウンデータを空にする if (item && item.__emptyArr) { (i = 0 とします; i < item.__emptyArr.length; i++) { キーをitem.__emptyArr[i]とします。 if (selectOption[キー]) { selectOption[キー] = [] } vm.$set(検索フォーム、キー、'') } } if (item && item.__nextFetch && item.__nextParam) { パラメータを {} とします (j = 0 とします; j < item.__nextParam.length; j++) { 値 = searchForm[item.__nextParam[j]] とする if (値) { param[item.__nextParam[j]] = 値 } } const res = リクエストを待つ({ url: item.__nextFetch、 メソッド: item.__nextMethod || 'post' }, パラメータ) もし(res){ {データ} = resとします if (データ && data.success) { vm.$set(selectOption、item.__nextKey、data.list) を設定します。 } } } vm.$emit('変更時', 値) } これで、基本的に 3 レベルのリンク機能が完成しました。 以下は効果図です コンポーネント拡張コンポーネントの拡張は非常に簡単です。必要なコンポーネントがまだ不足している場合は、components.jsで直接新しいコンポーネントを追加できます。 /** * 日付ピッカー * @param {*} h * @param {*} アイテム * @param {*} 仮想メモリ */ エクスポートconst date = function (h, item, vm) { const { searchForm } = vm 戻る ( <el-form-item label={item.label} labelWidth={item.labelWidth}> <el-日付ピッカー 入力時に={(v) => { searchForm[item.__key] = v }} 小道具={{ タイプ: '日付'、 サイズ: 「小」、 値: searchForm[item.__key], プレースホルダー:「日付を選択」、 ...アイテム }} > </el-date-picker> </el-form-item> ) } // searchArrを使用する場合は{を追加 __type: '日付'、 __key: '誕生日'、 ラベル: '誕生日' } 新しいクエリ条件タイプの追加を完了するために他の変更は必要ありません。効果は次のとおりです。 検索条件表示検索条件機能は比較的単純で、ユーザーが検索をクリックした後、入力条件が表示されます。これを独立したウィジェットとして分離します。 <クエリ情報 ref="クエリ情報" on-remove={this.removeTag} 選択オプション={ this.selectOption }></クエリ情報> このコンポーネントは、ドロップダウン配列をコンポーネントに渡します。設計時に、クロスをクリックして条件を削除することもできると言ったので、削除カスタムイベントをスローする必要があります。条件を削除した後、条件をクリアしてクエリメソッドを呼び出します。クエリを実行するときは、コンポーネントが表示できるように、検索条件をコンポーネントに渡します。 ここで注意すべき点は、props を介して検索条件をコンポーネントに直接渡すことはできないということです。そうすると、データがレスポンシブであるため、条件を入力すると下に表示されますが、これは望ましくありません。私たちが望んでいるのは、クエリ ボタンをクリックしたときにクエリ条件を表示することです。そのため、ここでは、クエリ ボタン メソッドで内部メソッドを直接呼び出して条件を渡し、その後、内部で JSON.parse(JSON.stringify(val)) を使用してディープ コピーを実現し、データを外部データから分離します。 削除タグ (名前) { this.searchForm[名前] = '' this.queryTable() } // クエリ queryTable() { this.$refs.queryInfo && this.$refs.queryInfo.queryTable(this.searchForm) this.moreShow = false this.$emit('search', this.searchForm) } コンポーネントの実装は次のとおりです。 <テンプレート> <div class="クエリ情報"> <elタグ v-for="タグ内のタグ" :key="タグ" 閉じられる スタイル="margin-right: 10px;" @close="(タグ)を閉じる" > {{displayName(タグ)}} </el-tag> </div> </テンプレート> <スクリプト> '@/utils/utils' から { getTitle } をインポートします。 エクスポートデフォルト{ 小道具: { // ドロップダウンデータ選択オプション: { タイプ: オブジェクト、 デフォルト: () => [] } }, データ () { 戻る { // クエリ条件 searchForm: {} } }, 計算: { /// 入力条件配列タグを計算する: function () { タグを [] にする キーをObject.keys(this.searchForm)とします。 keys.forEach((キー) => { if (this.searchForm[キー]) { tags.push(キー) } }) リターンタグ } }, メソッド: { // クリックして閉じる close (tag) { this.searchForm[タグ] = '' this.$emit('remove', タグ) }, // 外部から呼び出されるメソッド queryTable (searchForm) { this.searchForm = JSON.parse(JSON.stringify(searchForm)) }, // 名前を表示します。ドロップダウンデータの場合は、ドロップダウンデータ内の名前と一致して表示されます。displayName(key) { 値 = this.searchForm[キー] if (this.selectionOption[キー]) { getTitle(値、this.selectionOption[key]) を返します } それ以外 { 戻り値 } } } } </スクリプト> <スタイルスコープ> .クエリ情報{ 下マージン: 10px; } </スタイル> 達成された効果は次のとおりです。 機能ボタンエリアを追加これは現在、スロットを使用してsearchTableコンポーネントに追加されています <div class="right"> {this.$slots.rightButton} </div> // <search-table :searchArr="searchArr" @search="search"> を使用します <テンプレート v-slot:rightButton> <el-ボタン サイズ="小" タイプ="成功" @click="() => { MessageBox({ message: '開発中', type: '警告' })}"> 追加</el-button> </テンプレート> </検索テーブル> コードをコピー 効果: 最後にこれまで、クエリコンポーネントが実現したいいくつかの機能が1つずつ実現されてきました。実際には、実行するのは複雑ではありません。最も重要な点は、実行することではなく、実行する前に明確に考えることです。後で、動的ヘッダーを完成させるので、テーブルに関連する要件は基本的に完了します。 私たちのオープンソース プロジェクトにスターを付けることもできます: http://github.crmeb.net/u/defu どうぞよろしくお願いいたします! これで、element-ui に基づいてクエリ コンポーネントを段階的にカプセル化する方法について説明したこの記事は終了です。より関連性の高い element-ui カプセル化クエリ コンポーネント コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: 画像プレビュー付きのアップロードフォームの完全な HTML
>>: MySQL 5.7 の /etc/my.cnf パラメータの紹介
この記事では、CentOS 7 環境でソース コードから MySQL 5.7 をインストールする方法...
目次序文インライン要素の中央揃えテキストを垂直に中央揃え要素を水平方向に中央揃えにするブロックレベル...
序文最近、プロジェクトで SQL Server を使用するプログラムに遭遇しました。このデータベース...
この記事では、ログインジャンプを実装するためのVueの具体的なコードを例として紹介します。具体的な内...
ここ数年、Web デザインには「全幅背景と固定幅コンテンツ」というトレンドが生まれています。このデザ...
Mysqlリモート接続構成を実装する2つの方法会社で働いていると、誰かのコンピュータに保存されている...
序文日常の開発では、MySQL を使用してページングを実装する場合、常に MySQL 制限構文を使用...
MySQL 外部キー制約 (FOREIGN KEY) はテーブルの特別なフィールドであり、主キー制約...
各 Web ページには、URL () で識別されるアドレスがあります。通常、Web サイト内でリンク...
目次1. SVNとは何か2. SVNサーバーとクライアントの取得方法3. SVN ワークフローとアー...
innodb_autoinc_lock_mode パラメータは、auto_increment 列を持...
1. 機能: 親コンポーネントが子コンポーネントの指定された位置に HTML 構造を挿入できるように...
この記事では、Element-uiを使用してメニューナビゲーションを実装するVueの具体的なコードを...
Vue プロジェクトで mock.js を使用する開発ツールの選択: Vscode 1. コマンドラ...
IE で ClearType をオンにした後に発生する透明フォントの問題を解決するには、透明要素に背...