TechVue.jsJapanese

[ Vue.js ] b-table の行選択を可能にし、 選択した行 データ を取得する サンプル コード

Tech

BootstrapVue の b-table を用いて特定の行を選択し、選択した行データの内容を取得し、画面に表示する サンプル コード を説明します。


使用する データ

[ads]

出発地点は、以下の コード とします。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">b-table</span>
<span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span>
<span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span>
></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">b-table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span> <span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span> ></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<template>
  <div>
    <b-table
      class="text-left"
      :items="items"
    ></b-table>
  </div>
</template>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<script>
export <span class="hljs-keyword">default</span> {
data() {
<span class="hljs-keyword">return</span> {
items: <span class="hljs-keyword">null</span>,
}
},
created() {
<span class="hljs-keyword">this</span>.items = DATA
}
}
<span class="hljs-keyword">const</span> DATA = [
{ <span class="hljs-built_in">year</span>: <span class="hljs-number">2019</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">2</span>, sports_event: <span class="hljs-string">'2019 AFC Asian Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2019_AFC_Asian_Cup'</span> },
{ <span class="hljs-built_in">year</span>: <span class="hljs-number">2019</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">7</span>, sports_event: <span class="hljs-string">'2019 FIFA Women\'s World Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2019_FIFA_Women%27s_World_Cup'</span> },
{ <span class="hljs-built_in">year</span>: <span class="hljs-number">2021</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">1</span>, sports_event: <span class="hljs-string">'2020 African Nations Championship Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2020_African_Nations_Championship'</span> },
{ <span class="hljs-built_in">year</span>: <span class="hljs-number">2021</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">2</span>, sports_event: <span class="hljs-string">'2020 FIFA Club World Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2020_FIFA_Club_World_Cup'</span> },
{ <span class="hljs-built_in">year</span>: <span class="hljs-number">2021</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">7</span>, sports_event: <span class="hljs-string">'UEFA Euro 2020 Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/UEFA_Euro_2020'</span> },
{ <span class="hljs-built_in">year</span>: <span class="hljs-number">2022</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">12</span>, sports_event: <span class="hljs-string">'2022 FIFA World Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2022_FIFA_World_Cup'</span> },
]
</script>
<script> export <span class="hljs-keyword">default</span> { data() { <span class="hljs-keyword">return</span> { items: <span class="hljs-keyword">null</span>, } }, created() { <span class="hljs-keyword">this</span>.items = DATA } } <span class="hljs-keyword">const</span> DATA = [ { <span class="hljs-built_in">year</span>: <span class="hljs-number">2019</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">2</span>, sports_event: <span class="hljs-string">'2019 AFC Asian Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2019_AFC_Asian_Cup'</span> }, { <span class="hljs-built_in">year</span>: <span class="hljs-number">2019</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">7</span>, sports_event: <span class="hljs-string">'2019 FIFA Women\'s World Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2019_FIFA_Women%27s_World_Cup'</span> }, { <span class="hljs-built_in">year</span>: <span class="hljs-number">2021</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">1</span>, sports_event: <span class="hljs-string">'2020 African Nations Championship Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2020_African_Nations_Championship'</span> }, { <span class="hljs-built_in">year</span>: <span class="hljs-number">2021</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">2</span>, sports_event: <span class="hljs-string">'2020 FIFA Club World Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2020_FIFA_Club_World_Cup'</span> }, { <span class="hljs-built_in">year</span>: <span class="hljs-number">2021</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">7</span>, sports_event: <span class="hljs-string">'UEFA Euro 2020 Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/UEFA_Euro_2020'</span> }, { <span class="hljs-built_in">year</span>: <span class="hljs-number">2022</span>, <span class="hljs-built_in">month</span>: <span class="hljs-number">12</span>, sports_event: <span class="hljs-string">'2022 FIFA World Cup Final'</span>, url: <span class="hljs-string">'https://en.wikipedia.org/wiki/2022_FIFA_World_Cup'</span> }, ] </script>
<script>
export default {
  data() {
    return {
      items: null,
    }
  },
  created() {
    this.items = DATA
  }
}

const DATA = [
  { year: 2019, month: 2, sports_event: '2019 AFC Asian Cup Final', url: 'https://en.wikipedia.org/wiki/2019_AFC_Asian_Cup' },
  { year: 2019, month: 7, sports_event: '2019 FIFA Women\'s World Cup Final', url: 'https://en.wikipedia.org/wiki/2019_FIFA_Women%27s_World_Cup' },
  { year: 2021, month: 1, sports_event: '2020 African Nations Championship Final', url: 'https://en.wikipedia.org/wiki/2020_African_Nations_Championship' },
  { year: 2021, month: 2, sports_event: '2020 FIFA Club World Cup Final', url: 'https://en.wikipedia.org/wiki/2020_FIFA_Club_World_Cup' },
  { year: 2021, month: 7, sports_event: 'UEFA Euro 2020 Final', url: 'https://en.wikipedia.org/wiki/UEFA_Euro_2020' },
  { year: 2022, month: 12, sports_event: '2022 FIFA World Cup Final', url: 'https://en.wikipedia.org/wiki/2022_FIFA_World_Cup' },
]
</script>

この状態では、表の行を クリック しても選択された状態にはなりませんので、行を選択可能な状態にしていきます。


行を選択可能に

[ads]

select-mode プロパティ

ここでは、 select-mode prop を活用します。 select-mode プロパティには以下の3つの値が指定できます。今回は single を使っていきます。

  • multi: クリック の度に選択、解除。(デフォルト)
  • single: 1 行のみ選択可能
  • range: shift + クリック や Ctrl (Cmd) + クリック で複数行の選択も可能になる

selectable プロパティ

select-mode プロパティを使うためには、 兎にも角にも行を選択可能にしなければいけません。行を選択可能にするためには selectable プロパティ を使います。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">b-table</span>
<span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span>
<span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span>
<span class="hljs-attr">selectable</span>
></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">b-table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span> <span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span> <span class="hljs-attr">selectable</span> ></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<template>
  <div>
    <b-table
      class="text-left"
      :items="items"
      selectable
    ></b-table>
  </div>
</template>

これで以下のとおり、 デフォルト 動作である multi の動作になります。 試しに shift + クリック をしても、 複数行 は選択できません。

select-mode=”single”

次に、 select-mode に single を指定します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">b-table</span>
<span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span>
<span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span>
<span class="hljs-attr">select-mode</span>=<span class="hljs-string">"single"</span>
<span class="hljs-attr">selectable</span>
></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">b-table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span> <span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span> <span class="hljs-attr">select-mode</span>=<span class="hljs-string">"single"</span> <span class="hljs-attr">selectable</span> ></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<template>
  <div>
    <b-table
      class="text-left"
      :items="items"
      select-mode="single"
      selectable
    ></b-table>
  </div>
</template>

同時に 1 行しか選択できないように、振る舞いが変化しました。

‘single’ not defined

当初、 ‘select-mode’ に ‘singel’ や ‘multi’ を指定しても、 ‘single’ is not defined というエラーが出ていました。 以下のサイトを参考に、 primary-key を追加してみたら、 エラー が消え、その後、 primary-key を削除しても意図通り動作するようになりました。 詳細は調査しきれてないですが、 もし同様のエラーが出たら参考にしていただければと思います。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<<span class="hljs-keyword">template</span>>
<div>
<b-<span class="hljs-keyword">table</span>
<span class="hljs-keyword">class</span>="text-left"
:items="items"
selectable
<span class="hljs-keyword">select</span>-mode="single"
<span class="hljs-keyword">primary</span>-key="url"
></b-<span class="hljs-keyword">table</span>>
</div>
</<span class="hljs-keyword">template</span>>
<<span class="hljs-keyword">template</span>> <div> <b-<span class="hljs-keyword">table</span> <span class="hljs-keyword">class</span>="text-left" :items="items" selectable <span class="hljs-keyword">select</span>-mode="single" <span class="hljs-keyword">primary</span>-key="url" ></b-<span class="hljs-keyword">table</span>> </div> </<span class="hljs-keyword">template</span>>
<template>
  <div>
    <b-table
      class="text-left"
      :items="items"
      selectable
      select-mode="single"
      primary-key="url"
    ></b-table>
  </div>
</template>


選択行の情報を取得

[ads]

row-selected イベント

それでは、選択した 1 行の データ を取得していきます。 まずは、いまの状態での Vue の振る舞いを Chrome の Dev Tools でみていきます。

公式 サイト に以下の記載があるとおり、 row-selected イベントが発生しています。 具体的には、選択の度に、 row-clicked と row-selected の2つが発生していることがわかります。

When a table is selectable and the user clicks on a row, will emit the row-selected event, passing a single argument which is the complete list of selected items. Treat this argument as read-only.

https://bootstrap-vue.org/docs/components/table#row-select-support

BTable data.selectedRows

以下のとおり、 BTable の data 配下の selectedRows の選択した行と同じ Index に “true” が設定されることがわかります。

3行目(Index=2)を選択
4行目(Index=3)を選択

@row-select で イベント を拾う

それでは、最後に選択した行データを @row-selecteed を用いて、表示用の データプロパティ に格納し、画面に表示してみます。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">b-table</span>
<span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span>
<span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span>
<span class="hljs-attr">selectable</span>
<span class="hljs-attr">select-mode</span>=<span class="hljs-string">"single"</span>
@<span class="hljs-attr">row-selected</span>=<span class="hljs-string">"onRowSelected"</span>
></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span>
</span><span class="hljs-template-variable">{{ selected }}</span><span class="xml">
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span></span>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">b-table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-left"</span> <span class="hljs-attr">:items</span>=<span class="hljs-string">"items"</span> <span class="hljs-attr">selectable</span> <span class="hljs-attr">select-mode</span>=<span class="hljs-string">"single"</span> @<span class="hljs-attr">row-selected</span>=<span class="hljs-string">"onRowSelected"</span> ></span><span class="hljs-tag"></<span class="hljs-name">b-table</span>></span> </span><span class="hljs-template-variable">{{ selected }}</span><span class="xml"> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span></span>
<template>
  <div>
    <b-table
      class="text-left"
      :items="items"
      selectable
      select-mode="single"
      @row-selected="onRowSelected"
    ></b-table>
    {{ selected }}
  </div>
</template>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-builtin-name">export</span><span class="hljs-built_in"> default </span>{
data() {
return {
items: <span class="hljs-literal">null</span>,
selected: [],
}
},
methods: {
onRowSelected(items) {
this.selected = items
},
},
created() {
this.items = DATA
}
}
<span class="hljs-builtin-name">export</span><span class="hljs-built_in"> default </span>{ data() { return { items: <span class="hljs-literal">null</span>, selected: [], } }, methods: { onRowSelected(items) { this.selected = items }, }, created() { this.items = DATA } }
export default {
  data() {
    return {
      items: null,
      selected: [],
    }
  },
  methods: {
    onRowSelected(items) {
      this.selected = items
    },
  },
  created() {
    this.items = DATA
  }
}

これで、選択した行のデータを取得し、画面に表示することができました。


まとめ

[ads]
  • b-table の select-mode プロパティ を使って、 単一選択、 複数選択 を切り替える
  • @row-select で イベント を拾うことで、 選択行のデータを取得可能

関連記事

[ads]
Ads