Vue Element UI カスタム説明リストコンポーネント

Vue Element UI カスタム説明リストコンポーネント

この記事の例では、Vue Element UIカスタム説明リストコンポーネントの具体的なコードを参考までに共有しています。具体的な内容は次のとおりです。

レンダリング

前面に書かれた

バックエンド管理を書くとき、リストをクリックして詳細を表示し、データ情報を表示することがよくあります。Element UI にはテーブルコンポーネントがありますが、説明コンポーネントがありません。以前は、このような状況に遭遇すると、チームメンバーが独自のスタイルを記述する必要があり、記述が面倒で、各人が記述したスタイルが統一されておらず、プロジェクト全体のスタイルが崩れていました。
例えば、Ant Design UI には、非常に使いやすい説明コンポーネントがあるので、Element UI の el-row と el-col を組み合わせて自分で簡単に記述しました。

どのような機能が実装されているか

1. 各行の高さは、行内の列の最大高さに応じて自動的に拡張されます。
2. 最後の列が不完全にならないように列幅を自動的に補完する
3. プレーンテキストとHTMLスロットをサポート
4. 1行に複数の列を設定できる
5. 各列幅のカスタマイズをサポート
6. 動的なデータの再描画をサポート

コンポーネント設計

1. 親子コンポーネントのネストを使用します。親コンポーネントは e-desc、子コンポーネントは e-desc-item です。
2. e-desc-itemはpropsのラベルとスロットの値を渡し、$slots.contentを使用してDOMを表示します。
3. el-rowとel-colを使用してコンポーネント全体のレイアウトを実装する

e-descコンポーネントをカプセル化する

<テンプレート>
  <div class="desc" :style="{margin}">
    <!-- タイトル -->
    <h1 v-if="タイトル" class="desc-title" v-html="タイトル"></h1>
    <el-row クラス="desc-row">
      <スロット/>
    </el-row>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: 'EDesc',
  // provide() を通じて子コンポーネントに提供される {
    戻る {
      ラベル幅: this.labelWidth、
      列: this.column、
      サイズ: this.size
    }
  },
  小道具: {
    // データソース、データのリッスンとデータの再描画: {
      タイプ: オブジェクト、
      必須: true、
      デフォルト () {
        戻る {}
      }
    },
    // タイトル: {
      タイプ: 文字列、
      デフォルト: ''
    },
    // マージン: {
      タイプ: 文字列、
      デフォルト: '0'
    },
    // ラベルの幅 labelWidth: {
      タイプ: 文字列、
      デフォルト: '120px'
    },
    カラム: {
      // 行ごとに表示される項目の数 タイプ: [数値、文字列]、
      デフォルト: 3
    },
    サイズ: {
      // サイズタイプ: 文字列、
      デフォルト: ''
    }
  },
  時計:
    データ: {
      ハンドラ(){
        this.$nextTick(() => {
          // サブコンポーネント e-desc-item を除外する
          const データソース = this.$slots.default
          定数データリスト = []
          dataSource.forEach(アイテム => {
            if (item.componentOptions && item.componentOptions.tag === 'e-desc-item') {
              データリストをプッシュします(item.componentInstance)
            }
          })
          // 残りのスパン
          leftSpan = this.column とします
          const len ​​= データリスト.長さ
          dataList.forEach((アイテム、インデックス) => {
            // 列とスパンの関係を処理する // 残りの列の数は、設定されたスパンの数より少ない const hasLeft = leftSpan <= (item.span || 1)
            // 現在の列の次の列が残りの範囲より大きい
            const nextColumnSpan = (index < (len - 1)) && (dataList[index + 1].span >= leftSpan)
            // 最後の行の最後の列 const isLast = index === (len - 1)
            if (hasLeft || nextColumnSpan || isLast) {
            // 上記の条件が満たされた場合、最後の列が不完全になるのを避けるために、span を自動的に完了する必要があります。item.selfSpan = leftSpan
              leftSpan = this.column
            } それ以外 {
              左スパン -= アイテム.スパン || 1
            }
          })
        })
      },
      深い:本当、
      即時: 真
    }
  }
}
</スクリプト>

<スタイル スコープ lang="scss">
  .desc{
    .desc-title {
      下マージン: 10px;
      色: #333;
      フォントの太さ: 700;
      フォントサイズ: 16px;
      行の高さ: 1.5715;
    }
    .desc-row{
      ディスプレイ: フレックス;
      flex-wrap: ラップ;
      境界線の半径: 2px;
      境界線: 1px 実線 #EBEEF5;
      下境界線: 0;
      右境界線: 0;
      幅: 100%;
    }
  }
</スタイル>

e-desc-itemコンポーネントをカプセル化する

<テンプレート>
  <el-col :span="計算されたスパン" class="desc-item">
    <div class="desc-item-content" :class="size">
      <label class="desc-item-label" :style="{width: labelWidth}" v-html="label"></label>
      <div class="desc-item-value" v-if="$slots">
        <!-- プレーンテキスト -->
        <スロット v-if="$slots.default && $slots.default[0].text"/>
        <!-- HTML -->
        <スロット名="コンテンツ" v-else-if="$slots.content"/>
        <span v-else>データがありません</span>
      </div>
    </div>
  </el-col>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: 'EDescItem',
  挿入: ['labelWidth', 'column', 'size'],
  小道具: {
    スパン: {
      タイプ: [数値、文字列],
      必須: false、
      デフォルト: 0
    },
    ラベル: {
      タイプ: 文字列、
      必須: false、
      デフォルト: ''
    }
  },
  データ () {
    戻る {
      // サブコンポーネント自身のスパン
      自己スパン: 0
    }
  },
  計算: {
    計算されたスパン() {
      // 子コンポーネントのスパンは親コンポーネントによってスパンの計算と変更に使用されます
      if (this.selfSpan) {
        24 / this.column * this.selfSpan を返す
      } それ以外の場合は (this.span) {
      // プロパティによって渡されるスパン
        24 / this.column * this.span を返す
      } それ以外 {
      // spanが渡されない場合は列を取得します
        24 / this.column を返す
      }
    }
  }
}
</スクリプト>

<スタイル スコープ lang="scss">
  .desc-item {
    右境界線: 1px 実線 #EBEEF5;
    下境界線: 1px 実線 #EBEEF5;
    .desc-item-content {
      ディスプレイ: フレックス;
      コンテンツの配置: flex-start;
      アイテムの位置を中央揃えにします。
      色: rgba(0,0,0,.65);
      フォントサイズ: 14px;
      行の高さ: 1.5;
      幅: 100%;
      背景色: #fafafa;
      高さ: 100%;
      .desc-item-label{
        右境界線: 1px 実線 #EBEEF5;
        表示: インラインブロック;
        パディング: 12px 16px;
        フレックス成長: 0;
        フレックス収縮: 0;
        色: rgba(0, 0, 0, 0.6);
        フォントの太さ: 400;
        フォントサイズ: 14px;
        行の高さ: 1.5;
        高さ: 100%;
        ディスプレイ: フレックス;
        アイテムの位置を中央揃えにします。
      }
      .desc-item-value{
        背景: #fff;
        パディング: 12px 16px;
        フレックス成長: 1;
        オーバーフロー: 非表示;
        単語区切り: 全区切り;
        高さ: 100%;
        ディスプレイ: フレックス;
        アイテムの位置を中央揃えにします。
        色: #444;
        スパン{
          色: #aaa;
        }
      }
      &。小さい {
        .desc-item-label、
        .desc-item-value {
          パディング: 10px 14px;
        }
      }
    }
  }
</スタイル>

使い方

<テンプレート>
  <e-desc :data='info' margin='0 12px' label-width='100px'>
    <e-desc-item label="名前">{{info.name}}</e-desc-item>
    <e-desc-item label="年齢">{{ info.age }} 歳</e-desc-item>
    <e-desc-item label="性別">{{ info.sex }}</e-desc-item>
    <e-desc-item label="学校">{{ info.school }}</e-desc-item>
    <e-desc-item label="プロフェッショナル">{{ info.major }}</e-desc-item>
    <e-desc-item label="趣味">{{ info.hobby }}</e-desc-item>
    <e-desc-item label="携帯電話番号">{{ info.phone }}</e-desc-item>
    <e-desc-item label="微信">{{ info.wx }}</e-desc-item>
    <e-desc-item label="QQ">{{ info.qq }}</e-desc-item>
    <e-desc-item label="住所">{{ info.address }}</e-desc-item>
    <e-desc-item label="自己説明" :span='2'>{{ info.intro }}</e-desc-item>
    <e-desc-item label="操作" :span='3'>
      <テンプレートスロット="コンテンツ">
        <el-button size="small" type="primary">変更</el-button>
        <el-button size="small" type="danger">削除</el-button>
      </テンプレート>
    </e-desc-item>
  </e-desc>
</テンプレート>

<スクリプト>
'./e-desc' から EDesc をインポートします
'./e-desc-item' から EDescItem をインポートします。
エクスポートデフォルト{
  コンポーネント:
    EDesc、EDescItem
  },
  データ () {
    戻る {
      情報:
        名前: 'ジェリー'、
        年齢: 26歳
        性別: '男性'、
        学校: '四川大学'、
        専攻:「プロフェッショナル コーダー」
        住所: '四川省成都市'、
        趣味: 「レンガを動かすこと、フロントエンド、お金を稼ぐこと」
        電話番号: 18888888888、
        wx: 'Nice2cu_Hu',
        QQ: 332983810、
        イントロ: 「私は画家です。絵を描くのが得意です。」新しい家をもっと美しくするために塗装したいです。屋根を塗った後、彼は筆を忙しく飛ばしながら壁を塗った。ああ、私の小さな鼻は変わってしまった。私は画家であり、優れた絵画技術を持っています。新しい家をもっと美しくするために塗装したいです。屋根を塗った後、彼は筆を忙しく飛ばしながら壁を塗った。ああ、私の小さな鼻は変わってしまった。 '
      }
    }
  }
}
</スクリプト>

パラメータの説明

この時点でコードは完成しています。何か不備やバグなどありましたら、メッセージを残してお知らせください。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Element-ui レイアウト (行と列コンポーネント) の実装
  • el-row列レイアウトの使用に関するElement-UIチュートリアル
  • 要素 el-row el-col レイアウト コンポーネントの詳細な説明

<<:  Linuxアカウントファイル制御管理の詳細な手順

>>:  MySQL でプロファイルを使用する方法のチュートリアル

推薦する

VMware pro15 インストール macOS10.13 詳細インストール図(画像とテキスト)

編集者は最近、macOS システムを使い始めたかったので、VMware に macOS イメージ シ...

MySQLのビューの詳細な説明

ビュー: MySQL のビューはテーブルと多くの類似点があります。ビューも複数のフィールドと複数のレ...

Vant+postcss-pxtoremはブラウザ適応機能を実装します

Remレイアウトの適応Vant のスタイルでは、デフォルトで px を単位として使用します。rem ...

Vue の匿名スロットと名前付きスロットの詳細な説明

目次1. 匿名スロット2. 名前付きスロット要約するスロット (slot) は、Vue のコンテンツ...

広告を閉じる効果を実現するJavascript

参考までに、Javascript を使用して広告を閉じる方法に関するケース スタディを示します。詳細...

Vueバスの簡単な使い方

Vueバスの簡単な使い方シナリオの説明:コンポーネント A にはコンポーネント B と C が含まれ...

CSS 3D からソースコードによる空間座標軸へ

かつて、サイコロを振るゲームについて話しました。その時は、steps 属性 + スプライト画像を使用...

HTMLはマーキーを使用してテキストを左右にスクロールします

コードをコピーコードは次のとおりです。 <本文> //マーキーの助けを借りて<MA...

js を使用してファイルが UTF-8 でエンコードされているかどうかを判断する方法

従来の解決策FileReader を使用して UTF-8 形式のファイルを読み取り、ファイルの内容に...

SSL で Nginx リバース プロキシを構成する簡単な手順

序文リバース プロキシは、Web 経由で行われたリクエスト (http と https の両方) を...

MySQL の左結合操作における on 条件と where 条件の違いの紹介

優先度両方のケースで同じ条件を設定すると、異なる結果セットが生成される可能性があるのは、優先順位のた...

ウェブページを作成するために最もよく使用されるHTMLタグ

1. よく使われるHTMLタグの最適化HTML は Web 編集者にとって基本的なスキルであるべきで...

MySQLはinit-connectを使用してアクセス監査機能の実装を増やします

まず init-connect を通じて mysql 接続を初期化し、次にインスタンスに接続する必要...

Linux または Android でファイル システムを追加する属性インターフェイスを解析する方法

最初のもの: 1. 主要なヘッダーファイルを追加します。 #include <linux/of...

シンプルなショッピングカート機能を実現するjs

この記事の例では、簡単なショッピングカート機能を実現するためのjsの具体的なコードを参考までに共有し...