前言:
本篇是紀錄Vue RESTful API的簡單學習筆記 學習的內容來自 Alex大大的 Vue 全家桶與 RESTful API 串接入門介紹
這個VUE’s RESTful API系列的影片有兩部,長達七個小時,當初在YouTube上發現,Alex大大解說的方式,我可以聽得懂,就順勢入坑。
當初第一次看的時候,也是花了好幾天才把影片的範例給做完 但由於本身並不是寫前端的,只是偶爾寫一下python 所以學過的東西沒在用,很容易忘記…記得第一次看的時候是過年前 三月再回頭看,發現已經忘記…再看一次… 四月底再回頭看…發現又忘記…且之前寫的檔案也不知丟哪了… 才想到寫blog來記錄學習過程的重要…我也好久沒更新blog…
在開始貼程式碼前,總結一下這次每看必忘的學習過程… 最大的原因大概就是,我是直接學VUE,看這系列影片之前 有看過前端的教學影片, AMOS大大的 : 金魚都能懂的網頁設計入門 – 金魚都能懂了你還怕學不會嗎
But… 對JavaScript的了解,只停留在變數、迴圈、判斷式 很多東西如 dispatch、axios、promise、then、箭頭函式…等 都是在VUE的教學影片中看到…還以為這些都是VUE的特有功能… 再加上看完影片後,當下覺得可以理解影片的內容 但從沒自己找個side project練練手…加上金魚的記憶能力… XDD anyway 要學VUE…還是得先從JavaScript開始。
複製貼上程式碼之前 1.用NPM 安裝 json-server
npm i -g json-server
2.啟動 json-server (終端機下)
json-server 你的json檔案.json
3.注意事項: VS Code 套件 live server 的 auto-reload 會產生的坑 解決方式:請看VCR…
以下就開始複製貼上程式碼… 只有新增跟刪除資料的功能,沒有使用VUE Router跟VUEX
網頁畫面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue RESTful API</title>
</head>
<body>
<div id="app">
<p>
<!-- trim 去頭尾空白 -->
<input type="text" v-model.trim="input" /><a
href="javascript:;"
v-on:click="cerateHandler"
>Create</a
>
</p>
<ol>
<li v-for="(content,index) in contents">
{{content.content}} <a href="javascripts:;">Update</a>
<a href="javascript:;" v-on:click="deleteHandler(index)">Delete</a>
</li>
</ol>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
</body>
</html>
<script>
new Vue({
el: "#app",
// ES6寫法
data: {
input: "",
contents: [],
},
methods: {
cerateHandler() {
if (!this.input) {
return false;
}
// console.log("cerateHandler on clicked", this.input);
// axios.post 塞資料到api
axios
.post("http://localhost:3000/contents", {
content: this.input,
})
.then((res) => {
// 清空輸入欄位 , 資料輸出到網頁上
// push 是陣列 新增資料的用法 (contents是陣列)
(this.input = ""), this.contents.push(res.data);
});
},
// axios 刪除功能
deleteHandler(index) {
let target = this.contents[index];
// console.log("target= ", target);
axios
.delete(<code>http://localhost:3000/contents/${target.id}
)
.then((res) => {
this.contents.splice(index, 1);
});
},
},
mounted() {
axios.get("http://localhost:3000/contents").then((res) => {
// console.log(res.data);
this.contents = res.data;
});
},
});
接下來是完整的程式,有使用到VUE Router跟VUEX
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vue RESTful API</title> </head> <body> <div id="app"> <router-view></router-view> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script> </body> </html> <script> let List = { template: `<div> <p> <input type="text" v-model.trim="input" /><a href="javascript:;" v-on:click="cerateHandler"> Create </a> </p> <ol> <li v-for="(item,index) in contents" :key="item.id"> {{item.content}} <a href="javascripts:;" v-on:click="updateHandler(index)"> Update </a> <a href="javascript:;" v-on:click="deleteHandler(index)"> Delete </a> </li> </ol> </div>`, // ES6寫法 data: function () { return { input: "", // contents: [], }; }, computed: { contents() { return this.$store.state.contents; }, }, methods: { cerateHandler() { if (!this.input) { return false; } // console.log("cerateHandler on clicked", this.input); // axios.post 塞資料到api axios .post("http://localhost:3000/contents", { content: this.input, }) .then((res) => { // 清空輸入欄位 , 資料輸出到網頁上 // push 是陣列 新增資料的用法 (contents是陣列) this.input = ""; // this.contents.push(res.data); //上面不能push資料到data 開嚴格模式會報錯 ,沒開會讓你刪沒報錯 但是不合法 要走mutation 如下 this.$store.commit("addContent", res.data); }); }, // axios 刪除功能 deleteHandler(index) { let target = this.contents[index]; // console.log("target= ", target); //改成 action => mutation // axios // .delete(<code>http://localhost:3000/contents/${target.id}
) // .then((res) => { // this.contents.splice(index, 1); // }); // 先進 action 再進 mutation //CONTENT_DELETE 就是給action用的 this.$store.dispatch("CONTENT_DELETE", { target }); }, // axios 更新功能 updateHandler(index) { // console.log(this); let target = this.contents[index]; // this.$router.push({ path:/update/${target.id}
}); // id不是亂取的 是設定 router 時 設定的 path: "/update/:id" <=這個id //用name params寫法 this.$router.push({ name: "update", params: { id: target.id } }); // 寫法2 // this.$router.push({path:'/update/'+target.id}) }, }, mounted() { // axios.get("http://localhost:3000/contents").then((res) => { // // console.log(res.data); // this.contents = res.data; // }); }, }; let Edit = { template:<div><p><input type="text" v-model.trim="input" /><a href="javascripts:;" v-on:click="updateHandler">Update</a></p></div>
, data() { return { input: "", }; }, computed: { content() { return this.$store.state.contents.find((item) => { return item.id == this.$route.params.id; }); }, }, methods: { updateHandler() { this.$store .dispatch("CONTENT_UPDATE", { id: this.content.id, input: this.input, }) .then(() => { this.$router.push({ path: "/" }); }); }, }, mounted() { if (!this.content) return this.$router.replace({ path: "/" }); this.input = this.content.content; }, }; let store = new Vuex.Store({ strict: true, state: { contents: [], }, mutations: { SET_CONTENTS(state, data) { state.contents = data; }, addContent(state, data) { state.contents.push(data); }, deleteContent(state, data) { state.contents.splice(data, 1); }, updateContent(state, { item, input }) { item.content = input; }, }, actions: { CONTENTS_READ: (context) => { // console.log("context= ", context); // 讀資料 要return return axios.get("http://localhost:3000/contents").then((res) => { context.commit("SET_CONTENTS", res.data); }); }, CONTENT_DELETE: (context, { target }) => { let index = context.state.contents.indexOf(target); if (index == -1) return false; return axios .delete("http://localhost:3000/contents/" + target.id) .then((res) => { context.commit("deleteContent", index); }); }, CONTENT_UPDATE: (context, { id, input }) => { console.log("UPDATE"); let item = context.state.contents.find((item) => { return item.id == id; }); if (!item) return false; return axios .patch("http://localhost:3000/contents/" + item.id, { content: input, }) .then((res) => { context.commit("updateContent", { item, input }); }); }, }, }); // 設定 vue router let router = new VueRouter({ //由上往下走~有順序之分 routes: [ { path: "/", name: "list", component: List, }, { path: "/update/:id", name: "update", component: Edit, }, { path: "*", redirect: "/", }, ], }); new Vue({ el: "#app", // 掛載router ES6 router, store, mounted() { // this.$store.dispatch("CONTENTS_READ"); this.$store.dispatch("CONTENTS_READ"); }, });
以上就是,這兩部影片的內容…做完這個範例,不能說就可以完全了解VUE的運作,只能有一個初步的認識…離可以自行做一個side project還有一段路要走…
Reference:
- Alex 宅幹嘛 👨💻 Vue 全家桶與 RESTful API 串接入門介紹 part1
- Alex 宅幹嘛 👨💻 Vue 全家桶與 RESTful API 串接入門介紹 part2