言
萬萬沒想到我昨天發(fā)布的用Python畫中國地圖,實現(xiàn)各省份數(shù)據(jù)可視化這篇文章獲得了很多朋友的喜歡,目前已獲得了66次轉(zhuǎn)發(fā),314次收藏,也讓我漲了60個左右粉絲。
小嘚瑟
雖然這點成績跟很多大V不能比,但我已經(jīng)很知足,與此同時也感受到了責任所在,生怕文章內(nèi)容有誤,耽誤大家,所以我今天反反復復看昨天的文章,讓我欣慰的是的確沒有什么錯誤,但是我個人覺得還是有些點沒講到位,仍有不少可以細說的地方。所以今天再舉一個用Python畫江蘇省地圖并實現(xiàn)各地級市數(shù)據(jù)可視化的例子。
第一步:安裝pyecharts
在上篇文章中,我告訴大家我所安裝的pyecharts是0.1.9.4版本,但是并沒有說為什么,估計很多人也沒有當回事,其實這版本號是有講究的,因為pyecharts在0.3.2版本后,為了縮減項目本身的體積以及維持 pyecharts 項目的輕量化運行,pyecharts 將不再自帶地圖 js 文件。也就是說如果你安裝的pyecharts是0.3.2之后的版本,那么就要根據(jù)你想畫的地圖類型安裝相應的模塊。
pip install echarts-countries-pypkg # 世界地圖和 213 個國家,包括中國地圖
pip install echarts-china-provinces-pypkg # 23 個省,5 個自治區(qū)
pip install echarts-china-cities-pypkg # 370 個中國城市
pip install echarts-china-counties-pypkg # 2882 個中國縣·區(qū)
pip install echarts-china-misc-pypkg # 11 個中國區(qū)域地圖,比如華南、華北
此外,不同版本的pyecharts,在代碼上的使用也稍有區(qū)別,如果你使用的版本和我不一樣,那么直接按我代碼操作的話,大概率是會報錯的。
第二步:讀取數(shù)據(jù)
與上篇文章一樣,我的數(shù)據(jù)放在Excel的表格中,內(nèi)容是去年(2019年)江蘇各地級市的平均房價
HousePrice.xlsx文件
使用xlrd(沒有就通過pip install xlrd安裝)讀取Excel表格中的數(shù)據(jù)
from pyecharts import Map
import xlrd
# 第一種方式,使用xlrd讀取Execel表格中數(shù)據(jù)
data=xlrd.open_workbook('HousePrice.xlsx')
table=data.sheet_by_name('Sheet1')
city=table.col_values(0)[1:]
num=table.col_values(1)[1:]
如果沒有相應的Excel文件,并且嫌麻煩不想新建一個的話呢,也可以直接定義一個字典,其中鍵是城市名,值是對應的房價,然后再把相應的數(shù)據(jù)取出來
# 第二種方式,直接自己寫一個字典,然后取出相應數(shù)據(jù)
HousePrice_data={'南京市': 18633.0, '無錫市': 14052.0, '徐州市': 7855.0, '常州市': 16669.0,
'蘇州市': 21350.0, '南通市': 12326.0, '連云港市': 8463.0, '淮安市': 7038.0,
'鹽城市': 8455.0, '揚州市': 13418.0, '鎮(zhèn)江市': 10367.0, '泰州市': 9147.0, '宿遷市': 7979.0}
city=list(HousePrice_data.keys())
num=list(HousePrice_data.values())
這里需要注意的一點是,每個城市名后面要加上"市"這個字,因為源代碼默認規(guī)定要有“市”,必須與其對應。(不同于上篇文章,上篇文章中所讀取的各省份、直轄市、自治區(qū)名稱中,并沒有添加“省”、“市區(qū)”、“自治區(qū)”這些后綴)
第三步:畫圖
JiangSuMap=Map(width=1200, height=600)
JiangSuMap.add(name="房價信息",
attr=city,
value=num,
visual_range=[7038, 21350],
maptype='江蘇',
is_visualmap=True,
visual_text_color='#000')
JiangSuMap.render(path="江蘇地圖.html")
這里需要注意的是,maptype=‘江蘇’,不需要加"省"字。另外,我新增了一個參數(shù)visual_text_color,該參數(shù)是用來顯示數(shù)字刻度的,細心的朋友會發(fā)現(xiàn)上篇文章中所生成的地圖左下角并沒有數(shù)字刻度。
在運行上面的代碼后,會生成一個“江蘇地圖.html”的文件,打開后如圖所示:
無各地級市名稱
如果想保存為圖片,可以點擊地圖右側(cè)的下載按鈕,因為隔著比較遠,我在錄屏的時候并沒有把下載按鈕錄進來,但大家在自己電腦上肯定會看見的。
第四步:額外操作
第一點:大家可以看到上圖中各城市名稱只有在被鼠標選中的情況下,才能顯示,并且所保存的圖片也不會顯示各城市份名稱,如果想顯示各城市名稱,就要修改html文件,推薦使用notepad++(一個文本編輯軟件,直接去百度上下載,很簡單的)打開“江蘇地圖.html”文件,然后在第1923行的那個series中添加"label":{ "normal":{ "show":true}},并保存,如下:
修改html文件
然后再打開江蘇地圖.html,就會顯示各地級市名稱了,如下圖:
有各地級市名稱
第二點:大家可以看到地圖的默認色系是從冷色系過渡到暖色系,也就是從藍到黃再到紅,如果想更改地圖顯示的顏色,可以添加visual_range_color這個參數(shù),該參數(shù)接受一個列表,列表里存放的是顏色過渡信息。比如我存放了三個土黃色系的顏色:#FDAA78、#BB6C31、 #A84104。
JiangSuMap=Map(width=1200, height=600)
JiangSuMap.add(name="房價信息",
attr=city,
value=num,
visual_range=[7038, 21350],
maptype='江蘇',
is_visualmap=True,
visual_text_color='#000',
visual_range_color=['#FDAA78', '#BB6C31', '#A84104'])
JiangSuMap.render(path="江蘇地圖.html")
上面的代碼和第三步中的代碼區(qū)別就是添加了一個visual_range_color參數(shù),對應的效果如下:
土黃色系地圖
關注微信公眾號“Python小鎮(zhèn)”,發(fā)現(xiàn)更多干貨知識!
于企業(yè)多地點業(yè)務而言,SEO 策略與業(yè)務策略的協(xié)調(diào)對于成功至關重要。
無論企業(yè)是經(jīng)營特許經(jīng)營模式、零售連鎖店,還是以服務區(qū)業(yè)務的形式運營多個中心,您的本地 SEO方法都需要量身定制,以滿足您的特定目標。它還需要具有足夠的可擴展性和效率,以便在獲得長期投資回報的同時進行維護。
另一個關鍵要求是,您的內(nèi)容方法要為用戶和 Google 創(chuàng)造足夠的價值,以使其高于索引質(zhì)量閾值。
這意味著超越本地 SEO 的標準最佳實踐 ,并創(chuàng)建可持續(xù)提高品牌知名度和轉(zhuǎn)化率的本地 SEO 活動。
多地點經(jīng)營的企業(yè)有不同的目標。
雖然多地點管理的基礎相同,但您的方法需要與整體戰(zhàn)略相結(jié)合并與整體業(yè)務目標保持一致。
例如,在多個城鎮(zhèn)、城市和州經(jīng)營服務業(yè)務的多家運營商的戰(zhàn)略特許經(jīng)營業(yè)務與在多個州擁有數(shù)百家分店的大型倉儲式商店有所不同。
成功指標也各不相同。通常,企業(yè)本地 SEO 活動的 KPI 屬于以下類別之一:
企業(yè)對“成功”的定義將極大地影響您為用戶創(chuàng)建選擇架構的方法以及報告成功的方式。
多年來,我們描述和制作多區(qū)域服務頁面的方法發(fā)生了變化。
十年前,我們會將質(zhì)量低下的版本(只有細微修改且內(nèi)容基本相同)稱為門頁,而谷歌隨著時間的推移逐漸降低了門頁的價值。
近年來,隨著程序化 SEO(pSEO)的日益普及,這種方法已經(jīng)成為大規(guī)模創(chuàng)建這些頁面的流行方法。
對于運營數(shù)百或數(shù)千個門店的企業(yè)來說,程序化或部分程序化內(nèi)容創(chuàng)建可能是一個有吸引力的選擇。
程序化 SEO(簡稱 pSEO)可讓您大規(guī)模生成大量內(nèi)容。這種方法已幫助許多企業(yè)擴大規(guī)模,但如果所創(chuàng)建的頁面無法提供足夠獨特的價值主張,讓 Google 不愿投入資源,那么這種方法也會帶來問題。
如果我們看一下本地服務頁面的兩個常見網(wǎng)站架構,我們通常有一個中央服務頁面,然后是本地服務頁面,或者有一個充當區(qū)域設置服務頁面網(wǎng)關的中央頁面 - 例如商店定位器。
圖片來自作者,2024 年 7 月
根據(jù)您的業(yè)務類型,您可能會默認選擇一種結(jié)構,但兩者都可能帶來挑戰(zhàn)。
使用中央服務頁面結(jié)構,您可能會遇到創(chuàng)建獨特價值主張的問題,并確保每個頁面都具有足夠的差異化并高于 Google 索引的質(zhì)量閾值。
商店定位器頁面方法可能會導致 PageRank 分布以及內(nèi)部鏈接到不同位置的方式出現(xiàn)問題。大多數(shù)用戶友好的商店位置應用程序不會加載 HTML 鏈接,因此雖然可以直觀地鏈接到所有商店,但 Google 無法抓取這些鏈接。
然而,這兩種方法的共同問題是如何捕獲位置周圍“更廣泛”的搜索。
當本地頁面最適合位置時,它們會發(fā)揮最大的幫助。
從歷史上看,我看到一些公司通過在頁面上“夸大”該地區(qū)的額外信息來做到這一點,比如一兩段關于當?shù)鼗A設施、學校和運動隊的段落——如果你想讓人們訪問你的五金店或詢問你的上門安全裝配服務,這些信息都與你無關。
僅僅更改 URL、H1、標題標簽和整個正文中的位置名稱也是不夠的。
當這種情況發(fā)生時,谷歌實際上會看到近似重復的頁面,這些頁面在與用戶查詢相關的價值主張上幾乎沒有區(qū)別。
這種情況的癥狀是,當頁面在 Search Console 中顯示為未編入索引時,Google 要么選擇覆蓋用戶聲明的規(guī)范,要么停留在“已發(fā)現(xiàn)”或“已抓取”的階段,而當前尚未編入索引。
本地服務和位置頁面之間總會存在一定程度的重復。Google 對此并不介意。某些內(nèi)容在多個頁面上重復并不意味著其質(zhì)量低下。
這是我傾向于采用部分程序化方法的地方。
程序化可以滿足 70% (+) 的頁面內(nèi)容;它可以涵蓋您針對特定位置的服務產(chǎn)品、定價和公司信息。
該頁面的剩余百分比是手動的,但允許您創(chuàng)建與其他頁面的價值主張差異化。
假設您是一家跨州快遞服務公司,擁有多條市場路線,您在德克薩斯州的主要配送中心位于奧斯汀、圣安東尼奧和達拉斯,而您想要瞄準尤利斯的潛在客戶。
您為尤利斯提供的服務與您為普弗拉格維爾、凱爾和利安德的客戶提供的服務相同 - 因此每個位置頁面的這些部分在所有位置上都是相同的。
但是尤利斯由達拉斯樞紐提供服務,而其他機場則由奧斯汀樞紐提供服務——這是您要強調(diào)的第一個內(nèi)容差異點。
然后,您可以使用來自企業(yè)內(nèi)部的數(shù)據(jù)和關鍵字研究,用旅行時間數(shù)據(jù)充實這些頁面。
在尤利斯尋找快遞服務的客戶可能正在尋找從尤利斯到奧斯汀或從尤利斯到休斯頓的服務——因此,將此構建到本地頁面并提供從目的地到熱門地點的時間估算,可以顯示出本地的專業(yè)性并幫助客戶更好地了解服務和計劃。
您的業(yè)?務數(shù)據(jù)還將幫助您識別客戶類型。例如,在尤利斯預訂的許多工作可能針對的是搬出校園居住的大學生,因此這又是針對可以包含在頁面上的客戶群的更具本地化的定位。
當涉及到內(nèi)部鏈接時,使用偽 HTML 站點地圖可以幫助實現(xiàn)這一點,它不僅可以充當通過頁面的干凈內(nèi)部鏈接,而且還對用戶有益,并允許您創(chuàng)建其他登錄頁面來定位縣或地區(qū)級搜索。
十年前,在一個房產(chǎn)查找頁面上,我所在的團隊構建了“縣 > 鎮(zhèn)/市”的頁面結(jié)構模式,同時將相關位置拉入登錄頁面。
作者截圖,2024 年 7 月
從視覺上看,這只是一種更“手動”的方法,讓用戶可以從非特定位置的頁面篩選到他們所在的當?shù)貐^(qū)域。
另一個經(jīng)常被忽視的關鍵組件是將 Google 商業(yè)資料(GBP) 直接鏈接到網(wǎng)站上的相關位置頁面。
我遇到過許多跨國公司和國內(nèi)公司,他們鏈接回自己的公司主頁,有時還帶有一個參數(shù)來突出顯示用戶點擊的是哪個 GBP——但這既是糟糕的網(wǎng)絡架構,也是糟糕的用戶選擇架構。
如果用戶正在尋找 XYZ 中的服務/商店,他們不希望在點擊網(wǎng)站鏈接時看到主頁或通用信息頁面。
就用戶選擇架構而言,從這里,用戶可以導航到不同的商店或頁面,并錯過與他們相關的關鍵信息,否則這些信息可能會推動銷售或詢問。
除了 Google 的核心算法和更通用的搜索排名信號外,Google 還發(fā)布了專門針對本地查詢的更新。主要有兩個:
這些更新使企業(yè)更難以欺騙自己在當?shù)厥袌龅拇嬖冢⑶铱赡軣o法提供符合或滿足搜索者需求的價值主張。
據(jù)傳,谷歌似乎優(yōu)先對提供最全面信息的企業(yè)進行排名。
這包括開業(yè)日期、現(xiàn)場餐飲選擇(如果適用)、特殊營業(yè)時間、業(yè)務類別、服務列表以及定義服務區(qū)域和服務類型。
遵循指南是必須的,但即便如此,你仍可能會違反 Google 的自動檢測檢查。
與一家在亞洲擁有多個辦事處的國際軟件公司合作,在共享辦公室中租用了許多樓層。
我們假設,Google 偶爾會檢測到共享地址并誤認為它們是虛擬辦公室/虛假地址,而Possum 算法更新旨在減少這種情況。
當您與擁有大量實際位置的企業(yè)組織合作時,通過內(nèi)部利益相關者管理以及了解 GBP 如何適應并貢獻于總體目標和生態(tài)系統(tǒng),Google 商家資料管理方法可能會變得更加復雜。
根據(jù)您的目標,報告成功的方式將因活動而異。
通過 Google API,您可以訪問展示次數(shù)的列表級數(shù)據(jù),以及不同用戶互動的細分(從 GSC 鏡像指標推斷展示次數(shù)和點擊次數(shù))。
非典型的 Google Business Profile 報告儀表板。(作者截圖,2024 年 7 月)
在我看來,任何在多個城鎮(zhèn)、城市、縣或州運營的企業(yè)都需要擁有某種形式的 GBP 監(jiān)控和報告可見性,而不僅僅是在 Google Search Console 和其他分析平臺中跟蹤參數(shù)化 URL(假設您在 GBP 網(wǎng)站鏈接上使用參數(shù))。
首先明確這是我們即將需要開發(fā)的城市選擇頁面:
在gitee的分支欄點擊新建分支city-router,然后記得將本地master分支切換到city-router分支。如何切換呢?步驟如下:第一步:使用git pull將創(chuàng)建的city-router分支拉到本地;第二步:執(zhí)行git checkout city-router切換到city-router分支;第三步:使用git status查看一下當前的分支狀態(tài):(出現(xiàn)這個說明分支切換成功)
$ git status
On branch city-router
Your branch is up to date with 'origin/city-router'.
nothing to commit, working tree clean
接下來開始城市選擇頁面路由的配置。打開src/router/index.js文件,往其中添加新的url路徑:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/home/Home'
import City from '@/pages/city/City'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/city',
name: 'City',
component: City
}
]
})
接著去pages下面新建city文件夾,然后在city文件夾中新建一個City.vue文件,里面的代碼如下:
<template>
<div>city</div>
</template>
<script>
export default {
name: 'City'
}
</script>
<style lang="stylus" scoped>
</style>
我們是希望點擊右上角的北京也就是城市區(qū)域,可以跳轉(zhuǎn)至城市列表頁:
那么需要在Header.vue中進行跳轉(zhuǎn)鏈接的配置,而前面說過鏈接跳轉(zhuǎn)使用<router-link>標簽結(jié)合to屬性,則跳轉(zhuǎn)鏈接區(qū)域代碼修改為:
<router-link to="/city">
<div class="header-right">
{{ city }}
<span class="iconfont iconjiantouarrow486 arrow-icon"></span>
</div>
</router-link>
to屬性中的/city就是我們前面在router/index.js中配置的url鏈接。但是此時頁面跳轉(zhuǎn)區(qū)域會變?yōu)楹谏?/p>
那是因為<router-link>會默認給元素添加一個顏色:color: #25a4bb;,此時你可以給這個.header-right屬性增加color: #fff;使之變成白色就可以解決這個問題了,經(jīng)過測試發(fā)現(xiàn)頁面跳轉(zhuǎn)測試通過。
由于去哪網(wǎng)城市選擇頁面包含境內(nèi)和境外且兩者除了內(nèi)容不同外,其余所有信息均相同,因此本篇筆記只介紹境內(nèi)城市頁面的開發(fā)。
在city文件夾中新建一個components文件,用于存放組件,對于city文件來說City.vue是整個city頁面最外層的一個容器組件,里面肯定會嵌套其他的組件,因此把其他小組件都放在components文件中,然后在City.vue中進行引用即可,City.vue中的代碼如下:
<template>
<city-header></city-header>
</template>
<script>
import CityHeader from './components/Header'
export default {
name: 'City',
components: {
CityHeader
}
}
</script>
<style lang="stylus" scoped>
</style>
接著在src/pages/home/compontents文件夾中新建Header.vue文件里面的代碼如下:
<template>
<div class="header">
城市選擇
<router-link to="/">
<div class="iconfont iconfanhui header-icon"></div>
</router-link>
</div>
</template>
<script>
export default {
name: 'CityHeader'
}
</script>
<style lang="stylus" scoped>
@import "~styles/varibles.styl"
.header
position: relative
overflow: hidden
height: $headerHeight
line-height: $headerHeight
text-align: center
color: #fff
background: $bgColor
font-size: .32rem
.header-icon
position: absolute
top: 0
left: 0
width: .64rem
text-align: center
font-size: .4rem
color: #fff
</style>
注意一下以下代碼片段:
<router-link to="/">
<div class="iconfont iconfanhui header-icon"></div>
</router-link>
其實就是點擊左邊的箭頭頁面跳轉(zhuǎn)至首頁:
注意到height: $headerHeight,這是因為對于行高和高度而言,我們發(fā)現(xiàn)多處地方都是.86rem,因此考慮將其提出單獨成為一個變量,因此你可以在tyles/varibles.styl文件中新增:$headerHeight=.86rem即可。
注意考慮到效率的問題,現(xiàn)在可能是直接把完成后的整個代碼粘貼出來,后期會根據(jù)情況進行細化介紹。
最后就是將我們的代碼上傳到city-router分支,并且將其與master分支進行合并,相應的步驟如下:
git status
git add .
git commit -m 'city router'
git push
git checkout master
git merge city-router
git push
如此關于城市選擇頁路由配置就到此為止,后續(xù)是搜索框的布局。
在gitee的分支欄點擊新建分支city-search,然后記得將本地master分支切換到city-search分支。如何切換呢?步驟如下:第一步:使用git pull將創(chuàng)建的city-search分支拉到本地;第二步:執(zhí)行git checkout city-search切換到city-search分支;第三步:使用git status查看一下當前的分支狀態(tài):(出現(xiàn)這個說明分支切換成功)
$ git status
On branch city-search
Your branch is up to date with 'origin/city-search'.
nothing to commit, working tree clean
接下來開始搜索框頁面的配置。在city/components文件夾下面新建Search.vue,里面的初始代碼為:
<template>
<div>Search</div>
</template>4
<script>
export default {
name: 'CitySearch'
}
</script>
<style lang="stylus" scoped>
</style>
接著去City.vue中引入這個組件:
<template>
<div>
...
<city-search></city-search>
</div>
</template>
<script>
...
import CitySearch from './components/Search'
export default {
name: 'City',
components: {
...
CitySearch
}
}
</script>
<style lang="stylus" scoped>
</style>
接下來回到Search.vue文件開始修改樣式:
<template>
<div class="search">
<input class="search-input" type="text" placeholder="輸入城市名稱或者拼音"/>
</div>
</template>
<script>
export default {
name: 'CitySearch'
}
</script>
<style lang="stylus" scoped>
@import "~styles/varibles.styl"
.search
height: .72rem
padding: 0 .1rem
background: $bgColor
.search-input
box-sizing: border-box
width: 100%
height: .62rem
line-height: .62rem
padding: 0 .1rem
text-align: center
border-radius: 0.06rem
color: #666
</style>
之后的效果如圖:
關于box-sizing請點擊,或者去W3c上面查閱相關資料。
最后就是將我們的代碼上傳到city-search分支,并且將其與master分支進行合并,相應的步驟如下:
git status
git add .
git commit -m 'add search to city'
git push
git checkout master
git merge city-search
git push
如此關于城市搜索框的介紹完畢,后續(xù)是城市列表布局的開發(fā)。
在gitee的分支欄點擊新建分支city-list,然后記得將本地master分支切換到city-list分支。在city/components文件夾下面新建List.vue,并在City.vue文件中進行引用。List.vue中的代碼如下:
<template>
<div class="list">
<div class="area">
<div class="title border-topbottom">當前城市</div>
<div class="button-list">
<div class="button-wrapper">
<div class="button">北京</div>
</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">熱門城市</div>
<div class="button-list">
<div class="button-wrapper">
<div class="button">北京</div>
</div>
<div class="button-wrapper">
<div class="button">上海</div>
</div>
<div class="button-wrapper">
<div class="button">廣州</div>
</div>
<div class="button-wrapper">
<div class="button">深圳</div>
</div>
<div class="button-wrapper">
<div class="button">重慶</div>
</div>
<div class="button-wrapper">
<div class="button">天津</div>
</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉善盟</div>
<div class="item border-bottom">阿勒泰</div>
<div class="item border-bottom">安慶</div>
<div class="item border-bottom">安順</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉善盟</div>
<div class="item border-bottom">阿勒泰</div>
<div class="item border-bottom">安慶</div>
<div class="item border-bottom">安順</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉善盟</div>
<div class="item border-bottom">阿勒泰</div>
<div class="item border-bottom">安慶</div>
<div class="item border-bottom">安順</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉爾</div>
<div class="item border-bottom">阿拉善盟</div>
<div class="item border-bottom">阿勒泰</div>
<div class="item border-bottom">安慶</div>
<div class="item border-bottom">安順</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CityList'
}
</script>
<style lang="stylus" scoped>
@import "~styles/varibles.styl"
/**復寫border.css中的 .border-topbottom的樣式**/
.border-topbottom
&:before
border-color: #ccc
&:after
border-color: #ccc
.border-bottom
&:before
border-color: #ccc
/**list這個類用于固定標題,也就是說讓List組件的頂部外邊距騰出固定的位置用于顯示Header和Search組件**/
.list
overflow: hidden
position: absolute
top: 1.58rem
left: 0
right: 0
bottom: 0
background: red
.title
line-height: .44rem
background: #eee
padding-left: .2rem
color: #666
font-size: .26rem
.button-list //不添加overflow: hidden那么下面的button就無法撐起這個高度
overflow: hidden
padding: .1rem .6rem .1rem .1rem //右邊留出30px像素空間用于字母表顯示
.button-wrapper
float: left
width: 33.33%
.button
margin: .1rem
padding: .1rem 0
text-align: center
border: .02rem solid #ccc
border-radius: .06rem
.item-list
line-height: .76rem
color: #666
padding: .2rem
</style>
這里面有幾個注意點:第一個就是下面的代碼:
.border-topbottom
&:before
border-color: #ccc
它用于復寫border.css中的.border-topbottom的樣式,其中的&:before是Css中的before選擇器,:before選擇器在被選元素的內(nèi)容前面插入內(nèi)容,請使用 content 屬性來指定要插入的內(nèi)容。舉個例子,如在每個<p>元素的內(nèi)容之前插入新內(nèi)容:
p:before
{
content:"hello,vuejs!:";
}
其次就是list這個類用于固定標題,也就是說讓List組件的頂部外邊距騰出固定的位置用于顯示Header和Search組件。仔細看現(xiàn)在的樣子:
現(xiàn)在我們已經(jīng)把Header和Search組件所占用的空間給讓出來了,但是有一個問題就是紅色區(qū)域是list類所能顯示的范圍,也就是說紅色區(qū)域后面的都是顯示不了的:
有人可能會問怎么顯示不了,因為紅色區(qū)域就是<div class="list">所占用的區(qū)域背景:
.list
position: absolute
top: 1.58rem
left: 0
right: 0
bottom: 0
background: red
這樣是不行的,我們需要滑動右側(cè)的滾輪使城市列表詳細顯示出來,這就需要使用到后面介紹的BetterScroll了。
在前面為了保證button撐起可以顯示Header和Search組件的高度,我們給.list類添加了以下兩行代碼:
.list
overflow: hidden
position: absolute
這樣就會使得頁面無法滾動,想要實現(xiàn)可以滾動的效果可以借助于第三方插件better-scroll,先使用以下命令進行安裝better-scroll:npm install better-scroll --save,然后閱讀文檔發(fā)現(xiàn)DOM結(jié)構應當類似如下結(jié)構:
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- you can put some other DOMs here, it won't affect the scrolling
</div>
也就是說我們是幾個area都放在一個list類中,這是不行的,需要在最外層再添加一個div,將所有的area放在一個div中。閱讀英文文檔(中文文檔點這里):
因為上面的li就是我們在代碼中定義的area,因此需要包裹兩層結(jié)構:
繼續(xù)閱讀文檔:
文檔的意思是說使用better-scroll其實就是創(chuàng)建Bscroll對象,而這個對象需要傳入一個DOM節(jié)點作為參數(shù)。還記得以前講過當你需要直接操作某個DOM節(jié)點的時候,Vue提供了ref屬性,然后你只需要使用$refs來獲取DOM節(jié)點。
因此第一步獲取到wrapper類節(jié)點DOM:
<div class="list" ref="wrapper">
第二步導入Bscroll類及創(chuàng)建該對象:
<script>
import BScroll from 'better-scroll'
export default {
name: 'CityList',
mounted () {
this.scroll=new BScroll(this.$refs.wrapper)
}
}
</script>
只需這兩步就完成了頁面滾動的效果:
之前顯示不了的白色區(qū)域也全變成了紅色區(qū)域,現(xiàn)在去掉.list中的background屬性。
現(xiàn)在有一個小的細節(jié)就是“當前城市”的高度有點低,可以將.title的line-height屬性由.44rem調(diào)整為.54rem。
這樣城市列表頁的滾動效果就完成了,最后就是將我們的代碼上傳到city-list分支,并且將其與master分支進行合并,相應的步驟如下:
git status
git add .
git commit -m 'add city scroll'
git push
git checkout master
git merge city-list
git push
關于better-scroll,可以查看作者的這篇文章:當 better-scroll 遇見 Vue。
右側(cè)的城市字母表就是我們即將需要實現(xiàn)的功能:
在gitee的分支欄點擊新建分支city-alphabet,然后記得將本地master分支切換到city-alphabet分支。在city/components文件夾下面新建Alphabet.vue,并在City.vue文件中進行引用。Alphabet.vue中的代碼如下:
<template>
<ul class="list">
<li class="item">A</li>
<li class="item">B</li>
<li class="item">C</li>
<li class="item">D</li>
<li class="item">E</li>
<li class="item">F</li>
<li class="item">G</li>
<li class="item">H</li>
</ul>
</template>
<script>
export default {
name: 'CityAlphabet'
}
</script>
<style lang="stylus" scoped>
@import "~styles/varibles.styl"
.list
display: flex
flex-direction: column
justify-content: center
/** 以上三行代碼是讓字母表豎直居中 **/
position: absolute
top: 1.58rem
right: 0
bottom: 0
width: .4rem
/*background: red*/
.item
/** 以下三行代碼是讓字母表水平居中和顯示正常 **/
line-height: .4rem
text-align: center
color: $bgColor
</style>
注意幾點:1、以下三行代碼是讓字母表豎直方向上居中:
display: flex
flex-direction: column
justify-content: center
display:flex是一種布局方式,它既可以應用于容器中,也可以應用于行內(nèi)元素。Flex是Flexible Box的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。設為Flex布局以后,子元素的float、clear和vertical-align屬性將失效。了解更多可以點擊這里Css display:flex屬性。
flex-direction:表示彈性盒子中的元素的排列順序。可以按行、列、按行反向排序、或者按列反向排序等。此處我們的字母表是按列排序,不過使用這個參數(shù)的前提是需要有display: flex(即將其設置為彈性盒子) 否則無法實現(xiàn)預期效果,了解更多可以點擊這里CSS flex-direction屬性。
justify-content:用于設置或檢索彈性盒子元素在主軸(橫軸)方向上的對齊方式。 如果使用align-content屬性對齊交叉軸上的各項(垂直)。其實就是元素的水平對齊方式是左對齊、右對齊、居中對齊、兩端對齊還是環(huán)繞對齊。此處的字母表是水平居中對齊各個元素,因此應當設為center,了解更多可以點擊這里CSS justify-content 屬性。
這樣關于字母表的布局就介紹完了,后續(xù)是介紹如何將數(shù)據(jù)動態(tài)渲染到頁面上。不過在此之前先把本組件的代碼上傳至gitee上,即將代碼上傳到city-alphabet分支,并且將其與master分支進行合并,相應的步驟如下:
git status
git add .
git commit -m 'city css finish'
git push
git checkout master
git merge city-alphabet
git push
在gitee的分支欄點擊新建分支city-ajax,然后記得將本地master分支切換到city-ajax分支。這里的城市列表信息獲取其實和前面首頁信息獲取非常相似。
我們在City.vue文件中引入axios且在html頁面加載完全后使用生命周期函數(shù) mounted加載Ajax數(shù)據(jù)。mounted生命周期函數(shù)是在模板渲染成html后調(diào)用,通常是初始化頁面完成后,再對html的dom節(jié)點進行一些需要的操作:
<template>
<div>
<city-header></city-header>
<city-search></city-search>
<city-list></city-list>
<city-alphabet></city-alphabet>
</div>
</template>
<script>
import axios from 'axios'
import CityHeader from './components/Header'
import CitySearch from './components/Search'
import CityList from './components/List'
import CityAlphabet from './components/Alphabet'
export default {
name: 'City',
components: {
CityHeader,
CitySearch,
CityList,
CityAlphabet
},
methods: {
getCityInfo () {
axios.get('api/city.json')
.then(this.getCityInfoResource)
},
getCityInfoResource (res) {
console.log(res)
}
},
mounted () {
this.getCityInfo()
}
}
</script>
<style lang="stylus" scoped>
@import "~styles/varibles.styl"
</style>
運行結(jié)果為:
這里為了將ajax獲取到的數(shù)據(jù)進行展示,我們使用了父子組件正向傳值的方式。所有待展示的數(shù)據(jù)已經(jīng)準備好了,在static/envy/city.json文件中,里面包括:hotCities、cities。數(shù)據(jù)展示操作步驟如下,第一步打開City.vue文件(前三部均在該文件內(nèi)操作),新增數(shù)據(jù)返回對象data:
data () {
return {
cities: {},
hotCities: []
}
},
第二步修改getCityInfoResource函數(shù)代碼:
getCityInfoResource (res) {
res=res.data
if (res.ret && res.data) {
const data=res.data
this.cities=data.cities
this.hotCities=data.hotCities
}
}
第三步進行數(shù)據(jù)動態(tài)綁定:
<template>
<div>
<city-header></city-header>
<city-search></city-search>
<city-list :cities="cities" :hotCities="hotCities"></city-list>
<city-alphabet :cities="cities"></city-alphabet>
</div>
</template>
第四步打開List.vue文件,修改script代碼為:
<script>
import BScroll from 'better-scroll'
export default {
name: 'CityList',
props: {
cities: Object,
hotCities: Array
},
mounted () {
this.scroll=new BScroll(this.$refs.wrapper)
}
}
</script>
且使用文本插值語法展示熱門城市:
<div class="area">
<div class="title border-topbottom">熱門城市</div>
<div class="button-list">
<div class="button-wrapper" v-for="item of hotCities" :key="item.id">
<div class="button">{{ item.name }}</div>
</div>
</div>
</div>
然后繼續(xù)使用文本插值語法展示所有城市:
<div class="area" v-for="(item, key) of cities" :key="key">
<div class="title border-topbottom">{{key}}</div>
<div class="item-list">
<div class="item border-bottom" v-for="innerItem of item" :key="innerItem.id">{{innerItem.name}}</div>
</div>
</div>
請注意這個cities是一個對象,里面包含了數(shù)組,而數(shù)組中又包含了對象:
因此需要使用雙層循環(huán),第一層遍歷獲取諸如'A':[]類的信息,遍歷數(shù)組的格式是(item,index) of array,而遍歷對象的格式是(item,key,index) of object,所以使用對應的格式進行遍歷即可。注意雙層循環(huán)的時候,如果父級的:key與子級的:key值一樣是可以的,只要父級的:key不重復,而與子級的:key重復是沒有關系的。
第五步打開Alphabet.vue組件,開始填充城市字母表的數(shù)據(jù)。先使用props來接收父組件傳遞的數(shù)據(jù):
<script>
export default {
name: 'CityAlphabet',
props: {
cities: Object
}
}
</script>
接著就是修改template中的信息了:
<template>
<ul class="list">
<li class="item" v-for="(item,key) of cities" :key="key">{{key}}</li>
</ul>
</template>
刷新一下瀏覽器,最后的城市效果如下:
最后就是將我們的代碼上傳到city-ajax分支,并且將其與master分支進行合并,相應的步驟如下:
git status
git add .
git commit -m 'city ajax'
git push
git checkout master
git merge city-ajax
git push
如此關于城市列表頁的內(nèi)容就介紹完畢,后續(xù)是如何實現(xiàn)點擊右側(cè)的字母就能跳轉(zhuǎn)至對象的首字母城市,也就是兄弟組件之間的聯(lián)動。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。