隨著我國電動汽車的不斷探索與發(fā)展,如今的電動車數(shù)量有了質(zhì)的飛躍,為了更好的提供充電服務(wù),充電樁也在各個公共場合建議起來。在移動互聯(lián)網(wǎng)的下的今天,軟件與硬件的結(jié)合成為了一種趨勢,為了給予廣大車主更加方便的充電服務(wù),充電樁app被開發(fā)而來,有效的提高了充電效率,也進(jìn)一步提高了用戶的使用體驗,讓人們可以更加方便的充電樁的服務(wù)。
鐵塔充電平臺商業(yè)價值,鐵塔充電的模式是什么?
隨著中國新能源汽車保有量逐漸增長和電動技術(shù)的發(fā)展,共享充電樁被納入了“新基建”,國家政策扶持方向重點轉(zhuǎn)向充電樁建設(shè),在政策扶持下我國公共樁數(shù)量開始穩(wěn)定增長。鐵塔充電就抓住了這個機(jī)遇,成為共享充電樁這一行業(yè)的領(lǐng)頭羊。如果您現(xiàn)在想進(jìn)入這個行業(yè),那么正是時候,競爭不大、投資成本低,可快速提高自己在當(dāng)?shù)刂悄艹潆姌妒袌龅膶嵙椭?,為后面業(yè)務(wù)拓展打下堅實的基礎(chǔ)。再過兩三年將會進(jìn)入白熱化競爭,以政府領(lǐng)導(dǎo)為主,和當(dāng)?shù)赜袑嵙Φ倪\(yùn)營商合作,導(dǎo)致競爭壓力大、利潤點降低等結(jié)果。機(jī)會不容等待,想了解更多共享充電樁商業(yè)詳情,或是想搭建開發(fā)類似鐵塔充電系統(tǒng)平臺的朋友可以找我,小編是一家軟件技術(shù)開發(fā)公司。
我司官方認(rèn)證專業(yè)技術(shù)開發(fā):鐵塔充電平臺APP、小程序、公眾號、手機(jī)H5網(wǎng)站…均可開發(fā)
懶人經(jīng)濟(jì)催生了上門美甲、美容、足浴等服務(wù)的興起。互聯(lián)網(wǎng)時代,人們變懶不愿意出門,疫情之下也擔(dān)心安全風(fēng)險,上門服務(wù)需求今后會越來越大。與此同時,對于商家來說,消費(fèi)者不愿意到店消費(fèi),房租成本居高不下,必須想辦法拓展互聯(lián)網(wǎng)銷售渠道,給用戶提供更好的服務(wù)體驗。
預(yù)約到家美睫平臺商業(yè)價值,預(yù)約到家美睫的模式是什么
上門服務(wù)在服務(wù)行業(yè)中應(yīng)該是稀缺的高價值服務(wù),供給與需求兩側(cè)都沒有便宜的道理。用戶要想獲得良好的服務(wù)體驗必須付相對高的價格,還需具備合適的服務(wù)場地,甚至某些服務(wù)還對用戶自身素質(zhì)有較高要求。服務(wù)的提供者不僅需要良好的職業(yè)技能,還需要較高的職業(yè)操守與道德素質(zhì),最好不需要太多的工具設(shè)備,全靠技藝提供服務(wù)是最好的。
可以看出,預(yù)約到家美睫是一個朝陽產(chǎn)業(yè),將會是新一輪互聯(lián)網(wǎng)創(chuàng)新商業(yè)的風(fēng)口,越早投入越早得到收獲,若是想了解更多關(guān)于創(chuàng)新商業(yè)詳情的,或是想搭建開發(fā)類似預(yù)約到家美睫美容系統(tǒng)平臺的朋友都可以聯(lián)系我,小編是一家軟件技術(shù)開發(fā)公司,歡迎來思維碰撞!
預(yù)約到家美睫系統(tǒng)APP開發(fā)如何借鑒上門模式運(yùn)作
其一、擴(kuò)大經(jīng)營范圍,現(xiàn)實中的實體店能做的生意距離范圍基本在三、五公里的封頂了,再頂天去到十公里!上門按摩模式無需門店、借力互聯(lián)網(wǎng),沒有限制區(qū)域,一個技師可以全城接單!使得更高效連接了客人和技師之間距離。相同美容院也是一樣,客人只能到店,經(jīng)營距離就擺在哪里。
其二、易復(fù)制!開一個按摩會所店投入小則幾十萬、大至幾百萬。特別不好復(fù)制,但上門按摩模式則不同了、啟動一個城市進(jìn)行打板,成功打板一個城市后,以原有的運(yùn)作方式復(fù)制到其它城市開展跑出結(jié)果,陸陸續(xù)續(xù)非??臁O嗤廊菰阂彩且粯?。復(fù)制開分店非常難,因為硬成本就擺在哪里!而上門按摩app則不同,開多一個城市端口讓技師入駐則可開展接單進(jìn)行服務(wù)工作。
其三、解決常見的痛點!它打破了傳統(tǒng)按摩會所店的困境,省去門店租金和裝修成本、省去員工薪資成本、省去經(jīng)營管理成本。相同美容院也是一樣。從選址到開業(yè),每個環(huán)節(jié)的投入成本也是層層加碼,同時也很考驗后期的經(jīng)營能力。
]]>
一·編碼的類型
在短視頻程序源碼中視頻的編碼一般分為軟編碼和硬編碼兩種方式:
1·軟編碼就是采用CPU對設(shè)備端采集到的原始視頻數(shù)據(jù)進(jìn)行編碼。
2·軟編碼就是采用設(shè)備端提供的硬編接口,如顯卡GPU,專用的DSP,FPGA,ASIC芯片等進(jìn)行編碼。
二·軟 硬編碼的優(yōu)缺點是
1·短視頻系統(tǒng)源碼開發(fā)中軟編碼實現(xiàn)比較簡單,直接,而且技術(shù)相對來說比較成熟,參數(shù)的調(diào)整,升級比較也比較方便,低碼率下質(zhì)量通常比硬編碼要好一些;但是對CPU占用較少,用戶即使在短視頻程序源碼中長時間的高清錄制也不會出現(xiàn)發(fā)燙的情況,主要原因是因為使用的是系統(tǒng)的API,所以庫相對較小;但是硬編碼會受到硬件設(shè)備支持的影響,所以考慮兼容性的問題,壓縮率一般偏低,低碼率下通常質(zhì)量不如軟編碼。
三·短視頻程序源碼采用的是編碼類型
根據(jù)以上內(nèi)容分析得知,軟編碼和硬編碼都有一定的優(yōu)缺點,具體的選擇要根據(jù)自身的需求決斷。在短視頻程序源碼中,采用的是H.264和H.265的視頻編碼格式,即硬編碼,在節(jié)省CPU性能的同時,也實現(xiàn)了高效編碼。
四·服務(wù)器的選擇
在短視頻程序源碼開發(fā)時,除了流媒體的傳輸過程外,服務(wù)器的選擇也很重要:
1·寬帶的要求對短視頻程序源碼來說非常嚴(yán)格,如果寬帶不夠就會造成用戶無法正常訪問的情況,更不可能保障視頻的流暢度和清晰度了,為了滿足短視頻程序源碼的需求盡可能選擇大的寬帶。
2?短視頻節(jié)目源占用的服務(wù)器內(nèi)存比較大,短視頻或流媒體的存儲、上傳和下載都是測試存儲空間,合適的存儲空間給用戶帶來更好的使用體驗。
3·選擇拓展性強(qiáng)的服務(wù)器,短視頻程序前期所需要的服務(wù)器硬件配置可能不需要那么多,但是隨著不斷地發(fā)展,服務(wù)器配置就需要進(jìn)行升級,將所有數(shù)據(jù)轉(zhuǎn)移至新服務(wù)器太麻煩,所以服務(wù)器是否能擴(kuò)展升級就很重要了。
為了能讓短視頻程序源碼實現(xiàn)更好的商業(yè)價值,除了技術(shù)上不斷地進(jìn)步之外,在功能方面也要集多種功能于一體,盡可能地滿足用戶的各種不同需求,像當(dāng)下正流行的“短視頻+直播+電商”模式,就是實現(xiàn)短視頻程序源碼流量變現(xiàn)最佳的途徑。
]]>
不知不覺已經(jīng)是第四次接手負(fù)責(zé)每年的大型 H5 活動,這也意味著 4 年啦啊啊啊啊,哎時間過得真是太快,也是應(yīng)該做一點總結(jié)了。
每年都會有大型的 H5 項目上線,這一些項目的邏輯在一般的情況下,它們的差別不會很大,但是每一次都會有不同的樣式、條件和玩法。如果每一次大活動都是寫死邏輯且不可復(fù)用,下一次 H5 項目過來又再寫一次其實就是很沒有必要的事情。
如果能把這一些做過的組件做成通用可配置的,即插即用。那么肯定是會極大的提高開發(fā)效率,同時項目的穩(wěn)定性也有保證。只不過組件的代碼邏輯就會比較復(fù)雜,開發(fā)難度會比較高,就單單組件內(nèi)的一個按鈕就需要考慮到這個按鈕的顏色,大小,按鈕內(nèi)的字體各種樣式和背景色以及這按鈕是不是設(shè)計狀態(tài)變化,若有還要考慮這一個狀態(tài)變化的邏輯或者是一些聯(lián)動的可能。所以,一個通用組件需要考慮和實現(xiàn)的邏輯就很多。
舉個例子,比如今年的 H5 有一個 “我的獎品” 模塊 ( 頁面 or 彈窗 ),這個模塊里面有的獎品的信息展示、時間的展示、數(shù)量的展示以及底部還有一些其他的按鈕。以下是我截取兩次不同的活動的“我的獎品”列表展示模塊。
這兩種樣式的組件,大致的框架上都是一樣的,點擊側(cè)邊欄的 “我的獎勵” 和 “我的背包”,只是展現(xiàn)形式和展示數(shù)據(jù)類型以及按鈕的點擊事件是不一樣的。
所以,如果第三次 H5 ,或者以后的 H5 都寫一遍這樣的東西意義不大。所以,這樣使用頻率比較高的模塊,就必須和業(yè)務(wù)方討論。我們可以把這樣的模塊定出一個基本的交互和原型,統(tǒng)一做成一個通用列表展示組件,這個組件必須支持通用樣式的展示,也需要支持特殊的樣式展示,例如下面的情況
最左邊的也就是正常的列表樣式,右邊的就是一些特殊的卡片和文字樣式,所以,一個組件需要考慮的東西有很多。
這里叫列表展示組件而不叫“我的獎品組件”的原因是:我們只需要通過參數(shù)控制它需要展示什么的內(nèi)容、標(biāo)題是什么、按鈕名稱是什么、點擊之后的邏輯是什么,而不是只局限于我的獎品列表,它也可以用于其他數(shù)據(jù)的展示。同時,這樣的通用組件可以適用于各種 H5 。組件拿來即用或者用于一些 H5 自動生成的平臺,只要根據(jù)文檔傳參數(shù)就可以了。
通過 config 控制具體的展示名字還有按鈕id的標(biāo)記區(qū)分事件,data 初始化組件的列表,與業(yè)務(wù)區(qū)分開來這里就變成了一個很純粹的列表展示組件,可以展示任意的數(shù)據(jù),只要按照格式傳參就行。這里只是寫一個很簡單的 DEMO ,后面會提到入?yún)⒑秃瘮?shù)綁定。
拿到設(shè)計稿之后找出通用的模塊,再根據(jù)類似模塊之間的差異定出一個通用的規(guī)則。下面是本次大型 H5 的設(shè)計稿總覽:
第一大類:分組賽,資格賽,彈窗,規(guī)則和投票等
第二大類:沖刺賽,總決賽,PK模塊等
此次大型 H5 的分為了幾個大階段,分組賽,資格賽,沖刺賽和總決賽??瓷先ナ欠浅6鄡?nèi)容的,所以需要找出相似的模塊,再和業(yè)務(wù)側(cè)溝通從這幾個賽段來看,可以抽離成組件的是
這里就拿一部分的組件描述一下實現(xiàn)思路,全部寫的話就太多了,而且有些地方邏輯實現(xiàn)上也是比較像的。
一個通用組件所需要的配置參數(shù)一般歸納為幾種,最重要的是這個組件的所有需要使用的值,也就是這個初始化參數(shù)。其次,是這個組件的一些樣式配置或者是全局參數(shù)輔助使用,還有一些情況需要特定的屬于這個組件的 key 。當(dāng)然,不是說樣式和全局參等等是不重要的參數(shù),而是根據(jù)業(yè)務(wù)的需求來定,可能樣式的參數(shù)才是重點這個也是可能的,具體的還得從業(yè)務(wù)或者這個組件本身的性質(zhì)考慮,只是在做組件的時候優(yōu)先考慮功能的實現(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ù)或者是渲染組件的所有數(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ù)據(jù)不會發(fā)生變化的數(shù)據(jù)。數(shù)據(jù)格式類型是 Object 。
<script>
// 組件
export default {
props: {
styleForm: {
type: Object,
default: () => ({
// styles: {}, example
// bg: './images/xx.png' example
}),
},
}
</script>
commonForm 這個參數(shù)是通用的樣式配置,比如,控制這個組件的寬、高以及背景色等等。這個我們在自己在獨立開發(fā)的 H5 的時候,會按照這樣的參數(shù)格式配置。目的是讓組件更加通用,適用于不同的地方,比如一些 H5 的自動生成平臺。 因為,在互聯(lián)網(wǎng)大廠里 H5 的開發(fā)如果是比較簡單的頁面,是不會單獨用人力去開發(fā)的,而是通過平臺配置生成 H5。我們需要做的就是提供各種各樣的組件,讓業(yè)務(wù)同學(xué)去配置使用。所以,平臺的配置是以每個功能模塊劃分,commonForm 可以接入他們的平臺的接口數(shù)值,直接在平臺上控制這個組件的寬、高、是否居中等等的基礎(chǔ)樣式。
<script>
// 組件
export default {
props: {
commonStyle: {
type: Object,
default: () => ({
// width: 300, example
// height: 20 example
}),
},
}
</script>
全局屬性指的是這個項目的唯一標(biāo)記,適用于項目中的任意一個地方。比如說這個項目的 id ,他可能在做上報操作或者在請求接口的時候需要帶上這個參數(shù)。那么就由 global 這個參數(shù)統(tǒng)一接收。類型也是 Object 。
<script>
// 組件
export default {
props: {
global: {
type: Object,
default: () => ({
// page_id: 111, example
}),
},
}
</script>
componentKey 是組件的標(biāo)記,主要用于在做區(qū)分組件的時候,使用比如上報數(shù)據(jù)。同時也可以用于一些非常特定的邏輯,提供臨時的解決方法。舉個非常簡單例子:業(yè)務(wù)方需要畫 10 個圓且背景都是白色,突然間提出要在第 9 個圓中某個位置加上一個黑色的點,其他不變。 這樣既不合理也不通用還砍不掉的需求,臨時的解決方法就是通過 key 寫一個 if else ,之后再說。
<script>
// 組件
export default {
props: {
componentKey: {
type: [String,Number],
default: 1, // example
},
}
</script>
在組件內(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>
首先從功能上看,這個組件只能適用于獨立開發(fā)的 H5 ,它不適合 H5 生成平臺?;蛘哒f這樣的組件在 H5 生成平臺完全沒有意義。因為,左邊的 icon 和右邊按鈕列表,他們在 H5 生成平臺里面,這些按鈕都是靠使用者自己手動配置的地方。例如: 左邊的 icon 就是使用一個按鈕組件拖拽進(jìn)去,再加上一個跳轉(zhuǎn)事件。 右邊的 btn-list 可以看成是 3 個獨立按鈕,也和上面一樣用一個按鈕組件拖拽進(jìn)去,加上一個跳轉(zhuǎn)事件,再連續(xù)配置 3 次。
但是,這一次是獨立開發(fā),所以只能按照可復(fù)用定制模版的思路來實現(xiàn)。需要考慮的地方是:
如圖:對應(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)配置。這有點像是數(shù)據(jù)庫里面的主鍵,可以根據(jù)這個主鍵可以查詢或者關(guān)聯(lián)查找其他的數(shù)據(jù)表。
寫一個通用的方法,在后面如果有新增的按鈕,可以直接通過傳參 (第幾個按鈕) 控制按鈕的位置。
@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));
錨點跳轉(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);
}
},
倒計時組件在邏輯上是比較簡單的,更多需要考慮倒計時的展示樣式,因為在 H5 里面,每種設(shè)計的風(fēng)格或者業(yè)務(wù)需求不一樣,不可能一直沿用一種樣式的倒計時,比如這樣
所以需要考慮的點是:
在計算倒計時的方法上有兩種,第一種是獲取本地手機(jī)時間再寫一個 inteval 函數(shù)遞減計算,第二種是使用 interval 每秒都向服務(wù)器進(jìn)行時間獲取計算出剩余時間。 這里我一般會選擇后面那種,因為,首先本地時間不一定是正確的,也有可能是人為的去修改了系統(tǒng)的時間,其次,本地的 interval 延遲時間不一定準(zhǔn)確。比如我們設(shè)定 1000 毫秒執(zhí)行,但是由于部分手機(jī)本身的原因,這里可能存在著誤差,設(shè)定的是 1000 毫秒,而在實際的執(zhí)行中,它相當(dāng)于 800 毫秒。那么就會導(dǎo)致一個問題,本地的時間越算,誤差越大,如果在頁面中的時間停留較短那問題不大,但是如果在頁面的停留時間很長,到了最后看上就是一個大大的 BUG 。所以,每次都讀取服務(wù)器時間是比較靠譜的。
實現(xià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é)點樣式方面:讓 countdown-content 的內(nèi)容居中,倒計時前后可以配置任意文案,再給 clase="time" 加上一個寬度,這樣的好處是避免了在數(shù)字變化的時,因倒計時數(shù)字切換發(fā)生的抖動而影響到了整個倒計時文案的抖動問題。另一個是,在倒計時外層再包一層 v-if 樣式,這個是來拓展倒計時多種樣式的功能。
邏輯方面:傳入一個時間格式的配置項,比如是否需要展示天數(shù)或者秒數(shù),使用一個循環(huán)指定數(shù)據(jù)更新。最后的時間由 computed 計算屬性將 day, hours minutes , seconds 計算出來。同時,倒計時為零的時候支持配置一個方法,例如,最常見的操作就是刷新當(dāng)前頁面或者是執(zhí)行跳轉(zhuǎn)。
進(jìn)度條組件和倒計時組件一樣,屬于邏輯比較簡單而比較注重樣式上的一些配置。進(jì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é)點的的樣式和文案全部通過數(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)'
}
};
吸底部組件和頂部組件一樣,它不適用于 H5 自動生成平臺。吸底組件和頂部組件它們更像是一個容器,在這個容器里面配置其他的組件,所以這里還是做成一個可復(fù)用的定制模版。需要考慮的一些點:
他們的數(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ù)實際的需求來說沒有必要,所以這里就直接固定下來。
這個 H5 的投票功能相對簡單,只有一個增加/減少和最大值。
在做這個組件之前,我其實更想把它做成這樣的形式。如圖:
它可展示圖片,還可以展示選擇票的類型,同時下面還可以配置拓展按鈕也可以綁定執(zhí)行事件,看上去非常的好。但是后來想了一下,還是覺得這樣投票組件的邏輯會有點冗余,既然是一個投票組件應(yīng)該不就有其他的東西。
所以我也在原來的基礎(chǔ)上結(jié)合這個組件多加了一投票的類型選擇。就是這樣:
這樣看上去邏輯簡單,而且也確實多了是一個實用的功能。所以,這個組件需要考慮的點是:
<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ù)字上的校驗和統(tǒng)一管理檢驗失敗的提示文案。
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;
};
// 檢驗通過
return true;
}
},
validCount(1000);
排行組件是這一個活動邏輯最復(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', } }, .... ]};這一段是部分配置
以后無論是需要怎么樣的一個排行榜,先查找文檔看看是不是都有這樣類型的樣式,沒有的話拓展,有的話只需要傳入配置參數(shù)之后,再傳入具體的數(shù)據(jù)就可以跑起一個排行榜的組件。
從功能上看他需要支持:
標(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>
使用配置項循環(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)容都通過小組件形式引入。
]]>