---
title: 'VueJS 2.0 教學筆記: RESTFUL API 操作實作'
disqus: hackmd
---
VueJS 2.0 教學筆記: RESTFUL API 操作實作
===
綱要
[TOC]
完整範例
---
[前往Github](https://github.com/fortes1219/vue_2020/blob/day_3/src/components/ApiTemp.vue)
![](https://i.imgur.com/Y0LDEAR.png)
建立template
===
使用的style皆為之前Sass/Scss課程所整理過的現成資源
不知道在哪的可以直接來這裡挖:
https://github.com/fortes1219/sass_0208/tree/0222_homework/src/scss
開始這個範例以前,請先確認你的JSON-server是開啟的狀態。
如果沒啟動,就另開個終端機視窗輸入這個指令:
`json-server --watch db.json`
詳細的用法在[第一次上課](https://https://hackmd.io/_FEpivyARdSyUnXlONY-Yw?both#%E4%B8%89%E3%80%81Vue-%E4%BD%BF%E7%94%A8-axios-%E7%9A%84%E5%B0%81%E8%A3%9D%E6%96%B9%E5%BC%8F)時建立環境就有做過了
```htmlmixed=
<template>
<div class="page api_temp">
<div class="row column">
<!-- POST用的表單 -->
<el-form label-width="8rem" data-width="20rem" data-space="space-vertical">
<el-form-item label="ID">
<el-input v-model="postObj.id" type="text" />
<!-- <el-input v-model="postObj.id" type="text" @input="parser($event, postObj)"/> -->
</el-form-item>
<el-form-item label="Name">
<el-input v-model="postObj.name" type="text" />
</el-form-item>
<el-form-item label="Class">
<el-input v-model="postObj.class" type="text" />
</el-form-item>
<el-form-item label="Date">
<el-date-picker
v-model="postObj.date"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="請選擇時間"
/>
</el-form-item>
<div class="row horizontal v_center end">
<el-button @click="packagePostData">Add Data(POST)</el-button>
</div>
</el-form>
<!-- el table 顯示資料內容-->
<el-table :data="tableData" style="width: 100%; overflow: hidden;" height="50vh">
<el-table-column prop="id" label="ID" align="center" width="100" />
<el-table-column prop="name" label="Name" align="center" width="100" />
<el-table-column prop="class" label="Class" />
<el-table-column prop="date" label="Date" />
<el-table-column label="Action" align="center">
<template slot-scope="scope">
<el-button type="danger" @click="delCheck(scope.row.id)">DELETE</el-button>
<el-button type="warning" @click="openEditDialog(scope.row)">EDIT</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
```
```javascript=
<script>
export default {
name: 'apiTemp',
data() {
return {
lang: 'zh_tw',
tableData: [],
postObj: {
id: '',
name: '',
class: '',
date: '',
},
editForm: {},
editDialog: false,
};
},
}
</script>
```
GET
===
GET單純只有取得API回傳的內容,這邊我們用來顯示`el-table`表格的內容
```javascript=
<script>
export default {
name: 'apiTemp',
data() {
return {
//...略
tableData: []
};
},
methods: {
async packageGetData() {
// url 這個變數會依據你實際上拿到的API路徑有所不同
const url = 'http://localhost:3000/tableData?_sort=id';
// 命名一個變數 res 來代表Axios取回的內容
const res = await this.$api.get(url);
// el-table的bind:data,將取回的 API 資料存入 tableData 這個 v-model
this.tableData = [...res];
console.log('res: ', res)
}
},
created() {
// DOM 尚未生成以前就可以先去跟 API 要資料
this.packageGetData()
},
}
</script>
```
![](https://i.imgur.com/aySVG1P.png)
POST
===
POST需要一個表單模組,將參數放入一個Object做綁定後,送到指定的位置來更新資料。
```javascript=
<script>
export default {
name: 'apiTemp',
data() {
return {
//...略
postObj: {
id: '',
name: '',
class: '',
date: '',
},
};
},
methods: {
// async packageGetData() {...},
async packagePostData() {
const source = 'http://localhost:3000/tableData';
// 將 postObj 帶入 Axios 的 request
await this.$api.post(source, this.postObj);
// 要及時更新畫面的話,就必須再打一次GET取回新的資料
await this.packageGetData();
// 檢查看看自己POST出去的資料是否正常
console.log(source.data);
},
},
}
</script>
```
PUT
===
用來編輯內容時使用,與PATCH不同的地方是,**PUT會將整個物件的參數都更新**,PATCH 只更新指定的key。
```htmlmixed=
<el-table-column label="Action" align="center">
<template slot-scope="scope">
<!-- <el-button type="danger" @click="delCheck(scope.row.id)">DELETE</el-button> -->
<!-- 傳入scope.row就是將table中該筆資料一併帶入開啟Dialog組件的事件 -->
<el-button type="warning" @click="openEditDialog(scope.row)">EDIT</el-button>
</template>
</el-table-column>
```
```javascript=
<script>
export default {
name: 'apiTemp',
data() {
return {
//...略
editForm: {},
editDialog: false,
};
},
methods: {
// async packageGetData() {...},
// async packagePostData() {...},
openEditDialog(obj) {
// 開啟Dialog
this.editDialog = true;
// 將click事件帶入的scope.row資料轉為編輯用的v-model
this.editForm = { ...obj };
console.log('edit obj: ', this.editForm);
},
async updateData() {
// 前面開啟Dialog事件已經讓 this.editForm 有對應的資料,這邊定義變數 id 來存取
const id = this.editForm.id;
const source = `http://localhost:3000/tableData/${id}`;
try {
await this.$api.put(source, this.editForm);
// 如果資料無誤,成功送出就顯示elementUI的提示訊息組件
this.$message({
message: '編輯成功',
type: 'success',
});
this.editDialog = false;
console.log(`ID ${id} 編輯成功`);
} catch {
// 反之,回傳一個錯誤訊息
this.$message.error('編輯失敗');
}
// 修改資料後別忘了畫面會需要重新GET新的資料
await this.packageGetData();
},
},
}
</script>
```
DELETE
===
顧名思義,就是刪除的意思,帶入一個ID傳出去就能將該筆資料刪除。
但千萬記得這是不可逆的行為,最好能有一個防止誤觸的措施,比如確認視窗。
```htmlmixed=
<el-table-column label="Action" align="center">
<template slot-scope="scope">
<!-- 傳入scope.row.id一併帶入開啟確認視窗組件的事件 -->
<el-button type="danger" @click="delCheck(scope.row.id)">DELETE</el-button>
<!-- <el-button type="warning" @click="openEditDialog(scope.row)">EDIT</el-button> -->
</template>
</el-table-column>
```
```javascript=
<script>
export default {
name: 'apiTemp',
data() {...},
methods: {
// async packageGetData() {...},
// async packagePostData() {...},
// openEditDialog(obj) {...},
async delCheck(id) {
// 按下刪除Button時顯示確認視窗,此組件沒有html,只需要JS的Code就能呼叫
try {
await this.$confirm(
'將會刪除資料,是否繼續?', '刪除資料', {
confirmButtonText: '確認刪除',
cancelButtonText: '取消',
type: 'warning',
},
);
// 按下確認則呼叫刪除事件
await this.delData(id);
this.$message({
message: '刪除成功',
type: 'success',
});
} catch {
this.$message({
message: '已取消删除',
type: 'info',
});
}
},
async delData(id) {
const source = `http://localhost:3000/tableData/${id}`;
await this.$api.delete(source);
// 刪除後也需要重新更新畫面
await this.packageGetData();
console.log(this.tableData);
},
},
}
</script>
```
本日後記
===
串接API其實就是這麼回事,多著重在與UI之間的溝通和資料處理。
如果想知道真實環境串接API是什麼情形,可以[複習這篇](https://hackmd.io/_FEpivyARdSyUnXlONY-Yw?both#%E7%9C%9F%E5%AF%A6%E5%B0%88%E6%A1%88%E4%B8%8A%E6%8E%A5-API-%E6%98%AF%E4%BB%80%E9%BA%BC%E6%A8%A3%E7%9A%84%E7%8B%80%E6%B3%81%EF%BC%9F)
---
###### tags: `VueJS` `RESTFUL-API`