h5平臺搭建(H5開發(fā)平臺有哪些)

大型 H5 項(xiàng)目開發(fā)的思考
不知不覺已經(jīng)是第四次接手負(fù)責(zé)每年的大型 H5 活動,這也意味著 4 年啦啊啊啊啊,哎時間過得真是太快,也是應(yīng)該做一點(diǎn)總結(jié)了。
每年都會有大型的 H5 項(xiàng)目上線,這一些項(xiàng)目的邏輯在一般的情況下,它們的差別不會很大,但是每一次都會有不同的樣式、條件和玩法。如果每一次大活動都是寫死邏輯且不可復(fù)用,下一次 H5 項(xiàng)目過來又再寫一次其實(shí)就是很沒有必要的事情。
如果能把這一些做過的組件做成通用可配置的,即插即用。那么肯定是會極大的提高開發(fā)效率,同時項(xiàng)目的穩(wěn)定性也有保證。只不過組件的代碼邏輯就會比較復(fù)雜,開發(fā)難度會比較高,就單單組件內(nèi)的一個按鈕就需要考慮到這個按鈕的顏色,大小,按鈕內(nèi)的字體各種樣式和背景色以及這按鈕是不是設(shè)計(jì)狀態(tài)變化,若有還要考慮這一個狀態(tài)變化的邏輯或者是一些聯(lián)動的可能。所以,一個通用組件需要考慮和實(shí)現(xiàn)的邏輯就很多。
舉個例子,比如今年的 H5 有一個 “我的獎品” 模塊 ( 頁面 or 彈窗 ),這個模塊里面有的獎品的信息展示、時間的展示、數(shù)量的展示以及底部還有一些其他的按鈕。以下是我截取兩次不同的活動的“我的獎品”列表展示模塊。

這兩種樣式的組件,大致的框架上都是一樣的,點(diǎn)擊側(cè)邊欄的 “我的獎勵” 和 “我的背包”,只是展現(xiàn)形式和展示數(shù)據(jù)類型以及按鈕的點(diǎn)擊事件是不一樣的。
所以,如果第三次 H5 ,或者以后的 H5 都寫一遍這樣的東西意義不大。所以,這樣使用頻率比較高的模塊,就必須和業(yè)務(wù)方討論。我們可以把這樣的模塊定出一個基本的交互和原型,統(tǒng)一做成一個通用列表展示組件,這個組件必須支持通用樣式的展示,也需要支持特殊的樣式展示,例如下面的情況

最左邊的也就是正常的列表樣式,右邊的就是一些特殊的卡片和文字樣式,所以,一個組件需要考慮的東西有很多。
這里叫列表展示組件而不叫“我的獎品組件”的原因是:我們只需要通過參數(shù)控制它需要展示什么的內(nèi)容、標(biāo)題是什么、按鈕名稱是什么、點(diǎn)擊之后的邏輯是什么,而不是只局限于我的獎品列表,它也可以用于其他數(shù)據(jù)的展示。同時,這樣的通用組件可以適用于各種 H5 。組件拿來即用或者用于一些 H5 自動生成的平臺,只要根據(jù)文檔傳參數(shù)就可以了。

通過 config 控制具體的展示名字還有按鈕id的標(biāo)記區(qū)分事件,data 初始化組件的列表,與業(yè)務(wù)區(qū)分開來這里就變成了一個很純粹的列表展示組件,可以展示任意的數(shù)據(jù),只要按照格式傳參就行。這里只是寫一個很簡單的 DEMO ,后面會提到入?yún)⒑秃瘮?shù)綁定。
規(guī)劃公共組件
拿到設(shè)計(jì)稿之后找出通用的模塊,再根據(jù)類似模塊之間的差異定出一個通用的規(guī)則。下面是本次大型 H5 的設(shè)計(jì)稿總覽:
第一大類:分組賽,資格賽,彈窗,規(guī)則和投票等

第二大類:沖刺賽,總決賽,PK模塊等

此次大型 H5 的分為了幾個大階段,分組賽,資格賽,沖刺賽和總決賽??瓷先ナ欠浅6鄡?nèi)容的,所以需要找出相似的模塊,再和業(yè)務(wù)側(cè)溝通從這幾個賽段來看,可以抽離成組件的是
- TAB 切頁組件
- 進(jìn)度條組件
- 列表記錄組件
- 時間軸組件
- 排行榜組件
- 倒計(jì)時組件
- 投票組件
- 側(cè)邊欄懸浮組件
- pk 模塊組件
- 我的信息展示組件
- 頂部組件
- 吸底組件
- 按鈕組件
- 主播展示組件
這里就拿一部分的組件描述一下實(shí)現(xiàn)思路,全部寫的話就太多了,而且有些地方邏輯實(shí)現(xiàn)上也是比較像的。
組件的通用參數(shù)
組件傳入?yún)?shù)
一個通用組件所需要的配置參數(shù)一般歸納為幾種,最重要的是這個組件的所有需要使用的值,也就是這個初始化參數(shù)。其次,是這個組件的一些樣式配置或者是全局參數(shù)輔助使用,還有一些情況需要特定的屬于這個組件的 key 。當(dāng)然,不是說樣式和全局參等等是不重要的參數(shù),而是根據(jù)業(yè)務(wù)的需求來定,可能樣式的參數(shù)才是重點(diǎn)這個也是可能的,具體的還得從業(yè)務(wù)或者這個組件本身的性質(zhì)考慮,只是在做組件的時候優(yōu)先考慮功能的實(shí)現(xiàn)。以下是我封裝通用組件的一個習(xí)慣,分別綁定的參數(shù)是 data, styleForm, commonStyle, global, componentKey。以下是一個組件綁定參數(shù)和方法的例子:
<template>
<head-section
:data="headData"
:global="global"
:styleForm="headConfig"
:commonStyle="headCommonStyle"
:componentKey="headComponentKey"
@methods="headMethods"
/>
</template>
<script>
export default {
data(){
return {
// 全局配置
global: {},
// 頂部組件配置
headData: {},
headConfig: {},
headCommonStyle: {},
headComponentKey: {},
}
}
}
</script>
data 組件初始化參數(shù)
data 是這個組件傳入的初始化參數(shù)或者是渲染組件的所有數(shù)據(jù),類型是 Object 。組件可以用初始化參數(shù)通過 ajax 獲取數(shù)據(jù)也可以通過 class 執(zhí)行初始化邏輯或者是直接將數(shù)據(jù)綁定在這個 data 中。
<script>
// 組件
export default {
props: {
data: {
type: Object,
default: () => ({
// list:[], example
// total: 10 example
}),
},
}
</script>
styleForm 組件的配置參數(shù)
styleForm 這個是組件的配置信息,比如這個組件的一些背景、樣式信息以及一些固定的數(shù)據(jù)不會發(fā)生變化的數(shù)據(jù)。數(shù)據(jù)格式類型是 Object 。
<script>
// 組件
export default {
props: {
styleForm: {
type: Object,
default: () => ({
// styles: {}, example
// bg: './images/xx.png' example
}),
},
}
</script>
commonStyle 通用樣式配置參數(shù)
commonForm 這個參數(shù)是通用的樣式配置,比如,控制這個組件的寬、高以及背景色等等。這個我們在自己在獨(dú)立開發(fā)的 H5 的時候,會按照這樣的參數(shù)格式配置。目的是讓組件更加通用,適用于不同的地方,比如一些 H5 的自動生成平臺。 因?yàn)?,在互?lián)網(wǎng)大廠里 H5 的開發(fā)如果是比較簡單的頁面,是不會單獨(dú)用人力去開發(fā)的,而是通過平臺配置生成 H5。我們需要做的就是提供各種各樣的組件,讓業(yè)務(wù)同學(xué)去配置使用。所以,平臺的配置是以每個功能模塊劃分,commonForm 可以接入他們的平臺的接口數(shù)值,直接在平臺上控制這個組件的寬、高、是否居中等等的基礎(chǔ)樣式。
<script>
// 組件
export default {
props: {
commonStyle: {
type: Object,
default: () => ({
// width: 300, example
// height: 20 example
}),
},
}
</script>
global 全局屬性
全局屬性指的是這個項(xiàng)目的唯一標(biāo)記,適用于項(xiàng)目中的任意一個地方。比如說這個項(xiàng)目的 id ,他可能在做上報(bào)操作或者在請求接口的時候需要帶上這個參數(shù)。那么就由 global 這個參數(shù)統(tǒng)一接收。類型也是 Object 。
<script>
// 組件
export default {
props: {
global: {
type: Object,
default: () => ({
// page_id: 111, example
}),
},
}
</script>
componentKey
componentKey 是組件的標(biāo)記,主要用于在做區(qū)分組件的時候,使用比如上報(bào)數(shù)據(jù)。同時也可以用于一些非常特定的邏輯,提供臨時的解決方法。舉個非常簡單例子:業(yè)務(wù)方需要畫 10 個圓且背景都是白色,突然間提出要在第 9 個圓中某個位置加上一個黑色的點(diǎn),其他不變。 這樣既不合理也不通用還砍不掉的需求,臨時的解決方法就是通過 key 寫一個 if else ,之后再說。
<script>
// 組件
export default {
props: {
componentKey: {
type: [String,Number],
default: 1, // example
},
}
</script>
@methods 方法綁定
在組件內(nèi)通過輸出按鈕 id 或者事件類型,由上一層組件進(jìn)行執(zhí)行特定邏輯,這樣的好處是通用的樣式和 DOM 與 JavaScript 分離,不含有業(yè)務(wù)邏輯一下次也可以直接復(fù)用這個組件,不需要再去改。
組件
<template>
<div class="head-section" style="padding: 0px 0px">
<div
class="lottery-btn"
@click="onClickBtn('lottery', 'normal')"
></div>
<div
class="nav-btn rule-btn"
@click="onClickBtn('rule', 'page')"
></div>
</div>
</template>
<script>
export default {
methods: {
onClickBtn(id, type = 'page', eventParams = {}) {
this.$emit('methods',{
id: type,
value: eventParams
});
},
},
}
</script>
父級組件
<script>
export default {
methods: {
headMethods($Event) {
const { id, value } = $Event;
const page = (params) => {
this.goPage();
};
const anchor = (params) => {
this.goAnchor();
};
const clickEventMap = {
'page': page,
'anchor': anchor,
};
// 區(qū)分不同事件類型 傳參
clickEventMap[id](value);
},
goAnchor(params) {
// ...
},
goPage(params) {
// ...
}
},
}
</script>
頁面頂部組件
組件布局和實(shí)現(xiàn):

組件封裝思路
首先從功能上看,這個組件只能適用于獨(dú)立開發(fā)的 H5 ,它不適合 H5 生成平臺?;蛘哒f這樣的組件在 H5 生成平臺完全沒有意義。因?yàn)?,左邊?icon 和右邊按鈕列表,他們在 H5 生成平臺里面,這些按鈕都是靠使用者自己手動配置的地方。例如: 左邊的 icon 就是使用一個按鈕組件拖拽進(jìn)去,再加上一個跳轉(zhuǎn)事件。 右邊的 btn-list 可以看成是 3 個獨(dú)立按鈕,也和上面一樣用一個按鈕組件拖拽進(jìn)去,加上一個跳轉(zhuǎn)事件,再連續(xù)配置 3 次。
但是,這一次是獨(dú)立開發(fā),所以只能按照可復(fù)用定制模版的思路來實(shí)現(xiàn)。需要考慮的地方是:
- 頭圖片支持背景配置
- 左邊的按鈕支持背景設(shè)置,文案設(shè)置和顯隱設(shè)置。
- 右側(cè)的按鈕列表中支持單個按鈕的背景設(shè)置,文案設(shè)置和顯隱設(shè)置以及支持再新增加多個按鈕的情況下可復(fù)用樣式 。

如圖:對應(yīng)的每個模塊使用一個 ID 作為區(qū)分,其中 btn-list 包含以 btn-x 為唯一的標(biāo)記,內(nèi)容就是控制這個按鈕的背景,顯隱和文案。
之后再通過 headData 來渲染 btn-list ,數(shù)據(jù)格式為:
<script>
export default {
data() {
return {
headData:[
{
id: 'btn-1',
value: {
url: '...'
}
},
{
id: 'btn-2',
value: {
url: '...'
}
}
....
]
}
},
}
</script>
它的核心思想就是通過 ID 關(guān)聯(lián)數(shù)據(jù),通過 ID 關(guān)聯(lián)配置。這有點(diǎn)像是數(shù)據(jù)庫里面的主鍵,可以根據(jù)這個主鍵可以查詢或者關(guān)聯(lián)查找其他的數(shù)據(jù)表。

細(xì)節(jié)實(shí)現(xiàn)要點(diǎn)
寫一個通用的方法,在后面如果有新增的按鈕,可以直接通過傳參 (第幾個按鈕) 控制按鈕的位置。
@function head-nav-btn-top($number) {
$top: 15;
$boxHeight: 46;
@if($number == 1){
@return 385;
}
@return 385 + (($top + $boxHeight) * ($number - 1));
}
// .class
top: remit(head-nav-btn-top(1));
top: remit(head-nav-btn-top(2));
top: remit(head-nav-btn-top(3));
錨點(diǎn)跳轉(zhuǎn)到參數(shù)指定位置
headMethods($Event){
const { id, value } = $Event;
if (id === 'lottery-btn') {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
window.scrollTo(scrollTop, this.$refs[value].offsetTop);
}
},
倒計(jì)時組件
組件布局和實(shí)現(xiàn):

組件封裝思路
倒計(jì)時組件在邏輯上是比較簡單的,更多需要考慮倒計(jì)時的展示樣式,因?yàn)樵?H5 里面,每種設(shè)計(jì)的風(fēng)格或者業(yè)務(wù)需求不一樣,不可能一直沿用一種樣式的倒計(jì)時,比如這樣

所以需要考慮的點(diǎn)是:
- 倒計(jì)時的多種展示樣式和展示形式,比如是否需要拼接標(biāo)題和展示天數(shù)或者秒數(shù)。
- 倒計(jì)時在結(jié)束的時候需要執(zhí)行的下一步邏輯。
細(xì)節(jié)實(shí)現(xiàn)要點(diǎn)
在計(jì)算倒計(jì)時的方法上有兩種,第一種是獲取本地手機(jī)時間再寫一個 inteval 函數(shù)遞減計(jì)算,第二種是使用 interval 每秒都向服務(wù)器進(jìn)行時間獲取計(jì)算出剩余時間。 這里我一般會選擇后面那種,因?yàn)椋紫缺镜貢r間不一定是正確的,也有可能是人為的去修改了系統(tǒng)的時間,其次,本地的 interval 延遲時間不一定準(zhǔn)確。比如我們設(shè)定 1000 毫秒執(zhí)行,但是由于部分手機(jī)本身的原因,這里可能存在著誤差,設(shè)定的是 1000 毫秒,而在實(shí)際的執(zhí)行中,它相當(dāng)于 800 毫秒。那么就會導(dǎo)致一個問題,本地的時間越算,誤差越大,如果在頁面中的時間停留較短那問題不大,但是如果在頁面的停留時間很長,到了最后看上就是一個大大的 BUG 。所以,每次都讀取服務(wù)器時間是比較靠譜的。
實(shí)現(xiàn)要點(diǎn):
<template>
<div class="countdown-section">
<div
v-if="styleForm.type === 'normal'"
:style="[{ 'background-image': `url(${styleForm.bgUrl})` }]"
:class="['countdown-section-bg', `width-${styleForm.bgWidth}`]"
>
<div class="countdown-content">
<p class="time-front" v-text="styleForm.timeFront"></p>
<p class="time" v-text="countTime"></p>
<p class="time-end" v-text="styleFrom.timeEnd"></p>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {
countdown() {
...
this.timeStr = {} //data
this.format = ['hours', 'minutes','seconds'] // props
for(let i = 0 ;i < format.length; i++ ){
this.timeStr = this.time[format[i]];
}
},
},
}
</script>
節(jié)點(diǎn)樣式方面:讓 countdown-content 的內(nèi)容居中,倒計(jì)時前后可以配置任意文案,再給 clase="time" 加上一個寬度,這樣的好處是避免了在數(shù)字變化的時,因倒計(jì)時數(shù)字切換發(fā)生的抖動而影響到了整個倒計(jì)時文案的抖動問題。另一個是,在倒計(jì)時外層再包一層 v-if 樣式,這個是來拓展倒計(jì)時多種樣式的功能。
邏輯方面:傳入一個時間格式的配置項(xiàng),比如是否需要展示天數(shù)或者秒數(shù),使用一個循環(huán)指定數(shù)據(jù)更新。最后的時間由 computed 計(jì)算屬性將 day, hours minutes , seconds 計(jì)算出來。同時,倒計(jì)時為零的時候支持配置一個方法,例如,最常見的操作就是刷新當(dāng)前頁面或者是執(zhí)行跳轉(zhuǎn)。
進(jìn)度條組件
組件布局和實(shí)現(xiàn)

組件封裝思路
進(jìn)度條組件和倒計(jì)時組件一樣,屬于邏輯比較簡單而比較注重樣式上的一些配置。進(jìn)度條組件需要考慮的點(diǎn)是:
- 背景色支持漸變配置
- 進(jìn)度條每個節(jié)點(diǎn)上面和下面的文案與樣式支持配置
- 進(jìn)度條的節(jié)點(diǎn)所有內(nèi)容支持顯隱
細(xì)節(jié)實(shí)現(xiàn)要點(diǎn)
<template>
<div class="progress-content">
<div class="progress">
<div class="progress-line"
:style="{ width: `${currentProgress}%`, backgroundImage: `linear-gradient(
to right,
${styles.lineStyle.begin},
${styles.lineStyle.end}
)`}"></div>
<div class="progress-state">
<div v-for="(item, index) in styles.list"
:key="`${index}buttom`"
:style="[{ 'background-image': `url(${+index <= +current ? styles.dot.high: styles.dot.normal})` }]"
class="state"
>
<div v-if="item.topText" :style="styles.top[index]" :class="['top']" v-text="item.topText"></div>
<div v-if="item.bottomText" :style="styles.bottom[index]" class="buttom" v-text="item.bottomText"></div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {
},
}
</script>
首先,通過 props 進(jìn)來的 styles參數(shù), 獲取到這個進(jìn)度條的顏色,為了進(jìn)度條能有更多的顏色配置,就是用漸變色來配置,只要傳入一個開始和一個結(jié)束的色值。
節(jié)點(diǎn)的的樣式和文案全部通過數(shù)組渲染,來達(dá)到通用配置的目,以下是我截取簡易的配置數(shù)據(jù)
const progress = {
top: [
{
color: '#f5ddff',
},
{
color: '#d6a5ea',
},
....
],
bottom: [
{
color: '#d6a5ea',
},
{
color: '#d6a5ea',
},
....
],
dot: {
high: '',
normal: '',
},
list: [
{
topText: 'Switch',
bottomText: '0',
hidden: false
},
{
topText: '2部',
bottomText: '10000',
hidden: false
},
...
],
lineStyle:{
begin:'rgba(255, 166, 248, 1)',
end:'rgba(255, 58, 210, 1)'
}
};
吸底組件
組件布局和實(shí)現(xiàn):

組件封裝思路
吸底部組件和頂部組件一樣,它不適用于 H5 自動生成平臺。吸底組件和頂部組件它們更像是一個容器,在這個容器里面配置其他的組件,所以這里還是做成一個可復(fù)用的定制模版。需要考慮的一些點(diǎn):
- 最左邊部分的頭像和和昵稱可以寫死固定下來同時需要配置默認(rèn)打底狀態(tài)數(shù)據(jù)。
- 中間部分的票數(shù)做成可配置的情況可以展示 1 行或者 2 行以及支持顯隱。
- 最右邊部分的按鈕同樣支持可配置 1 個或者 2 個以及支持顯隱。
- 可配置背景色
細(xì)節(jié)實(shí)現(xiàn)要點(diǎn)
他們的數(shù)據(jù)格式是:
<script>
export default {
data() {
return {
// 數(shù)據(jù)源綁定
suspensionData: {
userSection: {
name: 'xxxx',
url: '....png',
},
textSection: [
{
'text': `已貢獻(xiàn)助力票數(shù): 600`
},
{
'text': `剩余助力票數(shù): 400`
}
],
},
// 數(shù)據(jù)配置樣式設(shè)定
suspensionConfig: {
bg: '....png',
btn: [
{
'id': 'get',
'url': '....png',
'text': '獲取助力票'
},
{
'id': 'exchange',
'url': '....png',
'text': '兌換助力票'
}
]
},
},
},
}
</script>
中間的文字展示和右邊的按鈕使用 Array 的形式渲染
<template>
...
<div
v-if="btn && btn.length > 0"
:class="['item-right, `length-${btn.length}`']"
>
...
</div>
</template>
<style lang="scss" scoped>
...
.btn{
...
&.length-2{
justify-content: space-between;
}
&.length-1{
justify-content: space-evenly;
}
}
</style>
在樣式上線配置好 length-x 情況下是居中還是均分的樣式。中間的文字也是同樣的方法,只是這里就多了一些細(xì)節(jié)的考慮,比如:字體容器的溢出處理和行間距的一些設(shè)定。
頭像和昵稱按理也可以做一些設(shè)定,但是這里根據(jù)實(shí)際的需求來說沒有必要,所以這里就直接固定下來。
投票組件
組件布局和實(shí)現(xiàn)

組件封裝思路
這個 H5 的投票功能相對簡單,只有一個增加/減少和最大值。
在做這個組件之前,我其實(shí)更想把它做成這樣的形式。如圖:

它可展示圖片,還可以展示選擇票的類型,同時下面還可以配置拓展按鈕也可以綁定執(zhí)行事件,看上去非常的好。但是后來想了一下,還是覺得這樣投票組件的邏輯會有點(diǎn)冗余,既然是一個投票組件應(yīng)該不就有其他的東西。
所以我也在原來的基礎(chǔ)上結(jié)合這個組件多加了一投票的類型選擇。就是這樣:

這樣看上去邏輯簡單,而且也確實(shí)多了是一個實(shí)用的功能。所以,這個組件需要考慮的點(diǎn)是:
- 增加/減少和最大值的計(jì)算
- 類型選擇同時可以支持拓展以及默認(rèn)隱藏使用。
細(xì)節(jié)實(shí)現(xiàn)要點(diǎn)
<template>
...
<!-- 票數(shù)編輯區(qū)域 -->
<div class="ticket-section">
<div class="ticket-edit">
<input class="ticket-text" v-model="ticketInfo['count']"/>
<div :class="['ticket-add']" @click="ticketAdd()" >
<p class="add">+</p>
</div>
<div :class="['ticket-min']" @click="ticketMins">
<p class="min">-</p>
</div>
</div>
<div :class="['ticket-max', 'allow']">
<p class="max" @click="ticketAdd(true)">MAX</p>
</div>
</div>
<!-- 類型選擇區(qū)域 -->
<div class="ticket-type-section">
<div v-if="typeList.length > 0" class="ticket-type-content">
<div v-for="(item,index) in typeList" :key="`type${index}`"
class="ticket-type-item">
<div :class="['box',item.active? 'active': '']"></div>
<div v-text="item.text"></div>
</div>
</div>
</div>
...
</template>
首先用一個數(shù)組渲染類型列表,編輯區(qū)域票數(shù)區(qū)域比較重要的的就是做好數(shù)字上的校驗(yàn)和統(tǒng)一管理檢驗(yàn)失敗的提示文案。
const tipsMap = {
error: '親!剩余助力票不足,請重新輸入!',
success: '助力成功!',
errorNum: '必須是一個數(shù)值,注意不能有空格',
errorMax: '親,剩余助票不足,請重新輸入',
errorZero: '親,剩余助票不足,請去獲取哦!',
};
const validCount = (num) => {
this.$set(this, 'showTips', false);
const regExp = /^\+?[1-9][0-9]*$/g;
if (+this.ticketInfo.count === 0) {
return false
}
if (!regExp.test(this.ticketInfo.count)) {
this.toast(tipsMap['errorNum'])
return false;
};
if (+this.ticketInfo.count > +this.ticketInfo.left){
this.toast(tipsMap['errorMax'])
return false;
};
// 檢驗(yàn)通過
return true;
}
},
validCount(1000);
排行榜組件
組件布局和實(shí)現(xiàn)

組件封裝思路
排行組件是這一個活動邏輯最復(fù)雜的一個,他除了需要支持到這個活動展示的列表數(shù)據(jù),也需要支持到以后其他 H5 的數(shù)據(jù)展示,也就是支持拓展。 比如:在這個排行榜中,第一列是一個頭像列表類型,第二列是一個文字類型,第三列也是一個頭像類型,第四列是一個按鈕類型。那么,在組件初始化的時候通過 config 配置定義好每一列的類型和樣式。如圖:

const rankConfig = { init: [ { type: 'headList', key: 'head', name: '超能', tips: 'live', style: { width: '25%', color: '#ffffff', background: '#c69494', } }, { type: 'text', key: 'score', name: '總助力值', style: { width: '25%', color: '#ffffff', background: '#e53de7', } }, .... ]};
這一段是部分配置
- type 是數(shù)據(jù)類型,比如 純文字,頭像或者按鈕。
- key 是對應(yīng)實(shí)際數(shù)據(jù)的 key,通過這個 key 讓這一列展示這個字段的內(nèi)容。
- name 是這一列的標(biāo)題
- style 是這一列的具體樣式配置參數(shù)。
以后無論是需要怎么樣的一個排行榜,先查找文檔看看是不是都有這樣類型的樣式,沒有的話拓展,有的話只需要傳入配置參數(shù)之后,再傳入具體的數(shù)據(jù)就可以跑起一個排行榜的組件。
從功能上看他需要支持:
- 支持?jǐn)?shù)據(jù)分頁
- 支持?jǐn)?shù)據(jù)展示和拓展展示的數(shù)據(jù)類型
- 點(diǎn)擊事件通用配置
細(xì)節(jié)實(shí)現(xiàn)要點(diǎn)
標(biāo)題部分主要代碼:
<template>
...
<div v-for="(item, index) in styles.init"
:style="item.style"
:class="['column-item', 'column-type']"
:key="`${index}column`">
<div class="item-title">
<p class="title-text" v-text="item.name"></p>
<slot class="title-tips" :name="`sub-${item.key}`"></slot>
</div>
</div>
</template>
使用配置項(xiàng)循環(huán)列出列表的標(biāo)題,里面有個 icon 的提示圖標(biāo),使用插槽的方式插入,這里需要用 sub-${item.key} 作為一個區(qū)分,需要顯示 tips icon 的標(biāo)題才展示。這里只能用 key 作為區(qū)分不能用 type,原因是一個列表里面是有可能有相同的 type 列的。
列表的渲染,這里需要各種類型的展示再抽離成一個小組件,比如將 text ,headList 等等抽離成一個小組件,需要的時候再引用。這樣做的好處出邏輯分開容易維護(hù),小組件容易拓展,排行榜的代碼也不會過多,如圖:

他的核心代碼如下:
<template>
...
<div
class="column"
v-for="(item, index) in info.list"
:key="`${index}rankList`"
>
<div
v-for="(styleItem, styleIndex) in styles.init"
:key="`${styleIndex}rankConfig`"
:class="'column-item'"
>
<HeadList
v-if="styleItem.type === 'headList'"
@methods="onClickEvent(item.key, item)"
><HeadList>
<Text v-if="styleItem.type === 'text'"></Text>
<ListBtn v-if="styleItem.type === 'btn'"></ListBtn>
</div>
</div>
</template>
第一層循環(huán)遍歷所有列表數(shù)據(jù),第二層循環(huán)遍歷配置表,根據(jù)類型渲染具體內(nèi)容,之后每一個塊的內(nèi)容都通過小組件形式引入。

如若轉(zhuǎn)載,請注明出處:http://www.qjsdgw.cn/86234.html