開始寫專案之前,團隊都是使用 Vue 2 寫畫面,Vue 2 要升級到 Vue 3 對我來說,最大的轉變就是 extends 了
Vue 2 用的是 Options API, Vue 3 寫的是 Composition API,寫法什麼的對還沒開始完成專案的我來說,好像沒太大差異。
但是當我實際開始寫之後,才知道我在專案上之前應用了很多 extends 用法,在 Vue 3 裡面通通失效了…
原本寫成 extends 的作法是讓每個 Component 都可以不必撰寫就有此方法,data 也可以逐一傳遞,現在通通要改成 Vue 3 的寫法。
先來看看 原本的 Vue 2 實現方式:
export default {
name: 'Base',
components: {},
data: function () {
return {
showQueryParam: false,
primaryKey: 'id',
pageInfo: {},
resource: new Map()
}
},
computed: {
list: {
get: function () {
return Array.from(this.resource.values())
},
set: function (newData) {
let resource = new Map()
Array.from(newData, (value, _key) => {
resource.set(value[this.primaryKey], value)
})
this.resource = resource
},
},
},
methods: {
setStandardResult(result) {
const { data, current_page, last_page, total, per_page } = result
this.list = data
this.pageInfo = { currentPage: current_page, lastPage: last_page, total: total, perPage: per_page }
},
}
}
原本我在 Vue 2 的寫法,後面只要元件使用 extends : Base ,那就會有內建的 data 數值,以及 methods ,還有 computed,這些參數都打好了,只需要 呼叫 API 的時候,使用 setStandardResult 把 laravel 內建的 paginate 取回,就可以很快的去設定 清單、分頁等內容,這些元件都可以持續的傳遞到 Pagination 元件或是 Table 元件等,要共用 function 就非常快速。
利用上述的 extends 方法,用 bootstrap vue 建立 sandbox 操作 建議開新頁看結果
現在專案要從 Vue 2 改成 Vue 3 ,讓我思考許久,看了許多參考文件,其中一個 Composition API 讓我感受到共用 function 的可能性。
就是 import 之後抽離 function 與 data ,並解構賦值,如此一來可以把預設的 data 塞到每個 Component 元件中,這邊簡單的說明
getStandardResource() {
const getData = () => {
return reactive({
primaryKey: 'id',
resource: new Map(),
pageInfo: {
disable: false,
page: 1,
pageSize: 10,
total: 0
},
list: computed({
get: () => Array.from(pageData.resource.values()),
set: (newData) => {
let resource = new Map()
Array.from(newData, (value, _key) => {
resource.set(value[pageData.primaryKey], value)
})
pageData.resource = resource
}
})
})
}
const pageData = getData()
const setStandardResult = (response) => {
const { current_page, last_page, total, per_page, data } = response
pageData.pageInfo = { current_page, last_page, total, per_page, disable: false }
pageData.list = data
}
return {
pageData,
setStandardResult
}
}
這段程式碼可以放在任一個要引入的地方,接著在你的 Component 裡面引入這隻檔案。
const { pageData, setStandardResult } = getStandardResource()
pageData 就是你預設的數值,你可以在 setup 裡面 return { …toRefs(pageData) } 把裡面每個變數響應到 template 中 setStandardResult 這個可以放到 methods 裡面,每次 call 完 API 去呼叫給值,這樣又可以異動原本的 pageData 數值,又不會跟其他 Component 的 pageData 汙染,Pagination 元件可以接受 pageInfo props 去顯示畫面,接收 emit 參數去異動 pageData 數值往後端發送。
利用上述的概念,用 quasar 2 建立出來的 sandbox 範例 建議開新頁看結果
主要應用在 /src/pages/Index.vue ,引入 /src/pages/base.js,當你有多頁相同 function 要共用的時候,可以利用 base.js 載入
每次應用相同的參數,來產生 Pagination Table 的元件所需的資料。
這種共用方式其實會來的比 Vue 2 還方便,可以把 function 拆分成你想要的組件,在資料的傳遞與改動數值如果在原始的 function 不好操作 ,建議改在原本的 Component 做就可以了,要不要轉換成共用的 function 可以視專案的程式碼的重複性質來引用。
以 Vue 2 的模式,就像是繼承一個血統一樣,父層有的基因繼承後的組件都會有,有些 data 你可能用不到,他會占用在你的實體中,但是這些 data 跟 method 你都可以用,或是被使用, Vue 3 的模式就像是捏臉系統一樣,你要從各個地方拿組件回來組回五官,但是你有可能組回來的東西會蓋過其他組件,所以在程式裡面撰寫者的掌握技術就很重要。