.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號: N191021201
出刊日期: 2019/10/2
本篇文章延續《使用Vue CLI與Vuex建立應用程式》一文的說明,利用REST API設計留言應用程式的新增、刪除、修改留言功能。
指定遠端資料來源
JSONPlaceholder網站提供偽線上REST API服務,以提供給應用程式開發、測試時使用,您不需要自行建立一個真實的REST API,節省開發的時間。其官網在以下網址:「https://jsonplaceholder.typicode.com/」。後續的留言版範例程式將改成使用以下網址提供的留言資料:
https://jsonplaceholder.typicode.com/comments
由於網站提供的comment測試資料共有500筆,我們可以在網址後方利用查詢字串加上「_limit」,限定只有回傳10筆資料供測試使用:
https://jsonplaceholder.typicode.com/comments?_limit=10
在專案之中,我們需要撰寫veux的Actions來送出AJAX請求,從遠端JSONPlaceholder REST API服務取得comment資料。先修改專案中的「state.js」檔案,移除掉靜態資料,讓「comments」屬性的值是一個空的陣列:
src\store\state.js
export default {
comments: []
}
Actions可以以同步或非同步的方式來執行,因為Actions可能需要花費較冗長的時間才能完成,所以不要直接透過vuex中的Actions程式碼來修改狀態,要異動狀態應該要透過Mutations。
修改「actions.js」檔案,定義一個「getCommentsAction」函式,利用「axios」插件來送出AJAX請求,因此在檔案中第一行程式先利用「import」關鍵字匯入「axios」插件,在「getCommentsAction」函式之中,叫用「axios.get」函式,從JSONPlaceholder REST API下載10筆資料。接著叫用「commit」函式,它將會叫用「mutations.js」中的「getComments」函式來更新狀態(state):
src\store\actions.js
修改「mutations.js」檔案,加入「getComments」函式,此函式接收兩個參數,第一個參數代表state;第二個參數則是「axios」取回的comments資料,我們在「getComments」函式中,透過Mutations來更新狀態:
src\store\mutations.js
export default {
getComments: (state, comments) => (state.comments = comments)
}
修改「Comments.vue」檔案,我們註冊組件的「created」事件,在組件建立時,叫用「getCommentsAction」函式以透過AJAX來取得遠端來源來源 資料:
Comments.vue
<template>
<div>
<h3>Comments</h3>
<b-list-group>
<b-list-group-item v-for="comment in getAllComments" v-bind:key="comment.id">{{comment.email}}</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
name: "Comments",
methods: {
...mapActions(["getCommentsAction"])
},
computed: {
...mapGetters(["getAllComments"])
},
created() {
this.getCommentsAction();
}
};
</script>
<style scoped>
.list-group-item {
color: blueviolet;
}
</style>
目前應用程式首頁的執行結果參考如下,你可以看到從JSONPlaceholder下載的10筆Comment資料中的電子郵件資訊:

圖 1:取得遠端資料來源資料。
由於在組件之中可能需要叫用多個Action,也可能有多個計算屬性要做對應,我們可以利用spread(...)運算子,改寫「Comments.vue」程式如下:
Comments.vue
<template>
<div>
<h3>Comments</h3>
<b-list-group>
<b-list-group-item v-for="comment in getAllComments" v-bind:key="comment.id">{{comment.email}}</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
name: "Comments",
methods: {
...mapActions(["getCommentsAction"])
},
computed: {
...mapGetters(["getAllComments"])
},
created() {
this.getCommentsAction();
}
};
</script>
<style scoped>
.list-group-item {
color: blueviolet;
}
</style>
新增Comment資料
接下來我們要來設計新增留言的功能。在「components」資料夾加入「AddComment.vue」檔案,然後加入以下程式碼,先為組件加入一個<h3>標題:
AddComment.vue
<template>
<h3> Add Comment </h3>
</template>
<script>
export default {
}
</script>
<style>
</style>
修改「App.vue」檔案,利用「import」關鍵字匯入並註冊「AddComment.vue」組件,然後在<template>樣版中,<h4>標題下方使用「<AddComment/>」標籤插入「AddComment.vue」組件:
App.vue
<template>
<div class="container" id="app">
<div class="heading">
<h1>Comments App</h1>
<h4>Let me hear your voices.</h4>
<AddComment/>
<Comments/>
</div>
</div>
</template>
<script>
import Comments from "./components/Comments.vue";
import AddComment from "./components/AddComment.vue";
export default {
name: "app",
components: {
Comments,
AddComment
}
};
</script>
<style>
#app {
background-color: rgb(92, 64, 132);
padding: 50px;
color: rgb(255, 255, 255);
}
</style>
目前應用程式首頁的執行結果參考如下:

圖 2:加入「AddComment」功能。
修改「actions.js」檔案,設計一個「addCommentAction」函式來新增留言資料,函式中利用「axios」插件的「post」函式送出一個AJAX請求到REST API,並將要新增的留言包裝成「comment」物件傳入「post」函式的第二個參數,完成後再透過「commit」函式以叫用「mutations.js」中的「insertComment」函式來更新狀態:
src\store\actions.js
修改「mutations.js」檔案,加入「insertComment」函式程式碼,將新增的留言加入「state.comments」之中:
src\store\mutations.js
export default {
getComments: (state, comments) => (state.comments = comments),
insertComment: (state, comment) => state.comments.unshift(comment)
}
留言所需的表單畫面,可以參考「https://bootstrap-vue.js.org/docs/components/form」文件中的標籤,修改「AddComment.vue」檔案,加入<b-form>表單來收集使用者輸入的留言資訊。範例中利用「@submit.prevent="onSubmit"」註冊表單的「submit」事件,在表單提交後,執行「onSubmit」函式,而函式中則叫用「addCommentAction」函式,將表單資料送到REST API做新增的處理:
AddComment.vue
<template>
<div>
<h3>Add Comment</h3>
<b-form @submit.prevent="onSubmit">
<b-form-group
id="input-group-1"
label="Email address:"
label-for="input-1"
description="We'll never share your email with anyone else."
>
<b-form-input
id="input-1"
v-model="form.email"
type="email"
required
placeholder="Enter email"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-2" label="Your Name:" label-for="input-2">
<b-form-input id="input-2" v-model="form.name" required placeholder="Enter name"></b-form-input>
</b-form-group>
<b-form-group id="input-group-3" label="Body" label-for="input-2">
<b-form-input id="input-2" v-model="form.body" required placeholder="Enter body"></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
</b-form>
</div>
</template>
<script>
import { mapActions } from "vuex"
export default {
name: "AddComment",
methods: {
...mapActions(["addCommentAction"]),
onSubmit () {
this.addCommentAction(this.form)
this.form = {
email: '',
name: '',
body: ''
}
}
},
data() {
return {
form: {
email: "",
name: "",
body: ""
}
}
}
}
</script>
<style>
</style>
下一個步驟則是修改「Comments.vue」檔案,利用<b-list-group>與<b-list-group-item>標籤來顯示詳細的留言者之「email」、「name」與「body」資訊:
Comments.vue
<template>
<div>
<h3>Comments</h3>
<b-list-group>
<b-list-group-item v-for="comment in getAllComments" v-bind:key="comment.id">
<strong> Email : </strong> {{comment.email}} <br/>
<strong> Name : </strong> {{comment.name}} <br/>
<strong> Body : </strong> {{comment.body}} <br/>
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex"
export default {
name: "Comments",
methods: {
...mapActions(["getCommentsAction"])
},
computed: {
...mapGetters(["getAllComments"])
},
created() {
this.getCommentsAction();
}
};
</script>
<style scoped>
.list-group-item {
color: blueviolet;
}
</style>
目前應用程式首頁的執行結果參考如下:

圖 3:新增留言畫面。
在網頁中「Add Comment」區段輸入留言資料,按下Submit後,新增的留言將會出現在下方清單,表單上文字方塊的內容將會被清空回到預設狀態:

圖 4:顯示新增的留言資訊。
若從瀏覽器除錯視窗檢視REST API的回應,你可以看到取得的伺服端回傳之最新新增的Comment資料,以及id編號,請參考下圖所示:

圖 5:檢視REST API的回應。
因為JSONPlaceholder 是一個用於測試的REST API服務,因此當你再度提交資料到JSONPlaceholder API,從瀏覽器的主控台(Console)會看到以下錯誤訊息:

圖 6:僞REST API服務回應。
新增資料永遠都會得到最新Comment id編號為「501」,而理論上id是不可以重複的,未來連接到真實的REST API服務就不會有這個問題,目前可以將這個錯誤忽略掉。未來應用程式之中若有這個問題的話,應該是REST API的設計有問題。
設計刪除功能
下一個步驟我們要為應用程式加入留言刪除的功能。修改「Comments.vue」檔案,使用「<div class="del"></div>」標籤加上刪除圖示,然後在<style>區段定義刪除圖示所需的CSS樣式:
Comments.vue
<template>
<div>
<h3>Comments</h3>
<b-list-group>
<b-list-group-item v-for="comment in getAllComments" v-bind:key="comment.id">
<div class="del"></div>
<strong> Email : </strong> {{comment.email}} <br/>
<strong> Name : </strong> {{comment.name}} <br/>
<strong> Body : </strong> {{comment.body}} <br/>
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex"
export default {
name: "Comments",
methods: {
...mapActions(["getCommentsAction"])
},
computed: {
...mapGetters(["getAllComments"])
},
created() {
this.getCommentsAction();
}
};
</script>
<style scoped>
.list-group-item {
color: blueviolet;
}
.del {
height: 50px;
width: 50px;
right : 30px;
background-color: #FA6900;
border-radius: 5px;
position: absolute;
}
.del:after {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
content: "\d7";
font-size: 50px;
color: #FFF;
line-height: 40px;
text-align: center;
}
</style>
目前應用程式首頁的執行結果參考如下,每一筆Comment資料後方,都會加上一個「X」圖示:

圖 7:加上刪除圖示。
叫用REST API刪除資料
修改「actions.js」檔案,加入「removeCommentAction」函式,叫用「axios.delete」函式送出刪除資料的AJAX請求,並傳送「id」參數指明要刪除的Comment留言編號,完成後透過「commit」函式來叫用Mutations的「deleteComment」函式以更新狀態:
src\store\actions.js
修改「mutations.js」檔案,加入「deleteComment」函式,從「state.comments」之中移除id相符的comment留言資料:
src\store\mutations.js
export default {
getComments: (state, comments) => (state.comments = comments),
insertComment: (state, comment) => state.comments.unshift(comment),
deleteComment: (state, id) => state.comments = state.comments.filter(c => c.id !== id)
}
修改「Comments.vue」檔案,註冊刪除按鈕的「click」事件,在事件觸發時,叫用「removeCommentAction」函式,傳入要刪除的「comment.id」當參數,以送出刪除的請求到REST API:
Comments.vue
<template>
<div>
<h3>Comments</h3>
<b-list-group>
<b-list-group-item v-for="comment in getAllComments" v-bind:key="comment.id">
<div class="del" @click="removeCommentAction(comment.id)"></div>
<strong> Email : </strong> {{comment.email}} <br/>
<strong> Name : </strong> {{comment.name}} <br/>
<strong> Body : </strong> {{comment.body}} <br/>
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex"
export default {
name: "Comments",
methods: {
...mapActions(["getCommentsAction" ,"removeCommentAction"])
},
computed: {
...mapGetters(["getAllComments"])
},
created() {
this.getCommentsAction();
}
};
</script>
<style scoped>
.list-group-item {
color: blueviolet;
}
.del {
height: 50px;
width: 50px;
right : 30px;
background-color: #FA6900;
border-radius: 5px;
position: absolute;
}
.del:after {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
content: "\d7";
font-size: 50px;
color: #FFF;
line-height: 40px;
text-align: center;
}
</style>
目前應用程式首頁的執行結果參考如下,只要點選刪除小圖示,就會將此筆資料刪除:

圖 8:資料刪除。
使用「vue-router」插件啟用路由
在留言應用程式中,需要有一個「About」頁面,顯示應用程式資訊,而且還需要有一個編輯留言的頁面,讓我們修改原有留言的內容。我們需要路由系統來協助切換到不同的頁面。「vue-router」插件可以幫助我們完成路由的處理。我們需要先在專案之中安裝「vue-router」插件(plugin),以啟用路由功能,先切換到命令提示字元,在專案根目錄,輸入以下指令:
npm install vue-router
接著修改「main.js」檔案,使用「import」關鍵字匯入「vue-router」,並在使用「new」關鍵字建立Vue實例時,直接注入「vue-router」:
main.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
import App from './App.vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import router from './router'
import store from './store'
Vue.config.productionTip = false
Vue.use(BootstrapVue)
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
接著我們要將原來在「App.vue」要顯示的內容搬到「Home.vue」組件中,然後修改「App.vue」檔案利用<router-link>定義「Home」與「About」兩個連結,<router-link>實際上是一個組件(Component)。修改「App.vue」檔案程式碼如下:
App.vue
<template>
<div class="container" id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<b-container>
<router-view/>
</b-container>
</div>
</template>
<script>
export default {
name: "app",
components: {
}
}
</script>
<style>
#app {
background-color: rgb(92, 64, 132);
padding: 50px;
color: rgb(255, 255, 255);
}
</style>
<router-view/> 標籤所在的位置是一個定位點,代表未來透過路由執行的「Home.vue」、「About.vue」組件標籤所要插入的位置。
接著在「components」資料夾中加入「About.vue」檔案, 並在檔案中加入以下內容,隨意在標題下方加入一些亂數假文:
components\About.vue
<template>
<div>
<h1> About</h1>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores consectetur quo consequuntur beatae sapiente illum atque quia aut nulla explicabo.
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
在「components」資料夾中加入「Home.vue」檔案,將先前在「App.vue」檔案中的內容加入,注意,我們修改了「import」那行程式碼,程式之中使用到了「@」符號,它對應到「src」資料夾:
components\Home.vue
<template>
<div class="heading">
<h1>Comments App</h1>
<h4>Let me hear your voices.</h4>
<AddComment/>
<Comments/>
</div>
</template>
<script>
import Comments from "@/components/Comments.vue"
import AddComment from "@/components/AddComment.vue"
export default {
name: "home",
components: {
Comments,
AddComment
}
};
</script>
<style>
</style>
在「src」資料夾之中加入「router.js」檔案,建立並匯出「Router」物件,在「routes」屬性使用陣列來定義兩個路由,「/」路徑會顯示「Home.vue」頁面;「/About」路徑將顯示「About.vue」頁面,而「name」是選擇性的:
src\router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/About',
name: 'about',
component: About
}
]
})
目前應用程式首頁的執行結果參考如下,網頁上方顯示「Home」、「About」兩個連結:

圖 9:使用路由系統切換到首頁、關於畫面。
點選「About」連結將切換到「About(關於)」頁面,請參考下圖所示:

圖 10:使用路由系統切換到「About(關於)」頁面。
設計選單樣式
預設選單的樣式較為單調,搭配Bootstrap Vue可以美化其外觀,參考官網文件的說明:「https://bootstrap-vue.js.org/docs/components/nav/#navs」,我們改用<b-nav>與<b-nav-item>標籤來顯示選單,並利用「isActive」變數來判斷哪一個選項要套用「active」attribute:
App.vue
<template>
<div class="container" id="app">
<b-nav tabs fill id="nav">
<b-nav-item id="navhome" @click="isActive=true" to="/" :active="isActive">Home</b-nav-item>
<b-nav-item id="navabout" @click="isActive=false" to="/About" :active="!isActive">About</b-nav-item>
</b-nav>
<b-container>
<router-view />
</b-container>
</div>
</template>
<script>
export default {
name: "app",
components: {},
data() {
return {
isActive: true
}
}
}
</script>
<style>
#app {
background-color: rgb(92, 64, 132);
padding: 50px;
color: rgb(255, 255, 255);
}
</style>
目前應用程式首頁的執行結果參考如下,預設「Home」的狀態是選取的(Active),因此背景顏色套用白色:

圖 11:套用Bootstrap Vue選單樣式。
若選取「About」連結,則「About」選項的背景顏色就會套用白色,請參考下圖所示:

圖 12::套用Bootstrap Vue選單樣式。
設計資料修改功能
最後我們要完成留言資料修改功能,使用者可以在首頁選取其中一筆留言資料,並利用路由切換到編輯畫面(EditComment.vue檔案),例如,若要修改「id」為「1」的資料,我們希望路由看起來為:
http://localhost:8080/edit/1
若要修改「id」為「2」的資料,我們希望路由看起來為:
http://localhost:8080/edit/2
我們需要動態路由來設定「id」。此外編輯畫面(EditComment.vue)要帶出目前資料的明細,以讓使用者修改資料,完成後將異動後的資料送到REST API,以更新後端資料。
修改「router.js」檔案,註冊動態路由,在「path」區塊中,我們使用到「:id」參數:
router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'
import EditComment from './components/EditComment.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/edit/:id',
name: 'editComment',
component: EditComment
}
]
})
在「components」資料夾中加入「EditComment.vue」檔案,然後加入以下程式碼,利用「this.$route.params.id」從路由資料中,取出「id」參數的值:
components\EditComment.vue
<template>
<div>
<h3>Edit Comment</h3>
{{this.$route.params.id}}
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
目前應用程式的首頁執行結果參考如下,在瀏覽器輸入以下URL:
http://localhost:8080/edit/1
將顯示「EditComment.vue」頁面,以及路由「id」參數資料,請參考下圖所示:
圖 13:存取路由參數。
修改「EditComment.vue」檔案,加入<b-form>標籤,由於資料修改通常不允許修改識別資料的「id」值,因此在範例中顯示「id」的文字方塊上,套用「disabled」Attribute。當表單提交之後,會叫用「editCommentAction」函式,送出AJAX請求到REST API,然後利用「this.$router.push("/")」,回到首頁:
components\EditComment.vue
<template>
<div>
<h3>Edit Comment</h3>
<!-- {{this.$route.params.id}} -->
<b-form @submit.prevent="onSubmit">
<b-form-group id="input-group-1" label="id :" label-for="input-1">
<b-form-input id="input-1" v-model="form.id" type="text" disabled></b-form-input>
</b-form-group>
<b-form-group
id="input-group-1"
label="Email address:"
label-for="input-1"
description="We'll never share your email with anyone else."
>
<b-form-input
id="input-1"
v-model="form.email"
type="email"
required
placeholder="Enter email"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-2" label="Your Name:" label-for="input-2">
<b-form-input id="input-2" v-model="form.name" required placeholder="Enter name"></b-form-input>
</b-form-group>
<b-form-group id="input-group-3" label="Body" label-for="input-2">
<b-form-input id="input-2" v-model="form.body" required placeholder="Enter body"></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
</b-form>
</div>
</template>
<script>
import { mapActions, mapState } from "vuex"
export default {
name: "EditComment",
methods: {
...mapActions(["editCommentAction"]),
onSubmit() {
this.editCommentAction(this.form)
this.$router.push("/")
}
},
data() {
return {
form: {}
};
},
computed: {
...mapState(["comments"])
},
mounted() {
const rid = Number.parseInt(this.$route.params.id),
ar = this.comments,
comment = ar.find(c => c.id == rid)
this.form = comment
}
}
</script>
<style>
</style>
修改「Comments.vue」檔案,加入<router-link>標籤,並根據comment的「id」值來組出「to」屬性的路徑。此外我們修改了「created」函式,不要每一次執行首頁時,都從REST API下載最新資料,如此異動資料時將會送兩個請求到REST API),一個put請求修改資料;一個get請求取回最新資料。這種作法較無效率,因此我們修改「created」函式程式碼,判斷「this.getAllComments.length」的值是否為0,若不為0則表示用戶端已有資料,所以只需送出一個「put」請求變更資料,然後手動更新用戶端的資料,不需要再重REST API取回資料:
Comments.vue
<template>
<div>
<h3>Comments</h3>
<b-list-group>
<b-list-group-item v-for="comment in getAllComments" v-bind:key="comment.id">
<div class="del" @click="removeCommentAction(comment.id)"></div>
<router-link class="edit" :to="`/edit/${comment.id}`"></router-link>
<strong>Email :</strong>
{{comment.email}}
<br />
<strong>Name :</strong>
{{comment.name}}
<br />
<strong>Body :</strong>
{{comment.body}}
<br />
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex"
export default {
name: "Comments",
methods: {
...mapActions(["getCommentsAction", "removeCommentAction"])
},
computed: {
...mapGetters(["getAllComments"])
},
created() {
if(this.getAllComments.length <= 0)
{
this.getCommentsAction()
}
}
}
</script>
<style scoped>
.list-group-item {
color: blueviolet;
}
.edit {
height: 50px;
width: 50px;
right: 90px;
background-color: #fa6900;
border-radius: 5px;
position: absolute;
}
.edit:after {
position: absolute;
top: 10px;
bottom: 0;
left: 0;
right: 0;
content: "\0395";
font-size: 30px;
color: #fff;
line-height: 30px;
text-align: center;
}
.del {
height: 50px;
width: 50px;
right: 30px;
background-color: #fa6900;
border-radius: 5px;
position: absolute;
}
.del:after {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
content: "\d7";
font-size: 50px;
color: #fff;
line-height: 40px;
text-align: center;
}
</style>
修改「actions.js」檔案,加入「editCommentAction」函式,利用「axios」插件送出「put」請求到REST API進行資料修改作業:
src\store\actions.js
import axios from 'axios'
export default {
async getCommentsAction({ commit }) {
const response = await axios.get(
'https://jsonplaceholder.typicode.com/comments?_limit=10'
)
commit('getComments', response.data)
},
async addCommentAction({ commit }, comment) {
const response = await axios.post(
'https://jsonplaceholder.typicode.com/comments', comment
)
commit('insertComment', response.data)
},
async removeCommentAction({ commit }, id) {
await axios.delete(`https://jsonplaceholder.typicode.com/comments/${id}`);
commit('deleteComment', id);
},
async editCommentAction({ commit }, comment) {
const response = await axios.put(
`https://jsonplaceholder.typicode.com/comments/${comment.id}`,
comment
);
commit('updateComment', response.data)
}
}
修改「mutations.js」檔案,更新狀態內容,將store中「id」相符的comment物件代換掉:
src\store\mutations.js
export default {
getComments: (state, comments) => (state.comments = comments),
insertComment: (state, comment) => state.comments.unshift(comment),
deleteComment: (state, id) => state.comments = state.comments.filter(c => c.id !== id),
updateComment: (state, comment) => {
const index = state.comments.findIndex(c => c.id === comment.id)
if (index !== -1) {
state.comments.splice(index, 1, comment)
}
}
}
目前應用程式的執行結果參考如下,每一筆留言資料右方有一個「E」按鈕:

圖 14:編輯資料。
點選「E」按鈕便將這筆資料帶入編輯畫面,請參考下圖所示:

圖 15:編輯選取資料。
修改完資料,按下「submit」按鈕,便會更新後端資料,然後回到首頁,請參考下圖所示:

圖 16:完成更新。