コンポーネント-テーブルを、異常な方法で記述します

別の小さな記事の方が簡単です。 Vueでテーブルを描画する方法を説明します。



Vueには多くのテーブルコンポーネントがあります。 さまざまな機能を備えています。 また、さまざまな方法でテーブルがテンプレートページまたはコンポーネントに組み込まれます。



基本的には次のようになります。



<template> <cmp-table :items="items" :columns="columns"/> </template> <script> export default { name: 'page', data() { return { items: [ { id: 1, name: 'Sony' } , { id: 2, name: 'Apple' }, { id: 3, name: 'Samsung' } ], columns: [ { prop: 'id', title: 'ID' }, { prop: 'name', title: 'Name' } ] } } } </script>
      
      





ここでは、 cmp-tableコンポーネントデータ( items )と列設定( columns )を渡します 。 そして、コンポーネント自体はすでにこれらの設定のテーブルをレンダリングしています。

設定はすべての人のために整理されています。 列設定、またはヒープ内のすべてを分離するだけです-列設定、テーブル、一部のアクションなど



このアプローチでは、列のレンダリング設定を整理する方法が好きではありません。 theadテーブルのヘッダーにある名前と、列の内容の両方。

テンプレート自体でこの機能を確認し、そこに列(コンテンツとヘッダー)を作成します。 より視覚的で便利です。 私は。



たとえば、このアプローチは、今日最も人気のあるコンポーネントコレクションであるElementで使用されています。

そこでは次のようになります:



 <template> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="Date" width="180"/> <el-table-column prop="name" label="Name" width="180"/> <el-table-column prop="address" label="Address"/> </el-table> </template> <script> export default { name: 'page', data() { return { tableData: [{ date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' }, { date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles' }] } } } </script>
      
      





ここではすべてが明確です。 列とセルの一般的なビューをすぐに想像できます。 そして、 el-tableコンポーネントでは、テーブル自体のデータと設定のみを転送します。



そして、すべては何もないでしょう。 私は一般的に要素が好きです。 しかし、テーブルが遅くなっていることにしばしば気づきました。 私は彼らのコードに入りました。 そして、行、セル、その他すべてのレンダリングがどれほど混乱しているかということから、ofigel。 大量のコード。 そして、私は彼らと同じようにテーブルを作る方法を考え始めました。 はるかに簡単です。



今、私がやったことを教えて見せます。



最終的に私たちのコンポーネントになるものについてすぐに。 さらに理解しやすくするために:





テーブルは2つの部分で構成されます。



  1. TableColumnのコンポーネント-その助けを借りて、テーブルヘッダーとセルのビューを形成します
  2. テーブルコンポーネント-すべてが組み立てられ、レンダリングされます


TableColumnコンポーネント-または簡潔さがすべてです



table-column.js



 export default { name: 'vu-table-column', props: ['prop', 'title'] };
      
      





これは、 vu-table-columnという名前のVueコンポーネントといくつかの入力パラメーターです。





はい-コンポーネントの現在の要件を実装するために必要なのはこれだけです。 さらに、ここですべてが非常に単純である理由が明らかになります。



テーブルコンポーネント-または、可能性が少ない場合にコードを増やす理由



table.js
 import './style.scss' import { get } from 'lodash' export default { name: 'vu-table', props: { rows: { type: Array, required: true } }, methods: { renderColumns(h, row, columnsOptions) { return columnsOptions.map((column, index) => { return h('td', { class: 'vu-table__tbody-td' }, [ column.scopedSlot ? column.scopedSlot({row, items: this.rows}) : row[column.prop] ]) }) } }, render(h) { const columnsOptions = this.$slots.default.filter(item => { return (item.componentOptions && item.componentOptions.tag === 'vu-table-column') }).map(column => { return Object.assign({}, column.componentOptions.propsData, { scopedSlot: get(column, 'data.scopedSlots.default') } ) }) const columnsHead = columnsOptions.map((column, index) => { return h('th', { class: 'vu-table__thead-th', key: index}, column.title) }) const rows = this.rows.map((row, index) => { return h('tr', { key: index }, [ this.renderColumns(h, row, columnsOptions) ]) }) return h('table', { class: 'vu-table' }, [ h('thead', { class: 'vu-table__thead' }, [ h('tr', [ columnsHead ]) ]), h('tbody', { class: 'vu-table__tbody' }, [ rows ]) ]) } };
      
      







そして、コードを確認します。



 import './style.scss' import { get } from 'lodash' export default { name: 'vu-table', props: { rows: { type: Array, required: true } } ... }
      
      





まず、表スタイルをインポートします。



そして、ここではlodash get関数を使用します。 これは必要ありません。 彼女はコードを短くするためにここにいます。



次に、入力パラメーターrows 。データを文字列の配列として転送します。



レンダリング機能の場合:



 render(h) { const columnsOptions = this.$slots.default.filter(item => { return (item.componentOptions && item.componentOptions.tag === 'vu-table-column') }).map(column => { return Object.assign({}, column.componentOptions.propsData, { scopedSlot: get(column, 'data.scopedSlots.default') } ) }) const columnsHead = columnsOptions.map((column, index) => { return h('th', { class: 'vu-table__thead-th', key: index}, column.title) }) const rows = this.rows.map((row, index) => { return h('tr', { key: index }, [ this.renderColumns(h, row, columnsOptions) ]) }) return h('table', { class: 'vu-table' }, [ h('thead', { class: 'vu-table__thead' }, [ h('tr', [ columnsHead ]) ]), h('tbody', { class: 'vu-table__tbody' }, [ rows ]) ]) }
      
      





columnOptionsでは、列とセルの設定を構成します。

これを行うには、まず、 テーブルコンポーネントのデフォルトスロット( this。$ Slots.default )からvu-table-columnタグ( TableColumnコンポーネント)を持つすべての要素を収集し、フィルタリングします。



これまでのところ、便利で視覚的な方法で列設定を転送するためにのみTableColumnコンポーネントが必要です。 これが、 TableColumnに レンダリング関数がない理由です。 このコンポーネントをレンダリングしないためです。 データを取得するだけです。



そして、フィルタリングされたvu-table-columnの配列を調べて 、vu-table-columnからの入力小道具でオブジェクトの配列を形成し、 scopedSlotプロパティを追加します。 ページテンプレートのvu-table-columnに渡された場合、限られたスコープのデフォルトスロットを保存します(存在する場合)。 これは、このスロットの内容をレンダリングする関数です。 また、このスロットのテンプレートで使用されるパラメーターを渡すことができます。 このスロットは、カスタムタイプのセルに使用します。



次に、 columnsHead (テーブルヘッダーのセル)を収集します-上記で定義した列設定( columnOptions )を調べて、 title - vu-table-columnに渡した列の名前を引き出します



の配列(実際にはテーブルの最終行)を形成します-入力調べ 、各tr要素でrenderColumnsメソッドを使用してセルを表示します:



 renderColumns(h, row, columnsOptions) { return columnsOptions.map((column, index) => { return h('td', { class: 'vu-table__tbody-td' }, [ column.scopedSlot ? column.scopedSlot({row, items: this.rows}) : row[column.prop] ]) }) }
      
      





h-関数( vNodeレンダリングする $ createElement関数のエイリアス)をmethod 、rowデータ、 columnOptions設定の配列に渡します



そして、レンダリングするセルの配列を収集します。



要素配列をレンダリングするときは、各要素にキーパラメータを割り当てることを忘れないでください。 そうしないと、データを更新するときに、表示されたデータに衝突が生じる可能性があります。
そして、 レンダリング機能の最後に、ヘッダーセルが挿入された最終テーブルと、レンダリングされた行を表示します。

それだけです!



セルとヘッダーを描画するためのすべてのコードです。

さらに、フィルタリング、列の非表示/表示、ソート、および魂が望むすべてのものを貼り付けることはすでに可能です。 これは次の話です。 そして、それは次の記事にあります。 無限のテキストを書かないために。



そして、書かれたコンポーネントを使用する例:



example.vue
 <template lang="html"> <div> <vu-table :rows="rows"> <vu-table-column prop="id" title="ID"> <template slot-scope="{ row }"> <b>{{ row.id }}</b> </template> </vu-table-column> <vu-table-column prop="name" title="Name"/> <vu-table-column prop="rating" title="Rating"> <template slot-scope="{ row, items }"> {{ row.rating }} <b v-if="items.every(item => item.rating <= row.rating)">Best choie!</b> </template> </vu-table-column> </vu-table> </div> </template> <script> export default { name: 'example-page', data() { return { rows: [ { id: 1, name: 'Sony', rating: 777 }, { id: 2, name: 'Apple', rating: 555 }, { id: 3, name: 'Samsung', rating: 333 } ] } } }; </script>
      
      







ここでは、通常のタイトルとセルのカスタムルックの両方を使用します。



評価セルでは、 アイテムデータ( scopedSlot関数に渡され、文字列を含む受信配列を含む)と評価プロパティの値を使用して、現在の行が最高評価であるかどうかを判断します。 「はい」の場合、「最良の選択!」



そして、完成した結果:







最終的にそのようなコンポーネントが判明しました。



今は見ています。 機能を追加します。 次の記事では、機会の拡大について説明します。



All Articles