Vueコンポーネントにおけるthisの理解と活用

# はじめに
現在、`Vue.js`を用いて、Webアプリケーションを開発の勉強をしています。
今回は、`this`の使い方について「なるほど～(;'∀')」と思ったので、自分なりにまとめたいと思います。
これから始める人の参考にもなればと思います！

# thisの使い方
Vueコンポーネントインスタンス自身のことを`this`で指定し、コンポーネント内でデータプロパティやメソッドにアクセスする際に使用するそうです。
Vueコンポーネントでは、`data`オプションで定義したデータプロパティや、`methods`オプションで定義したメソッドはコンポーネントインスタンスに属するため、`this`を用いることで、これらにアクセスすることができるらしいです。よくわからない。

例えば、csvファイルを読み込むコンポーネントを作成する際に、読み込んだデータを格納するために`data`オプションを以下のように定義します。
```javascript
data() {
      return {
        csvData: [],
        fileName: '',
        columns: [],
      };
    }
```

このとき、`this.fileName = file.name;`は、コンポーネントの`data`オプションで定義した`fileName`データプロパティに、選択されたファイルの名前を代入していることになります。

このように、`this`を用いることで、コンポーネント内のデータやメソッドに簡単にアクセスすることができるので、コンポーネントの状態を管理し、テンプレートとの連携を実現することができます。

# 具体的な例
では、実際にcsvファイルを読み込んでデータを格納するコード例を示します。
```vue
<script>
  import { VueGoodTable } from 'vue-good-table-next';
  
  export default {
    components: {
      VueGoodTable,
    },
    data() {
      return {
        csvData: [],
        fileName: '',
        columns: [],
      };
    },
    methods: {
      handleFileUpload(event) {
        const file = event.target.files[0];
        this.fileName = file.name;
        const reader = new FileReader();
  
        reader.onload = () => {
          const csvContent = reader.result;
          const rows = csvContent.split('\n');
          this.columns = rows[0].split(',').map((header) => ({
            label: header,
            field: header,
          }));
          this.csvData = rows.slice(1).map((row) => {
            const rowData = {};
            row.split(',').forEach((cell, index) => {
              rowData[this.columns[index].field] = cell;
            });
            return rowData;
          });
        }; 
        reader.readAsText(file);
      },
    },
  };
  </script>
```

`methods`でファイルがアップロードされたときのメソッドを書いています。
ここでは、`this`以外のコードについても解説しようと思います。

`handleFileUpload(event)`では、ファイルが選択された際に呼び出されるメソッドを書いていますが、
- `const file = event.target.files[0];`：選択されたファイルを取得
- `this.fileName = file.name;`：選択されたファイル名を`fileName`に設定
- `const reader = new FileReader();`：ファイルを読み込むための`FileReader`オブジェクトを作成

と処理が進みます。その後、`reader.onload = () =>`でファイルの読み込みが完了した際に実行される関数を定義します。
- `const csvContent = reader.result;`：読み込まれたcsvファイルの内容を取得
- `const rows = csvContent.split('\n');`：csvデータを行ごとに分割
- `this.columns = ...`：csvファイルのヘッダー行からカラム情報を生成し、`columns`に設定
- `this.csvData = ...`：csvデータの各行をオブジェクトに変換し、`csvData`に設定

最後に`reader.readAsText(file;)`で選択されたファイルをテキストとして読み込ませ、テーブルを表示します。

また、csvファイルからカラム情報を生成したり、各行をオブジェクトに変換する部分は少し難しいのでもう少しかみ砕いて説明します。

```javascript
this.columns = rows[0].split(',').map((header) => ({
    label: header,
    field: header,
}));
```
上記のコードでは、csvファイルのヘッダー行からカラム情報を生成し、`columns`に代入しています。
以下詳細な順序です。
1. csvデータは改行文字で区切られた文字列として読み込まれ、rows配列にそれぞれの行が格納されます。そのため、`rows[0]`は、csvデータの最初の行を取得していることになります。
1. `.split(',')は、最初の行をカンマで分割します。これにより、csvのヘッダー行がカラムごとに分割されることになります。
1. `.map((header) => ({...})`は、分割されたヘッダーの各要素に対して、新しいオブジェクトを生成します。
    - `(header) => ({...})`は、アロー関数を用いて、各ヘッダーに対して実行される処理を定義
    - `{label: header, field: header}`は、各ヘッダーに対して、`label`と`field`プロパティを持つオブジェクトを生成
それぞれのプロパティには、ヘッダーの値をそのまま代入しています。

この処理によって、csvファイルのヘッダー行からテーブルのカラム情報が生成されることになります。

例えば、csvファイルの最初の行が、`"Name,Age,City"`だったとしたら次のように処理が進みます。
1. `rows[0]`は、"Name,Age,City"を取得
1. `.split(',')`により、["Name", "Age", "City"]に分割
1. `.map((header) => ({ ... }))`により、次のようなオブジェクトの配列が生成
```javascript
[
  { label: "Name", field: "Name" },
  { label: "Age", field: "Age" },
  { label: "City", field: "City" }
]
```
わかりやすいですね。

では、次に各行をオブジェクトに変換する部分について説明します。
```javascript
this.csvData = rows.slice(1).map((row) => {
  const rowData = {};
  row.split(',').forEach((cell, index) => {
    rowData[this.columns[index].field] = cell;
  });
  return rowData;
});
```
1. `rows.slice(1)`は、rows配列の2番目の要素（インデックス1）から最後の要素までを取得します。これにより、CSVファイルのヘッダー行を除いたデータ行だけが選択されます。
1. `.map((row) => { ... })`は、選択されたデータ行に対して、新しいオブジェクトを生成します。
1. `(row) => { ... }`は、アロー関数を使用して、各データ行に対して実行される処理を定義しています。
1. `const rowData = {};`は、各データ行を表すオブジェクトを初期化しています。このオブジェクトは、列名をキーとして、対応するセルの値を格納します。
1. `row.split(',').forEach((cell, index) => { ... })`は、データ行をカンマで分割し、各セルに対して処理を行います。
    - `(cell, index) => { ... }`は、アロー関数を使用して、各セルに対して実行される処理を定義しています。
    - `rowData[this.columns[index].field] = cell;`は、`this.columns`の対応するインデックスの`field`プロパティをキーとして、`rowData`オブジェクトにセルの値を代入しています。
        - `this.columns[index].field`は、先ほど生成されたカラム情報の配列から、現在の列のインデックスに対応する`field`プロパティを取得しています。
        - `cell`は、現在のセルの値を表します。
1. `return rowData;`は、生成されたオブジェクトを返します。

こちらでも、たとえばcsvファイルの2行目が`"John,25,New York"`だったとします。
1. `rows.slice(1)`で、`["John,25,New York", ...]`のようなデータ行の配列が選択。
1. `.map((row) => { ... })`により、各データ行に対して以下の処理が実行。
1. `const rowData = {};`で、空のオブジェクトが初期化。
1. `row.split(',').forEach((cell, index) => { ... })`で、データ行が`["John", "25", "New York"]`に分割され、各セルに対して以下の処理が実行。
    - `rowData[this.columns[index].field] = cell;`により、`rowData`オブジェクトに、対応するカラムの`field`プロパティをキーとして、セルの値が代入。
        - 例えば、`rowData["Name"] = "John", rowData["Age"] = "25", rowData["City"] = "New York"`のようになる。

# まとめ
細かい部分も書いているとかなり長くなってしまいました。
ごめんなさい( ;∀;)
最初は、何書いてんだ(´・ω・｀)
って感じで理解しようとしませんでしたが、1文1文理解して言語化することでぼんやりと何をやっているかはわかってきました。
やっぱり落ち着いて読めば理解は難しくないですね(/・ω・)/

今回は`this`の使い方を中心に、周辺のコードの意味も併せてまとめてみました。
いかがだったでしょうか。
初心者故の糞コードになっているかもしれませんが、目を瞑っていただけると飛んで喜びます。
または、アドバイスをいただけると地面にのめりこむ程頭を下げます。
だれかしらの役に立てれば幸いです。
今後も、基礎的な部分かもしれませんが、インプットアウトプット続けてVue.jsを使いこなせるようにガンパりたいと思います！
それでは！！！