最後,我們再次回到Employee.vue的區塊,這裡要介紹的是v-model
雙向綁定的功能,參考如下:
<!-- src/views/Employee.vue -->
<template>
<section id="member-settings">
<h1>成員設定</h1>
<!-- 分頁元件 -->
<b-pagination
v-model="currentPage"
:per-page="pageSize"
:total-rows="employeesCount"
class="my-3"
/>
</section>
</template>
// src/views/Employee.vue
import store from "@/store";
import { mapGetters } from "vuex";
import { FETCH_EMPLOYEES, } from "@/store/actions.type";
import { SET_CURRENT_PAGE } from "@/store/mutations.type";
export default {
name: "EmployeePage",
computed: {
...mapGetters("employee", [
"pageSize",
"employeesCount",
]),
// 用 v-model綁定這個computed:讀取/寫入Vuex
currentPage: {
// getters
get() {
return this.$store.state.employee.currentPage;
},
// setters
set(newPage) {
this.$store.commit(`employee/${SET_CURRENT_PAGE}`, newPage);
}
}
},
watch: {
// 任何方式改到currentPage(UI或程式碼)都會跑這裡
currentPage() {
this.refreshList();
}
},
methods: {
refreshList() {
store.dispatch(`employee/${FETCH_EMPLOYEES}`, {
page: this.currentPage,
page_size: this.pageSize
});
},
},
};
有別於一般props屬性,僅於接收到資料後,才自動更新狀態並渲染,v-model
雙向綁定可以做到,隨著網頁使用者操作改變狀態的同時,畫面即隨著狀態的更新而自動渲染。
v-model
雙向綁定,能做到同步更新畫面的原因,在於其除了讀取資料狀態外,尚有同步更新資料狀態的功能,以達成同步畫面渲染的作用。兩種功能分別可運用getter()及setter()完成。
以所提供的程式碼為例,該雙向綁定者為currentPage
,畫面顯示的頁碼,乃直接讀取資料狀態,return this.$store.state.employee.currentPage;
(getter),而當commit更新頁碼狀態時,this.$store.commit(
employee/${SET_CURRENT_PAGE}, newPage);
(setter),就會因頁碼資料狀態更新,而被即時讀取並渲染。
此外,因雙向綁定者僅為currentPage
,該頁碼對應的員工資料,需要再次重新更新員工資料狀態,即向API請求員工資料。因此需搭配watch
,當發現到currentPage
改變時,即再次執行refreshList()
一次,才可以取得更新頁面的員工資料。
最後,其實v-model
可以把它想像成,兩種形式的組合,即:value
用來讀取資料狀態,以及@input
於監聽到輸入事件,即時更新資料狀態,也可做到同步輸入資料即時更新畫面顯示。參考例子如下,同時提示一些版本的語法差異:
<!-- 分頁元件(Vue 2, BootstrapVue) -->
<b-pagination
:value="currentPage"
@input="currentPage = $event"
/>
<!-- 分頁元件(Vue 3, BootstrapVueNext) -->
<b-pagination
:modelValue="currentPage"
@update:modelValue="currentPage = $event"
/>
<!-- 輸入元件 -->
<input
:value="msg"
@input="msg = $event.target.value"
/>
至此,再次應更可體認Vue所提供簡潔的v-model
雙向綁定語法,讓程式撰寫者可以很簡便地達到同步即時畫面更新的功能。