Go + Echo + Vue.js SPAへの第一歩

# Golang + Echo + Vue.js でSPA
 * 作ります。本当に導入の導入部分だけ実装します。
 * [cotch-io/go-echo-vue-single-page-app](https://github.com/scotch-io/go-echo-vue-single-page-app) このリポジトリをみて参考にしたのですが、ajaxに推奨されていない`vue-resourceを使用している + バージョンが古い` ので、
 フォークして`axiosを使用するように書き換え + めちゃくちゃ簡素化` したものを解説します。
 * めんどくさいのでDBはつなぎません。バックエンドとフロントエンドのつなぎ込みだけです
 * フォークしたリポジトリに修正分をコミットして、それをベースに解説していきます。
 * リポジトリ -> https://github.com/ShingoYadomoto/go-echo-vue-single-page-app

## 簡素化
**コミットはこれ↓**
https://github.com/ShingoYadomoto/go-echo-vue-single-page-app/commit/efed92735ffeeccdab93667247a7e1e0b8f7cb2b
☆以下解説です☆

### main
```go
func main() {

	e := echo.New()

	e.File("/", "public/index.html")
	e.GET("/tasks", handlers.GetTasks)

	e.Start(":8080")
}
```
そのまんまですが、
`http://localhost:8080/` にアクセスすると`public/index.html`を返し、
`http://localhost:8080/tasks` にアクセスすると、`handlers.GetTasks()`を叩くWebサーバーを起動

### model
```go
// Task is a struct containing Task data
type Task struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

// TaskCollection is collection of Tasks
type TaskCollection struct {
	Tasks []Task `json:"items"`
}

// GetTasks
func GetTasks() (tc TaskCollection) {
	tc = TaskCollection{
		[]Task{
			{1, "洗濯"},
			{2, "掃除"},
		},
	}

	return
}
```
`Task`, `TaskCollection`の定義、
`GetTasks()`は、適当な値が入ってる`TaskCollection`を返す

### handler
```go
// GetTasks endpoint
func GetTasks(c echo.Context) error {
	return c.JSON(http.StatusOK, models.GetTasks())
}
```
単純です。上の`models.GetTasks()`を叩いて、`models.TaskCollection`をjson形式でレスポンスとして返します。

### index.html
```vue
<html>
    <head>
        <!-- Vue.js -->
        <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.24/vue.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.7.0/vue-resource.min.js"></script>
    </head>
    <body>
        <div>
            <h1>Hello Vue.js</h1>
            <button v-on:click="showTask">タスクを表示する。</button>
            <ul>
                <li v-for="task in tasks">
                    {{ task.name }}
                </li>
            </ul>
        </div>
        <script>
            new Vue({
                el: 'body',

                data: {
                    tasks: [],
                },

                methods: {
                  showTask: function() {
                      // Use the vue-resource $http client to fetch data from the /tasks route
                      this.$http.get('/tasks').then(function(response) {
                          this.tasks = response.data.items ? response.data.items : []
                      })
                  },
                }
            })
        </script>
    </body>
</html>

```
`go run todo.go` をターミナルで叩いて、ブラウザで`http://localhost:8080`にアクセスすると


<img width="328" alt="スクリーンショット 2018-08-25 2.50.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/231923/3c43c352-83ef-adb9-6f24-b1f22cb12a12.png">

こんな感じになると思います。
そして、`タスクを表示する。`を押すと、

<img width="245" alt="スクリーンショット 2018-08-25 2.53.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/231923/f28f4b49-ab83-e423-1dae-8293118f1557.png">

こうなるはず。これだけでなんちゃってSPAです。

以下はリファクタに近いですが念のため

## Vue.jsのバージョンを新しく(2.5.13) + ajaxにaxiosを使用
**コミットはこれ↓**
https://github.com/ShingoYadomoto/go-echo-vue-single-page-app/commit/515215733df732422e3d7ab724a421e23954bbdb
☆以下解説です☆

### 読み込みscriptタグの変更
```html
- <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.24/vue.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.7.0/vue-resource.min.js"></script>

+ <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script> 
+ <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
```

vueのバージョンあげました。バージョンの数字を変えただけでなくcdnのドメインも変わってるか新しくなっているみたいです。
`vue-resourece` -> `axios` に変更しました。 `vue-resource` は、使用できないわけではないらしいですが、本家推奨ではなくなったらしいので変えておきましょう。

### elementの変更
```vue
- el: 'body',

+ el: '#top',
```
これはシンプルにbodyタグ(確かhtmlタグも)にはelementとしてマウントできなくなったみたいです(warningかも)
あやふやですいません、、 すぐ試せると思うので、ご自身で試してみてください。

### メソッドの変更
```js
-  this.$http.get('/tasks').then(function(response) {
-      this.tasks = response.data.items ? response.data.items : []                       
-  })

+  axios.get('/tasks').then(res => {
+      this.tasks = res.data.items || [];
+  }).catch(function (error) {
+      console.log(error);
+  });
```
`vue-resourece` -> `axios` の変更に伴う修正です。
書き換えた後は例外処理も含めているので、それがなければ実際はほぼ同じようなもんですね。

## 以上です
こんな簡単にSPAの仕組みを作れるなんて！
SPAとかむずそうって人はこの記事くらいなら動かせると思うので、きっかけとして利用して下さい！
ありがとうございました。