--- 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`