目前在做的電商項目是通過cms系統(tǒng)生成了頁面配置的json文件來前端渲染頁面,其中有一個熱區(qū)組件,通過給圖片畫區(qū)域,然后用戶點(diǎn)擊不同區(qū)域跳轉(zhuǎn)到不同的頁面去瀏覽。
1.如何實現(xiàn)熱區(qū)
當(dāng)時想到的方法是通過定位根據(jù)json里面的配置的坐標(biāo)點(diǎn)來畫盒子。然后對這個盒子加一個點(diǎn)擊事件。想到這種方式去實現(xiàn)有點(diǎn)耗時間,先排除,去找度娘。通過度娘我們發(fā)現(xiàn),html是自帶有熱區(qū)的標(biāo)簽的map和area。心情一下子就舒暢了起來,我們的宗旨是能少敲點(diǎn)代碼就盡量不多敲一個字母。
2.愉快的實現(xiàn)我們的熱區(qū)組件
- 通過查詢了解到一個熱區(qū)map會生成一系列的area,這個area就是每一塊的小熱區(qū)塊。area元素有一個coords屬性,這個屬性值是這個方形的坐標(biāo)點(diǎn)。同時我們需要給area標(biāo)簽上設(shè)置shape="rect"。
<map>
<area shape="rect" coords="0,0,10,10"/>
</map>
-
coords屬性的值如何排列
coords的值是4個,分別是由,號隔開。前兩個表示起始點(diǎn)的坐標(biāo),我們在瀏覽器頁面中坐標(biāo)系的0點(diǎn)是在我們的左上角,后面兩個是結(jié)束點(diǎn)的坐標(biāo),也就是起始點(diǎn)對角的坐標(biāo)點(diǎn)。
image.png
如上圖所示,那么我們這個區(qū)域的熱區(qū)coords的值就是‘10,10,20,25’
- 接口中給我們的坐標(biāo)點(diǎn)如何轉(zhuǎn)換成我們項目中的坐標(biāo)
首先得和后端人員確定下,他們是以什么比例來畫的區(qū)塊。我們這邊后端cms系統(tǒng)中是以400的寬度生成的坐標(biāo)點(diǎn),那么前端在拿到坐標(biāo)點(diǎn)后,需要用后端的(默認(rèn)寬度400)/(屏幕的可視寬度)*(以坐標(biāo)值),那么上面的coords的值就是(屏幕可視寬度w = window.innerWidth)10 * (400/w),10 * (400/w),20 * (400/w),25 * (400/w)這個才是我們前端展示的真正的坐標(biāo)。 - 與圖片如何對應(yīng)
熱區(qū)和圖片一一對應(yīng),需要在img標(biāo)簽上設(shè)置usemap屬性和ismap,然后在map標(biāo)簽上設(shè)置相同值的name和id與之對應(yīng)
<img src='path' usemap='img1' ismap>
<map name='img1' id='img1'>
<area coords="x,x,x,x">
</map>
如上步驟,在area標(biāo)簽上加href屬性跳轉(zhuǎn)或者加click事件跳轉(zhuǎn),就能實現(xiàn)熱區(qū)效果了。
3. 封裝成vue組件
- 從上面步驟我們可以發(fā)現(xiàn),基本上map是不會變動的變動的只是area,如果有多個熱區(qū)的新增area就可以了。那么vue中我們可以通過v-for來遍歷我們熱區(qū)塊。
- 封裝通用組件
template:
<template>
<div>
<slot name="img" :usemap="usemap">
<map :name="usemap" :id="usemap">
<area :coords="coords(p)" v-for="(p, i) in item.props" :key="i">
</map>
</div>
</template>
js:
function* nextId() {
let index = 0;
while(true) {
yield index++;
}
}
let mapAreaId = nextId();
export default {
data(){
return {
index: 0
}
},
props: {
configDefaultWth: { // 后端默認(rèn)寬度
type: [Number],
default: 400
},
id: { // 熱區(qū)id
type: String,
default: 'id'
}
item: {
type: [Object],
default(){
return {
props: [
"rightBottomSpot":"401,304",
"leftTopSpot":"0,0", // 坐標(biāo)
"link":"B", // 跳轉(zhuǎn)地址
]
}
}
}
...
},
mounted () {
this.index = mapAreaId.next().value;
},
methods: {
coords(item){
return 計算的坐標(biāo)值
}
}
}
使用:
生成一個輪播圖熱區(qū)
<swipe>
<swipe-item v-for="(item, index) in componentConfig.props" :key="index" >
<mapAreaImg :item="item" :id="item.componentType">
<template slot="img" slot-scope="slotProps">
<img :src="imgPath+item.urlPath" :usemap="slotProps.usemap" ismap alt="" srcset="">
</template>
</mapAreaImg>
<swipe-item>
</swipe>
普通熱區(qū)
<mapAreaImg :item="item" :id="item.componentType">
<template slot="img" slot-scope="slotProps">
<img :src="imgPath+item.urlPath" :usemap="slotProps.usemap" ismap alt="" srcset="">
</template>
</mapAreaImg>
到此一個vue的熱區(qū)組件就封裝完了,之所以想用slot-scope而不是直接傳一個img的src到組件中去,是想著圖片可以受父組件控制。如果本文對你有所幫助,可以幫忙點(diǎn)個小愛心,如果有不對的地方望大佬們多加指點(diǎn),康桑密達(dá)!
