VueJSでJSONをきれいに出力する方法

WailsとVue.jsでECSリリースツールの実装をしています。
あまりjsをガシガシ書いてこなかったので、勉強しながら記事を書いています。
自己的なメモになりますので大した内容になっていません、すみません:tea:
間違っている箇所がありましたら、ご指摘ください！

# TODO
* textareaにJSONを出力

# 前提
| 技術  |
| ---- |
|  Vue.js 2系  |
|  macOS Catalina 10.15.7  |

# 事象
ECSのタスク定義をVueテンプレートに表示できなかった。
つまづいた点は2つです。

* 1. <code>\<textarea\>{{ecs.task}}\</textarea\></code>はできない
 * pタグだとobjectでも出力できていた→同様にできると思った
* 2. JSONをstringにキャストする方法を知らなかった

```vuejs:間違えた方法
<template>
  <div class="container">
    <!-- ECS -->
    <h3>ECSの現在</h3><hr>
    <textarea>{{ecs.task}}<textarea/>
    <!-- [元凶] 下記だと文字として表示 -->
    <p>{{ecs.task}}<p/>
    <p>タスクリソース名：{{ecs.taskarn}}</p>
    <p>タスク定義した人：{{ecs.taskupdater}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      ecs: {
        task: "",
        taskarn: "",
        taskupdater: "",
      }
    };
  },
  methods: {
    getECSTask: function() {
      var self = this;
      window.backend.ECS.GetTask().then(result => {
        let td = result.TaskDefinition;
        // Objectのまま変数に入れてしまった
        self.ecs.task = td;
        self.ecs.taskarn = td.TaskDefinitionArn;

        let brf = td.RegisteredBy;
        if (brf !== null || typeof(brf) !== undefined) {
          self.ecs.taskupdater = brf.replace(/arn:aws:iam::(\d+):user\//, '');
        }
      });
    }
  },
  beforeMount() {
    this.getECSTask();
  }
};
</script>
```

# 解決

## 1つ目の問題
* 二重中括弧は<code>プレーンテキストとして扱われる</code>
* <code>v-model</code>はデータバインディングを作成する
 * 基本的にはユーザ入力データを更新するための使われる
 * textarea/selectなどにつかわれる

## 2つ目の問題
* JSONをstringに変換するには<code>JSON.stringify</code>を使う
 * 第2引数=>結果をどう変換するか（好きな形に変えられるコールバック）
 * 第3引数=>数値指定

JSONのインデントは2つ派なので、第3引数に2を指定しました。
空白を指定する人もいるそうで、<code>\t</code>でタブでもいいかもですね！

```ts:
/**
 * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
 * @param value A JavaScript value, usually an object or array, to be converted.
 * @param replacer A function that transforms the results.
 * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
 */
stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
```

# 結論
上記を踏まえた結果こうなりました。
Vueって書きやすくてよいですね、ハマりそうです:tea:

```vue:正しい方法
<template>
  <div class="container">
    <!-- ECS -->
    <h3>ECSの現在</h3><hr>
    <!-- ↓変更箇所 -->
    <textarea v-model="ecs.task" />
    <p>タスクリソース名：{{ecs.taskarn}}</p>
    <p>タスク定義した人：{{ecs.taskupdater}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      ecs: {
        task: "",
        taskarn: "",
        taskupdater: "",
      }
    };
  },
  methods: {
    getECSTask: function() {
      var self = this;
      window.backend.ECS.GetTask().then(result => {
        let td = result.TaskDefinition;
        // JSON.stringifyを使って引数指定
        self.ecs.task = JSON.stringify(td, null, 2);
        self.ecs.taskarn = td.TaskDefinitionArn;

        let brf = td.RegisteredBy;
        if (brf !== null || typeof(brf) !== undefined) {
          self.ecs.taskupdater = brf.replace(/arn:aws:iam::(\d+):user\//, '');
        }
      });
    }
  },
  beforeMount() {
    this.getECSTask();
  }
};
</script>
```

![スクリーンショット 2021-04-22 20.10.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429019/198c7284-75c5-1f2a-475e-b94e9e8f1b41.png)

# 参考
https://gunmagisgeek.com/blog/javascript/3783
https://blog.katsubemakito.net/nodejs/json-pretty
https://eslint.vuejs.org/rules/no-textarea-mustache.html