目前的進度在做記帳程式「支出紀錄」的增刪改查,原本以為這樣簡單的 CRUD 應該是一塊小蛋糕,卻在要將「新增」與「編輯」的 form dialog 抽成共用模組時遇到資料流的問題。
將整個記帳紀錄的操作畫個簡圖如上,這裡的目的是要將「新增」、「編輯」都能使用 BillingDialog
這個共用模組。
明明直覺是一個可以輕鬆解決的問題,但卻卡了一陣子,於是今天決定冷靜地整理關於共用對話框資料傳遞的流程。
其實這種共用對話框的作法有好幾種寫法,以下分別列出幾種我想到的方法。
一種是考慮到未來全站都會有使用 dialog 的需求,所以利用 Vue 中的 動態模組(Dynamic Components) 寫法,並搭配 Vuex 的 store 存放這個 dialog 的相關資料:要顯示的模組、資料、callback function。
如此一來未來全站有任何一個地方要打開一個 dialog,只要撰寫一個特定樣貌的 dialog 並註冊在這個動態模組中,就能直接利用 store 的 action 與 state 來操作打開與關閉對話框,雖然要做比較多工,但算是比較一勞永逸的方法。
這個解法比較直覺,以這邊的例子而言,就是直接將 BillingDialog
抽成「新增」與「編輯」的共用模組就好,也就是只要把原本搞不定的資料流,在父層的 Billing
搞定就好。
最後也是直接選擇這個做法。
原本想說都弄不出來的話,不如就不另外抽成模組了,「新增」用一個、「編輯」自己用一個,不過這樣比較像是在逃避問題,但不失為一個好的解法,畢竟能趕上十二點發文比較重要。
在父層 Billing
的寫法如下:
<el-button
class="pg-billing__btn-add"
type="primary"
@click="handleAdd"
>新增紀錄</el-button>
<BillingDialog
:showDialog="showDialog"
:dialogData="dialogData"
@close="closeDialog"
/>
<BillingList @edit="handleEdit" />
data() {
return {
showDialog: false,
dialogData: {
action: '',
data: {}
}
}
},
methods: {
handleAdd() {
this.dialogData.action = 'ADD'
this.dialogData.data = {}
this.showDialog = true
},
handleEdit({ index, data }) {
this.dialogData.action = 'EDIT'
this.dialogData.data = data
this.dialogData.index = index
this.showDialog = true
},
closeDialog() {
this.dialogData.action = ''
this.dialogData.data = {}
this.showDialog = false
}
}
這邊稍微筆記一下,首先在 Billing
有兩個地方會發出事件叫 BillingDialog
打開:
Billing
中的「新增紀錄」按鈕BillingList
中每一列的「編輯」按鈕所以分別寫 handleAdd
與 handleEdit
的操作。而因為兩種操作的行為不一樣,需要紀錄一下是哪一種操作,這邊紀錄一個資料狀態如下:
dialogData: {
action: '',
data: {
dollar: 0,
type: '',
account: '',
title: ''
}
}
這裡的 action 紀錄是 ADD
還是 EDIT
,而 data 則是按編輯時要將原本當列的紀錄傳給 BillingDialog
。
再來還需要在 Billing
的地方紀錄 dialog 開關的狀態,這裡用 showDialog
表示。
最後還要知道 BillingDialog
什麼時候關閉對話框,所以需要一個關閉的 callback 事件,用來將 Billing
這一層 dialog 相關的資料 reset。
再來就可以處理 BillingDialog
這一層:
watch: {
showDialog: function(newValue) {
if (newValue) {
this.dialogFormVisible = true
if (this.dialogData.action === 'ADD') {
this.form = {
dollar: 0,
type: '',
title: '',
account: ''
}
} else {
this.form = { ...this.dialogData.data }
}
}
}
}
若是在父層收到開關變化說要打開, dialog 這層就將自己的開關狀態打開,並根據 action 的種類準備好對應的表單資料,其他的就交給 el-dialog
處理了。
今天修正了昨天搞不定的 dialog 共用的問題,明天先來研究怎麼弄後端系統吧,不然一直在 store 弄假資料最後仍然是要改不少。
紀錄一下第二個週末的有趣現象,團隊死線前衝刺有你有我真溫馨
第一種解法覺得遇到最困難的情況就會是當有需求是嵌套 dialog 的時候就會很慘了XD
對啊,可能就只能先關掉原本的,有需要的話再另外記住前一個 dialog 的資料。
但假如真的遇到有嵌套 dialog 的狀況,好像轉向思考其他的呈現方式會比較好,太多層的 dialog 畫面會有點複雜。