Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 久久免费视频网,在线精品日韩一区二区三区,国产在线观看成人

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          用Python畫江蘇省地圖,實現各地級市數據可視化

          用Python畫江蘇省地圖,實現各地級市數據可視化

          萬萬沒想到我昨天發布的用Python畫中國地圖,實現各省份數據可視化這篇文章獲得了很多朋友的喜歡,目前已獲得了66次轉發,314次收藏,也讓我漲了60個左右粉絲。

          小嘚瑟

          雖然這點成績跟很多大V不能比,但我已經很知足,與此同時也感受到了責任所在,生怕文章內容有誤,耽誤大家,所以我今天反反復復看昨天的文章,讓我欣慰的是的確沒有什么錯誤,但是我個人覺得還是有些點沒講到位,仍有不少可以細說的地方。所以今天再舉一個用Python畫江蘇省地圖并實現各地級市數據可視化的例子。

          第一步:安裝pyecharts

          在上篇文章中,我告訴大家我所安裝的pyecharts是0.1.9.4版本,但是并沒有說為什么,估計很多人也沒有當回事,其實這版本號是有講究的,因為pyecharts在0.3.2版本后,為了縮減項目本身的體積以及維持 pyecharts 項目的輕量化運行,pyecharts 將不再自帶地圖 js 文件。也就是說如果你安裝的pyecharts是0.3.2之后的版本,那么就要根據你想畫的地圖類型安裝相應的模塊。

          pip install echarts-countries-pypkg          # 世界地圖和 213 個國家,包括中國地圖
          pip install echarts-china-provinces-pypkg    # 23 個省,5 個自治區
          pip install echarts-china-cities-pypkg       # 370 個中國城市
          pip install echarts-china-counties-pypkg     # 2882 個中國縣·區
          pip install echarts-china-misc-pypkg         # 11 個中國區域地圖,比如華南、華北

          此外,不同版本的pyecharts,在代碼上的使用也稍有區別,如果你使用的版本和我不一樣,那么直接按我代碼操作的話,大概率是會報錯的。

          第二步:讀取數據

          與上篇文章一樣,我的數據放在Excel的表格中,內容是去年(2019年)江蘇各地級市的平均房價

          HousePrice.xlsx文件

          使用xlrd(沒有就通過pip install xlrd安裝)讀取Excel表格中的數據

          from pyecharts import Map
          import xlrd
          # 第一種方式,使用xlrd讀取Execel表格中數據
          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文件,并且嫌麻煩不想新建一個的話呢,也可以直接定義一個字典,其中鍵是城市名,值是對應的房價,然后再把相應的數據取出來

          # 第二種方式,直接自己寫一個字典,然后取出相應數據
          HousePrice_data={'南京市': 18633.0, '無錫市': 14052.0, '徐州市': 7855.0, '常州市': 16669.0,
                             '蘇州市': 21350.0, '南通市': 12326.0, '連云港市': 8463.0, '淮安市': 7038.0,
                             '鹽城市': 8455.0, '揚州市': 13418.0, '鎮江市': 10367.0, '泰州市': 9147.0, '宿遷市': 7979.0}
          city=list(HousePrice_data.keys())
          num=list(HousePrice_data.values())

          這里需要注意的一點是,每個城市名后面要加上"市"這個字,因為源代碼默認規定要有“市”,必須與其對應。(不同于上篇文章,上篇文章中所讀取的各省份、直轄市、自治區名稱中,并沒有添加“省”、“市區”、“自治區”這些后綴)

          第三步:畫圖

          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")
        1. 其中參數name指的是顯示在地圖正上方的標題,
        2. attr就是一個包含了各地級市名稱的列表,
        3. value就是包含了各地級市房價的列表,
        4. visual_range指的是整個數據中的數值范圍,
        5. maptype就是指的地圖類型,
        6. is_visualmap代表是否顯示顏色
        7. 這里需要注意的是,maptype=‘江蘇’,不需要加"省"字。另外,我新增了一個參數visual_text_color,該參數是用來顯示數字刻度的,細心的朋友會發現上篇文章中所生成的地圖左下角并沒有數字刻度。

          在運行上面的代碼后,會生成一個“江蘇地圖.html”的文件,打開后如圖所示:

          無各地級市名稱

          如果想保存為圖片,可以點擊地圖右側的下載按鈕,因為隔著比較遠,我在錄屏的時候并沒有把下載按鈕錄進來,但大家在自己電腦上肯定會看見的。

          第四步:額外操作

          第一點:大家可以看到上圖中各城市名稱只有在被鼠標選中的情況下,才能顯示,并且所保存的圖片也不會顯示各城市份名稱,如果想顯示各城市名稱,就要修改html文件,推薦使用notepad++(一個文本編輯軟件,直接去百度上下載,很簡單的)打開“江蘇地圖.html”文件,然后在第1923行的那個series中添加"label":{ "normal":{ "show":true}},并保存,如下:

          修改html文件

          然后再打開江蘇地圖.html,就會顯示各地級市名稱了,如下圖:

          有各地級市名稱

          第二點:大家可以看到地圖的默認色系是從冷色系過渡到暖色系,也就是從藍到黃再到紅,如果想更改地圖顯示的顏色,可以添加visual_range_color這個參數,該參數接受一個列表,列表里存放的是顏色過渡信息。比如我存放了三個土黃色系的顏色:#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")

          上面的代碼和第三步中的代碼區別就是添加了一個visual_range_color參數,對應的效果如下:

          土黃色系地圖

          關注微信公眾號“Python小鎮”,發現更多干貨知識!

          于企業多地點業務而言,SEO 策略與業務策略的協調對于成功至關重要。

          無論企業是經營特許經營模式、零售連鎖店,還是以服務區業務的形式運營多個中心,您的本地 SEO方法都需要量身定制,以滿足您的特定目標。它還需要具有足夠的可擴展性和效率,以便在獲得長期投資回報的同時進行維護。

          另一個關鍵要求是,您的內容方法要為用戶和 Google 創造足夠的價值,以使其高于索引質量閾值。

          這意味著超越本地 SEO 的標準最佳實踐 ,并創建可持續提高品牌知名度和轉化率的本地 SEO 活動。

          協調 SEO 與業務戰略

          多地點經營的企業有不同的目標。

          雖然多地點管理的基礎相同,但您的方法需要與整體戰略相結合并與整體業務目標保持一致。

          例如,在多個城鎮、城市和州經營服務業務的多家運營商的戰略特許經營業務與在多個州擁有數百家分店的大型倉儲式商店有所不同。

          成功指標也各不相同。通常,企業本地 SEO 活動的 KPI 屬于以下類別之一:

          • 提高各個地點的知名度和客流量。
          • 將本地意向搜索引導至在線商店進行直接投放,或將來與本地商店進行互動。
          • 以上兩者的結合。

          企業對“成功”的定義將極大地影響您為用戶創建選擇架構的方法以及報告成功的方式。

          批量創建本地頁面的方法

          多年來,我們描述和制作多區域服務頁面的方法發生了變化。

          十年前,我們會將質量低下的版本(只有細微修改且內容基本相同)稱為門頁,而谷歌隨著時間的推移逐漸降低了門頁的價值。

          近年來,隨著程序化 SEO(pSEO)的日益普及,這種方法已經成為大規模創建這些頁面的流行方法。

          本地服務頁面的程序化內容創建

          對于運營數百或數千個門店的企業來說,程序化或部分程序化內容創建可能是一個有吸引力的選擇。

          程序化 SEO(簡稱 pSEO)可讓您大規模生成大量內容。這種方法已幫助許多企業擴大規模,但如果所創建的頁面無法提供足夠獨特的價值主張,讓 Google 不愿投入資源,那么這種方法也會帶來問題。

          如果我們看一下本地服務頁面的兩個常見網站架構,我們通常有一個中央服務頁面,然后是本地服務頁面,或者有一個充當區域設置服務頁面網關的中央頁面 - 例如商店定位器。

          圖片來自作者,2024 年 7 月

          根據您的業務類型,您可能會默認選擇一種結構,但兩者都可能帶來挑戰。

          使用中央服務頁面結構,您可能會遇到創建獨特價值主張的問題,并確保每個頁面都具有足夠的差異化并高于 Google 索引的質量閾值。

          商店定位器頁面方法可能會導致 PageRank 分布以及內部鏈接到不同位置的方式出現問題。大多數用戶友好的商店位置應用程序不會加載 HTML 鏈接,因此雖然可以直觀地鏈接到所有商店,但 Google 無法抓取這些鏈接。

          然而,這兩種方法的共同問題是如何捕獲位置周圍“更廣泛”的搜索。

          本地內容價值主張

          當本地頁面最適合位置時,它們會發揮最大的幫助。

          從歷史上看,我看到一些公司通過在頁面上“夸大”該地區的額外信息來做到這一點,比如一兩段關于當地基礎設施、學校和運動隊的段落——如果你想讓人們訪問你的五金店或詢問你的上門安全裝配服務,這些信息都與你無關。

          僅僅更改 URL、H1、標題標簽和整個正文中的位置名稱也是不夠的。

          當這種情況發生時,谷歌實際上會看到近似重復的頁面,這些頁面在與用戶查詢相關的價值主張上幾乎沒有區別。

          這種情況的癥狀是,當頁面在 Search Console 中顯示為未編入索引時,Google 要么選擇覆蓋用戶聲明的規范,要么停留在“已發現”或“已抓取”的階段,而當前尚未編入索引。

          本地服務和位置頁面之間總會存在一定程度的重復。Google 對此并不介意。某些內容在多個頁面上重復并不意味著其質量低下。

          創造價值主張差異化

          這是我傾向于采用部分程序化方法的地方。

          程序化可以滿足 70% (+) 的頁面內容;它可以涵蓋您針對特定位置的服務產品、定價和公司信息。

          該頁面的剩余百分比是手動的,但允許您創建與其他頁面的價值主張差異化。

          假設您是一家跨州快遞服務公司,擁有多條市場路線,您在德克薩斯州的主要配送中心位于奧斯汀、圣安東尼奧和達拉斯,而您想要瞄準尤利斯的潛在客戶。

          您為尤利斯提供的服務與您為普弗拉格維爾、凱爾和利安德的客戶提供的服務相同 - 因此每個位置頁面的這些部分在所有位置上都是相同的。

          但是尤利斯由達拉斯樞紐提供服務,而其他機場則由奧斯汀樞紐提供服務——這是您要強調的第一個內容差異點。

          然后,您可以使用來自企業內部的數據和關鍵字研究,用旅行時間數據充實這些頁面。

          在尤利斯尋找快遞服務的客戶可能正在尋找從尤利斯到奧斯汀或從尤利斯到休斯頓的服務——因此,將此構建到本地頁面并提供從目的地到熱門地點的時間估算,可以顯示出本地的專業性并幫助客戶更好地了解服務和計劃。

          您的業?務數據還將幫助您識別客戶類型。例如,在尤利斯預訂的許多工作可能針對的是搬出校園居住的大學生,因此這又是針對可以包含在頁面上的客戶群的更具本地化的定位。

          內部鏈接

          當涉及到內部鏈接時,使用偽 HTML 站點地圖可以幫助實現這一點,它不僅可以充當通過頁面的干凈內部鏈接,而且還對用戶有益,并允許您創建其他登錄頁面來定位縣或地區級搜索。

          十年前,在一個房產查找頁面上,我所在的團隊構建了“縣 > 鎮/市”的頁面結構模式,同時將相關位置拉入登錄頁面。

          作者截圖,2024 年 7 月

          從視覺上看,這只是一種更“手動”的方法,讓用戶可以從非特定位置的頁面篩選到他們所在的當地區域。

          Google 商業資料鏈接

          另一個經常被忽視的關鍵組件是將 Google 商業資料(GBP) 直接鏈接到網站上的相關位置頁面。

          我遇到過許多跨國公司和國內公司,他們鏈接回自己的公司主頁,有時還帶有一個參數來突出顯示用戶點擊的是哪個 GBP——但這既是糟糕的網絡架構,也是糟糕的用戶選擇架構。

          如果用戶正在尋找 XYZ 中的服務/商店,他們不希望在點擊網站鏈接時看到主頁或通用信息頁面。

          就用戶選擇架構而言,從這里,用戶可以導航到不同的商店或頁面,并錯過與他們相關的關鍵信息,否則這些信息可能會推動銷售或詢問。

          谷歌的本地算法

          除了 Google 的核心算法和更通用的搜索排名信號外,Google 還發布了專門針對本地查詢的更新。主要有兩個:

          • Pigeon 2014:此次更新旨在通過將本地搜索結果與一般搜索排名信號更緊密地結合起來,提供更相關、更準確的本地搜索結果。用戶接近度(作為信號)也得到了提升。
          • Possum 2016:此次更新旨在提高位于城市邊界外的商家的排名,使搜索結果更符合用戶與商家的距離。還引入了基于地址的過濾,以避免重復列出共享同一地址的商家(例如虛擬辦公室)。

          這些更新使企業更難以欺騙自己在當地市場的存在,并且可能無法提供符合或滿足搜索者需求的價值主張。

          據傳,谷歌似乎優先對提供最全面信息的企業進行排名。

          這包括開業日期、現場餐飲選擇(如果適用)、特殊營業時間、業務類別、服務列表以及定義服務區域和服務類型。

          Google 商業檔案的重要性

          遵循指南是必須的,但即便如此,你仍可能會違反 Google 的自動檢測檢查。

          與一家在亞洲擁有多個辦事處的國際軟件公司合作,在共享辦公室中租用了許多樓層。

          我們假設,Google 偶爾會檢測到共享地址并誤認為它們是虛擬辦公室/虛假地址,而Possum 算法更新旨在減少這種情況。

          當您與擁有大量實際位置的企業組織合作時,通過內部利益相關者管理以及了解 GBP 如何適應并貢獻于總體目標和生態系統,Google 商家資料管理方法可能會變得更加復雜。

          報告英鎊數據

          根據您的目標,報告成功的方式將因活動而異。

          通過 Google API,您可以訪問展示次數的列表級數據,以及不同用戶互動的細分(從 GSC 鏡像指標推斷展示次數和點擊次數)。

          非典型的 Google Business Profile 報告儀表板。(作者截圖,2024 年 7 月)

          在我看來,任何在多個城鎮、城市、縣或州運營的企業都需要擁有某種形式的 GBP 監控和報告可見性,而不僅僅是在 Google Search Console 和其他分析平臺中跟蹤參數化 URL(假設您在 GBP 網站鏈接上使用參數)。

          市選擇頁需求展示

          首先明確這是我們即將需要開發的城市選擇頁面:

          城市選擇頁路由配置

          在gitee的分支欄點擊新建分支city-router,然后記得將本地master分支切換到city-router分支。如何切換呢?步驟如下:第一步:使用git pull將創建的city-router分支拉到本地;第二步:執行git checkout city-router切換到city-router分支;第三步:使用git status查看一下當前的分支狀態:(出現這個說明分支切換成功)

          $ 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>
          

          我們是希望點擊右上角的北京也就是城市區域,可以跳轉至城市列表頁:

          那么需要在Header.vue中進行跳轉鏈接的配置,而前面說過鏈接跳轉使用<router-link>標簽結合to屬性,則跳轉鏈接區域代碼修改為:

              <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鏈接。但是此時頁面跳轉區域會變為黑色:

          那是因為<router-link>會默認給元素添加一個顏色:color: #25a4bb;,此時你可以給這個.header-right屬性增加color: #fff;使之變成白色就可以解決這個問題了,經過測試發現頁面跳轉測試通過。

          城市選擇頁面開發

          由于去哪網城市選擇頁面包含境內和境外且兩者除了內容不同外,其余所有信息均相同,因此本篇筆記只介紹境內城市頁面的開發。

          在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>
          

          其實就是點擊左邊的箭頭頁面跳轉至首頁:

          注意到height: $headerHeight,這是因為對于行高和高度而言,我們發現多處地方都是.86rem,因此考慮將其提出單獨成為一個變量,因此你可以在tyles/varibles.styl文件中新增:$headerHeight=.86rem即可。

          注意考慮到效率的問題,現在可能是直接把完成后的整個代碼粘貼出來,后期會根據情況進行細化介紹。

          最后就是將我們的代碼上傳到city-router分支,并且將其與master分支進行合并,相應的步驟如下:

          git status
          git add .
          git commit -m 'city router'
          git push
          git checkout master
          git merge city-router
          git push
          

          如此關于城市選擇頁路由配置就到此為止,后續是搜索框的布局。

          搜索框布局

          在gitee的分支欄點擊新建分支city-search,然后記得將本地master分支切換到city-search分支。如何切換呢?步驟如下:第一步:使用git pull將創建的city-search分支拉到本地;第二步:執行git checkout city-search切換到city-search分支;第三步:使用git status查看一下當前的分支狀態:(出現這個說明分支切換成功)

          $ 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
          

          如此關于城市搜索框的介紹完畢,后續是城市列表布局的開發。

          城市列表頁開發

          在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選擇器在被選元素的內容前面插入內容,請使用 content 屬性來指定要插入的內容。舉個例子,如在每個<p>元素的內容之前插入新內容:

          p:before
          { 
          content:"hello,vuejs!:";
          }
          

          其次就是list這個類用于固定標題,也就是說讓List組件的頂部外邊距騰出固定的位置用于顯示Header和Search組件。仔細看現在的樣子:

          現在我們已經把Header和Search組件所占用的空間給讓出來了,但是有一個問題就是紅色區域是list類所能顯示的范圍,也就是說紅色區域后面的都是顯示不了的:

          有人可能會問怎么顯示不了,因為紅色區域就是<div class="list">所占用的區域背景:

          .list
            position: absolute
            top: 1.58rem
            left: 0
            right: 0
            bottom: 0
            background: red
          

          這樣是不行的,我們需要滑動右側的滾輪使城市列表詳細顯示出來,這就需要使用到后面介紹的BetterScroll了。

          字母滾動條

          在前面為了保證button撐起可以顯示Header和Search組件的高度,我們給.list類添加了以下兩行代碼:

          .list
            overflow: hidden
            position: absolute
          

          這樣就會使得頁面無法滾動,想要實現可以滾動的效果可以借助于第三方插件better-scroll,先使用以下命令進行安裝better-scroll:npm install better-scroll --save,然后閱讀文檔發現DOM結構應當類似如下結構:

          <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,因此需要包裹兩層結構:

          繼續閱讀文檔:

          文檔的意思是說使用better-scroll其實就是創建Bscroll對象,而這個對象需要傳入一個DOM節點作為參數。還記得以前講過當你需要直接操作某個DOM節點的時候,Vue提供了ref屬性,然后你只需要使用$refs來獲取DOM節點。

          因此第一步獲取到wrapper類節點DOM:

            <div class="list" ref="wrapper">
          

          第二步導入Bscroll類及創建該對象:

          <script>
          import BScroll from 'better-scroll'
          export default {
            name: 'CityList',
            mounted () {
              this.scroll=new BScroll(this.$refs.wrapper)
            }
          }
          </script>
          

          只需這兩步就完成了頁面滾動的效果:

          之前顯示不了的白色區域也全變成了紅色區域,現在去掉.list中的background屬性。

          現在有一個小的細節就是“當前城市”的高度有點低,可以將.title的line-height屬性由.44rem調整為.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。

          城市字母表

          右側的城市字母表就是我們即將需要實現的功能:

          在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是一種布局方式,它既可以應用于容器中,也可以應用于行內元素。Flex是Flexible Box的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。設為Flex布局以后,子元素的float、clear和vertical-align屬性將失效。了解更多可以點擊這里Css display:flex屬性。

          flex-direction:表示彈性盒子中的元素的排列順序。可以按行、列、按行反向排序、或者按列反向排序等。此處我們的字母表是按列排序,不過使用這個參數的前提是需要有display: flex(即將其設置為彈性盒子) 否則無法實現預期效果,了解更多可以點擊這里CSS flex-direction屬性。

          justify-content:用于設置或檢索彈性盒子元素在主軸(橫軸)方向上的對齊方式。 如果使用align-content屬性對齊交叉軸上的各項(垂直)。其實就是元素的水平對齊方式是左對齊、右對齊、居中對齊、兩端對齊還是環繞對齊。此處的字母表是水平居中對齊各個元素,因此應當設為center,了解更多可以點擊這里CSS justify-content 屬性。

          這樣關于字母表的布局就介紹完了,后續是介紹如何將數據動態渲染到頁面上。不過在此之前先把本組件的代碼上傳至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頁面加載完全后使用生命周期函數 mounted加載Ajax數據。mounted生命周期函數是在模板渲染成html后調用,通常是初始化頁面完成后,再對html的dom節點進行一些需要的操作:

          <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>
          

          運行結果為:

          這里為了將ajax獲取到的數據進行展示,我們使用了父子組件正向傳值的方式。所有待展示的數據已經準備好了,在static/envy/city.json文件中,里面包括:hotCities、cities。數據展示操作步驟如下,第一步打開City.vue文件(前三部均在該文件內操作),新增數據返回對象data:

          data () {
              return {
                cities: {},
                hotCities: []
              }
            },
          

          第二步修改getCityInfoResource函數代碼:

          getCityInfoResource (res) {
                res=res.data
                if (res.ret && res.data) {
                  const data=res.data
                  this.cities=data.cities
                  this.hotCities=data.hotCities
                }
              }
          

          第三步進行數據動態綁定:

          <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>
          

          然后繼續使用文本插值語法展示所有城市:

          <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是一個對象,里面包含了數組,而數組中又包含了對象:

          因此需要使用雙層循環,第一層遍歷獲取諸如'A':[]類的信息,遍歷數組的格式是(item,index) of array,而遍歷對象的格式是(item,key,index) of object,所以使用對應的格式進行遍歷即可。注意雙層循環的時候,如果父級的:key與子級的:key值一樣是可以的,只要父級的:key不重復,而與子級的:key重復是沒有關系的。

          第五步打開Alphabet.vue組件,開始填充城市字母表的數據。先使用props來接收父組件傳遞的數據:

          <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
          

          如此關于城市列表頁的內容就介紹完畢,后續是如何實現點擊右側的字母就能跳轉至對象的首字母城市,也就是兄弟組件之間的聯動。


          主站蜘蛛池模板: 国产一区二区三区手机在线观看 | 国产亚洲福利一区二区免费看 | 日韩精品无码一区二区视频| 国产日韩精品一区二区三区在线| 亚洲日韩AV无码一区二区三区人| 亚欧成人中文字幕一区| 国产在线观看一区二区三区四区| 国产日韩一区二区三区| 久久久av波多野一区二区| 中文字幕日韩人妻不卡一区 | 天堂不卡一区二区视频在线观看 | 无码人妻一区二区三区一| 免费日本一区二区| 亚洲日韩精品一区二区三区无码| 一区二区三区四区在线观看视频| 国产亚洲综合精品一区二区三区 | 无码人妻一区二区三区免费n鬼沢| 国产一区二区精品久久凹凸 | 国产成人欧美一区二区三区 | 夜色阁亚洲一区二区三区| 女女同性一区二区三区四区| 在线免费观看一区二区三区| 国产精品久久久久一区二区三区 | 国产精品合集一区二区三区| 人妻体内射精一区二区三四| 精品人妻码一区二区三区| 国产成人精品日本亚洲专一区 | 欧美亚洲精品一区二区| 日本精品一区二区在线播放| 欧洲亚洲综合一区二区三区| 福利一区在线视频| 久久久久女教师免费一区| 中文字幕一区二区三区四区| 国产一区二区三区久久精品| 亚洲AV综合色一区二区三区| 亚洲一区二区三区免费观看| 国产精品无码一区二区三区毛片| 男人的天堂亚洲一区二区三区| 国产精品99无码一区二区| 国产AV一区二区三区无码野战| 亚洲中文字幕久久久一区|