這篇文章主要講解了“如何使用Vue3開發(fā)一個(gè)Pagination公共組件”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何使用Vue3開發(fā)一個(gè)Pagination公共組件”吧!
創(chuàng)新互聯(lián)自成立以來(lái),一直致力于為企業(yè)提供從網(wǎng)站策劃、網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、電子商務(wù)、網(wǎng)站推廣、網(wǎng)站優(yōu)化到為企業(yè)提供個(gè)性化軟件開發(fā)等基于互聯(lián)網(wǎng)的全面整合營(yíng)銷服務(wù)。公司擁有豐富的網(wǎng)站建設(shè)和互聯(lián)網(wǎng)應(yīng)用系統(tǒng)開發(fā)管理經(jīng)驗(yàn)、成熟的應(yīng)用系統(tǒng)解決方案、優(yōu)秀的網(wǎng)站開發(fā)工程師團(tuán)隊(duì)及專業(yè)的網(wǎng)站設(shè)計(jì)師團(tuán)隊(duì)。
我們采用的是測(cè)試驅(qū)動(dòng)開發(fā)(TDD)開發(fā)的流程為
寫對(duì)應(yīng)功能點(diǎn)的文檔
寫對(duì)應(yīng)功能點(diǎn)的單元測(cè)試
跑測(cè)試案例,確保案例失敗
寫代碼實(shí)現(xiàn)
跑測(cè)試案例,確保案例成功
Vue3 的新特性
用 jest 測(cè)試,@vue/test-utils: 2.0.0-rc.6 測(cè)試 Vue 組件
jsx 語(yǔ)法
組織結(jié)構(gòu)參考 vitepress 文檔
主要根據(jù)設(shè)計(jì)師給出的 UI 效果圖,再結(jié)合其他優(yōu)秀的 UI 庫(kù)中的功能點(diǎn),最后討論得到我們需要實(shí)現(xiàn)的效果,最后寫文檔。
行覆蓋率(line coverage):每個(gè)可執(zhí)行代碼行是否都執(zhí)行了? 函數(shù)覆蓋率(function coverage):每個(gè)函數(shù)是否都調(diào)用了? 分支覆蓋率(branch coverage):每個(gè)流程控制的各個(gè)分支是否都執(zhí)行了? 語(yǔ)句覆蓋率(statement coverage):每個(gè)語(yǔ)句是否都執(zhí)行了?
測(cè)試驅(qū)動(dòng)開發(fā)要求測(cè)試用例編寫優(yōu)先于單元功能的實(shí)現(xiàn),這就需要先去思考組件該如何取拆分,拆分以后每個(gè)部分需要哪些功能。
對(duì)這些想象中的功能進(jìn)行測(cè)試。但是在實(shí)際開發(fā)過程中發(fā)現(xiàn)功能沒有開發(fā)出來(lái)之前編寫測(cè)試用例很難去做到一個(gè)比較高的一個(gè)測(cè)試覆蓋率,只好在功能開發(fā)完成以后對(duì)測(cè)試進(jìn)行一個(gè)補(bǔ)充。
如下是我在編寫功能之前給給的組織結(jié)構(gòu),功能實(shí)現(xiàn)在 jumper、pager、pagination、simpler、sizes、total 等 jsx 文件
- _tests_ - pagination.js - style - index.js - index.less - mixin.less - const.js - index.js - jumper.jsx - pager.jsx - pagination.jsx - simpler.jxs - sizes.jsx - total.jsx
其他部分的測(cè)試也類似
ShowQuickJumper 樹形為 true 的時(shí)候 jumper 相關(guān)功能才會(huì)展示,而判斷 jumper 是否展示可以通過渲染后的組件是否擁有的的特殊的 jumper 相關(guān) class 來(lái)實(shí)現(xiàn),@vue/test-utils 里面的 classes api 很好的實(shí)現(xiàn)這樣一個(gè)效果。
當(dāng) jumper 輸入的值不為數(shù)字、數(shù)字超出邊界、數(shù)字為 NaN 等問題的一個(gè)測(cè)試。
功能測(cè)試,當(dāng)輸入完成,失去焦點(diǎn)的時(shí)候是否可以跳轉(zhuǎn)到相應(yīng)的頁(yè)面。
測(cè)試都不能通過
測(cè)試覆蓋率不足 70%,可惜忘了截圖
如下圖,最終測(cè)試覆蓋率是100%
非常有必要,因?yàn)樵谧非?100% 的測(cè)試覆蓋率的時(shí)候我回去審查每一行代碼,看實(shí)際過程中是否每一行代碼都可以覆蓋到,而在這個(gè)過程中發(fā)現(xiàn)了一些冗余代碼,比如說我已經(jīng)在 jumper.jsx 里面已經(jīng)對(duì)回傳 pagination.jsx 中的數(shù)據(jù)進(jìn)行了一個(gè)處理,確保里面不會(huì)產(chǎn)生非數(shù)字,且不會(huì)超出邊界,而又在 pagination.jsx 中處理了一遍, 這樣導(dǎo)致 pagination 里面的處理變得多余,而永遠(yuǎn)不會(huì)執(zhí)行。因?yàn)槊恳恍?,每一個(gè)分支都可以執(zhí)行到,這樣也可以有效的減少潛在的 bug。
需要兼容切換風(fēng)格、后期可能會(huì)調(diào)整字體顏色、按鈕大小、按鈕之間的距離等,開發(fā)的時(shí)候所有顏色、常規(guī)的一些距離等等都需要再公共文件里面取。這樣每一個(gè)小的樣式都需要思考是否必須,是否需要在庫(kù)里取,開發(fā)過程可能會(huì)比直接寫顏色等要慢一些。
所以可能帶有的 class 都要有 is 屬性,is-disabled、is-double-jumper 啥的
盡量不用元素選擇器,一個(gè)是效率低,一個(gè)是變更時(shí)候容易照成必須要的影響
jsx 里面使用 bind 綁定事件時(shí)候,如果里面的第一個(gè)參數(shù)沒有意義,直接設(shè)為 null 即可,handleXxx.bind(null, aaa)
jsx 語(yǔ)句盡量格式化,簡(jiǎn)短一點(diǎn)
// setup 里面 // 不好的寫法 return ( <div> {simple.value ? <Simple xxx /> : <Pager xxx/>} <div> ) // 好的寫法 const renderPage = () => { if (simple.value) { return <Simele xxx/>; } return <Pager xxx/> } return ( <div> {renderPage()} </div> )
功能的功能盡量封裝成 hooks, 比如實(shí)現(xiàn) v-model
setup 函數(shù)接受兩個(gè)參數(shù),一個(gè)是 props, 一個(gè)是 context
不能用 es6 解構(gòu),解構(gòu)出來(lái)的數(shù)據(jù)會(huì)失去響應(yīng)式,一般會(huì)使用 toRef 或者 toRefs 去處理
該參數(shù)包含 attrs、slot、emit,如果里面需要使用到某個(gè) emit,則要在 emits 配置中聲明
import { definedComponent } from 'vue'; export default definedComponent({ emits: ['update:currentPage'], setup(props, { emit, slot, attrs }) { emit('update:currentPage'); ... } })
pageSize 和 currentPage 兩個(gè)屬性都需要實(shí)現(xiàn) v-model。
vue 2 實(shí)現(xiàn)自定義組件一到多個(gè)v-model雙向數(shù)據(jù)綁定的方法
https://blog.csdn.net/Dobility/article/details/110147985
假如只需要實(shí)現(xiàn) currentPage 雙向綁定, vue3 默認(rèn)綁定的是 modelValue 這個(gè)屬性
// 父組件使用時(shí)候 <Pagination v-model="currentPage" /> // 相當(dāng)于 <Pagination :modelValue="currentPage" @update:modelValue="(val) => {currentPage = val}" /> // Pagination 組件 import { defineComponent } from vue; export default defineComponent({ props: { currentPage: { type: Number, default: 1 } } emits: ['update:currentPage'], setup(props, { emit }) { 當(dāng) Pagaintion 組件改變的時(shí)候,去觸發(fā) update:currentPage 就行 emit('update:currentPage', newCurrentPage) } })
pageSize 和 currentPage 兩個(gè)屬性都需要實(shí)現(xiàn) v-model
// 父組件使用時(shí)候 <Pagination v-model:currentPage="currentPage" v-model:pageSize="pageSize" /> // Pagination 組件 import { defineComponent } from vue; export default defineComponent({ pageSize: { type: Number, default: 10, }, currentPage: { type: Number, default: 1, }, emits: ['update:currentPage', 'update:pageSize'], setup(props, { emit }) { 當(dāng) Pagaintion 組件改變的時(shí)候,去觸發(fā)相應(yīng)的事件就行 emit('update:currentPage', newCurrentPage) emit('update:pageSize', newPageSize) } })
對(duì)于綁定單個(gè)屬性來(lái)說感覺方便程度區(qū)別不大,而綁定多個(gè)值可以明顯感覺 Vue3 的好處,不需要使用 sync 加 computed 里面去觸發(fā)這種怪異的寫法,直接用 v-model 統(tǒng)一,更加簡(jiǎn)便和易于維護(hù)。
實(shí)際組件中未使用,這里舉例說明
import { reactive } from 'vue'; // setup 中 const data = reactive({ count: 0 }) console.log(data.count); // 0
jumper 文件中用來(lái)給用戶輸入的數(shù)據(jù)添加響應(yīng)式
import { defineComponent, ref, } from 'vue'; export default defineComponent({ setup(props) { const current = ref(''); return () => ( <div> <FInput v-model={current.value}></FInput> </div> ); }, });
當(dāng)然,其實(shí)用 ref 給對(duì)象添加響應(yīng)式也是可以的,但是每次使用的時(shí)候都需要帶上一個(gè)value, 比如,變成 data.value.count 這樣使用, 可以 ref 返回的數(shù)據(jù)是一個(gè)帶有 value 屬性的對(duì)象,本質(zhì)是數(shù)據(jù)的拷貝,已經(jīng)和原始數(shù)據(jù)沒有關(guān)系,改變 ref 返回的值,也不再影響原始數(shù)據(jù)
import { ref } from 'vue'; // setup 中 const data = ref({ count: 0 }) console.log(data.value.count); // 0
toRef 用于為源響應(yīng)式對(duì)象上的屬性新建一個(gè) ref,從而保持對(duì)其源對(duì)象屬性的響應(yīng)式連接。接收兩個(gè)參數(shù):源響應(yīng)式對(duì)象和屬性名,返回一個(gè) ref 數(shù)據(jù),本質(zhì)上是值的引用,改變了原始值也會(huì)改變
實(shí)際組件并未使用,下面是舉例說明
import { toRef } from 'vue'; export default { props: { totalCount: { type: number, default: 0 } }, setup(props) { const myTotalCount = toRef(props, totalCount); console.log(myTotalCount.value); } }
toRefs 用于將響應(yīng)式對(duì)象轉(zhuǎn)換為結(jié)果對(duì)象,其中結(jié)果對(duì)象的每個(gè)屬性都是指向原始對(duì)象相應(yīng)屬性的 ref。常用于es6的解構(gòu)賦值操作,因?yàn)樵趯?duì)一個(gè)響應(yīng)式對(duì)象直接解構(gòu)時(shí)解構(gòu)后的數(shù)據(jù)將不再有響應(yīng)式,而使用 toRefs 可以方便解決這一問題。本質(zhì)上是值的引用,改變了原始值也會(huì)改變
// setup 中 const { small, pageSizeOption, totalCount, simple, showSizeChanger, showQuickJumper, showTotal, } = toRefs(props); // 這樣就可以把里面所有的 props '解構(gòu)'出來(lái) console.log(small.value)
由于 props 是不能用 es6 解構(gòu)的,所以必須用 toRefs 處理
reactive、toRef、toRefs 處理返回的對(duì)象是原始對(duì)象的引用,響應(yīng)式對(duì)象改變,原始對(duì)象也會(huì)改變,ref 則是原始對(duì)象的拷貝,和原始對(duì)象已經(jīng)沒有關(guān)系。
ref、toRef、toRefs 返回的響應(yīng)式對(duì)象都需要加上 value, 而 reactive 是不需要的
reactive 為普通對(duì)象;ref 值類型數(shù)據(jù);toRef 響應(yīng)式對(duì)象,目的為取出某個(gè)屬性; toRefs 解構(gòu)響應(yīng)式對(duì)象;
如果想要復(fù)用是一個(gè)功能,vue2 可能會(huì)采用 mixins 的方法,mixins 有一個(gè)壞處,來(lái)源混亂,就是有多個(gè) mixin 的時(shí)候,使用時(shí)不知道方法來(lái)源于哪一個(gè) mixins。而 Vue3 hooks 可以很好解決這一個(gè)問題。我們把 v-model 寫成一個(gè) hook
const useModel = ( props, emit, config = { prop: 'modelValue', isEqual: false, }, ) => { const usingProp = config?.prop ?? 'modelValue'; const currentValue = ref(props[usingProp]); const updateCurrentValue = (value) => { if ( value === currentValue.value || (config.isEqual && isEqual(value, currentValue.value)) ) { return; } currentValue.value = value; }; watch(currentValue, () => { emit(`update:${usingProp}`, currentValue.value); }); watch( () => props[usingProp], (val) => { updateCurrentValue(val); }, ); return [currentValue, updateCurrentValue]; }; // 使用的時(shí)候 import useModel from '.../xxx' // setup 中 const [currentPage, updateCurrentPage] = useModel(props, emit, { prop: 'currentPage', });
可以看到,我們可以清晰的看到 currentPage, updateCurrentPage 的來(lái)源。復(fù)用起來(lái)很簡(jiǎn)單快捷,pager、simpler 等頁(yè)面的 v-model 都可以用上 這個(gè) hook
感覺和 Vue2 中用法類似,不同點(diǎn)在于 Vue3 中使用的時(shí)候需要引入。 舉例 watch 用法由于 currentPage 改變時(shí)候需要觸發(fā) change 事件,所以需要使用到 watch 功能
import { watch } from 'vue'; // setup 中 const [currentPage, updateCurrentPage] = useModel(props, emit, { prop: 'currentPage', }); watch(currentPage, () => { emit('change', currentPage.value); })
感謝各位的閱讀,以上就是“如何使用Vue3開發(fā)一個(gè)Pagination公共組件”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)如何使用Vue3開發(fā)一個(gè)Pagination公共組件這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
本文名稱:如何使用Vue3開發(fā)一個(gè)Pagination公共組件
本文來(lái)源:http://jinyejixie.com/article20/joggjo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、軟件開發(fā)、用戶體驗(yàn)、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)