使用 Node + vue 對公司的官網進行了一個簡單的移動端的實現。javascript
https://github.com/wx1993/node-vue-fabaocnphp
Express、Vue、Vue-Router、Vue-Resource、Webpackcss
Vuehtml
vue 的組件化思想和 React 很像,一個 vue 組件將 html、css 和 js 都寫在一個文件裏面,組件管理和維護本身的數據和狀態,方便編寫也便於調試。vue
Vue-Resourcejava
做爲 vue 全家桶的一員,vue-resource 主要用在 HTTP 請求功能上,相似的工具還有 axios,雖然 vue2.0 推薦使用 axios,可是我的仍是習慣於用 vue-resource,使用起來也十分簡單,在實例中可使用如下格式的寫法:node
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
關於 vue-resource 的使用能夠參考: http://www.jianshu.com/p/3ce2bd36596ejquery
Vue-Routerwebpack
vue 經過配合 vue-router 來建立單頁應用,其思想是將 vue 組件映射到路由,並將路由掛載到 app 上,在頁面中經過 router-link 和 router-view 來定義頁面路由並切換到不一樣的組件。ios
<!-- html --> <router-link to="/home">Home</router-link> // js import Home from './components/home' const routes = [ { path: '/home', component: Home }, ] const router = new VueRouter({ routes }) const app = new Vue({ router }).$mount('#app')
Express + Vue + Webpack
經典的 node 項目結構配合手動建立的 src 目錄(用來放置全部的組件、入口和路由文件)。
// 安裝依賴 npm install // 項目打包 webpack -w // 啓動項目 npm start
由於項目自己並不複雜,因此這裏僅針對幾個難點和遇到的坑進行簡單的解釋和分析。
一、接口的封裝和數據的請求
應用相關的接口都在node中進行封裝,具體使用到了 request 模塊的 get 和 post 方法,以下:
// 獲取職位列表 router.post('/getJobs', function (req, res, next) { console.log(req.body.jobId); const jobsUrl = 'http://www.fabao.cn/api/FABAO_WEBSITE/job/getjobinfo?nonce=1494212786000§ionid=' + req.body.jobId +'&pageNumber=1&pageSize=20'; console.log(jobsUrl); request(jobsUrl, function (error, response, body) { if(!error && response.statusCode == '200') { res.send(body) } }) })
請求接口在組件中經過 vue-resource 來實現,以下:
getJoblist () { this.$http.post('/getJobs', { jobId }).then(data => { console.log(data); this.items = data.body.res; }, error => { console.log(error); }) }
二、路由地址變化的的監聽
在項目中的新聞詳情頁面有一個點擊按鈕查看上一篇或下一篇新聞的功能:
這裏經過直接在按鈕上定義路由中的新聞 id 的增減的方式來實現,以下:
<router-link :to="{name: 'news', params: {id: data.id - 1}}" replace>{{prevTxt}}</router-link> <router-link :to="{name: 'news', params: {id: data.id + 1}}">{{nextTxt}}</router-link>
可是發現,在點擊了按鈕以後,地址欄中的 url 確實變了,新聞 id 對應的加1或減1,可是頁面內容並無發生變化,針對這個問題,能夠經過監聽router 來解決,以下:
watch: { // 當路由發生變化時自動請求數據 "$route": "getNewsDetail" }
這樣,在 url 發生變化時,就獲取新的 url 地址,並主動請求一次數據,從而實現了內容的更新。
getNewsDetail 方法以下:
getNewsDetail () { // use vue-resource const curId = this.$route.params.id; this.$http.post('/getNewsDetail', {id: curId }).then(data => { if (data.body.res) { this.prevTxt = '上一篇'; this.nextTxt = '下一篇' this.data = data.body.res[0] }else { if (curId > this.initialId) { // 點擊了下一篇 this.nextTxt = '沒有啦'; this.prevTxt = '上一篇'; }else { // 點擊了上一篇 this.prevTxt = '沒有啦' this.nextTxt = '下一篇' } } }, error => { console.log(error); }) }
三、元素的切換和顯示隱藏
使用 jquery 來實現元素的切換和顯示隱藏十分簡單,只要控制元素的display屬性或者show()/hide()方法或者經過添加和移除類名的方式來實現,可是在 vue 中,由於不便於直接操做 dom 元素,因此在實現這樣的效果的時候須要轉換思路。以"加入咱們"頁面的效果爲例:
在實現上方標籤的切換和高亮,以及下方職位列表信息的現實隱藏,都涉及到元素屬性和樣式的變化,這裏主要是經過動態的類名和 v-show 的方式來實現。
首先,崗位標籤的結構以下:
<div class="job-type"> <span @click="getJoblist(6)" :class="{active: activeId == 6}">急招崗位</span> <span @click="getJoblist(7)" :class="{active: activeId == 7}">平常崗位</span> <span @click="getJoblist(8)" :class="{active: activeId == 8}">校園招聘</span> </div>
在這裏,點擊不一樣的標籤會傳入不一樣的參數,並請求不一樣的崗位信息來實現下方列表的更新,同時爲每個標籤都綁定了一個 active 的類名,並經過判斷當前點擊的標籤 id 來控制類名的有無。
getJoblist (jobId) { this.activeId = jobId; this.$http.post('/getJobs', { jobId }).then(data => { console.log(data); this.items = data.body.res; }, error => { console.log(error); }) }
能夠看到,在請求職位列表的方法中,首先便經過傳入的 jobId 來設置當前的標籤 id,由於標籤 id 是定義在 data 中的,因此全部的標籤都共享一個 activeId,所以當點擊了標籤時,傳入的 id 即是當前的標籤 id,對應的類名 active 也就爲真,同時其餘的標籤對應的 active 爲假,經過這種方式來實現類名的控制。
一樣,在下方職位列表信息的現實隱藏上也使用了相似的方式,不一樣的地方在於,在點擊了對應的職位時,不只須要顯示詳細信息,還需明確當前點擊的是哪一項,所以這裏須要用到兩個判斷:
<section class="job-info" @click="showDetail(item.id)"> <h3>{{item.name}}</h3> <div> <address>{{item.company_name}}</address> <span>{{item.type}}</span> <time>{{item.create_date}}</time> </div> </section> <transition name="fade"> <section class="job-detail" v-show="jobId === item.id && ifShow"> <h4>職位描述</h4> <p> <span>崗位職責</span> <pre>{{item.require}}</pre> <span>任職資格</span> <pre>{{item.description}}</pre> </p> </section> </transition>
ifShow 在 組件的 data 中定義,默認爲 false,當點擊列表,觸發showDetail(item.id)方法時,傳入當前列表項的id,並賦值給 jobId,同時修改 ifShow,這樣經過兩個布爾值的綜合判斷,能夠決定當前點擊項對應的詳情是否顯示。
四、百度地圖的使用
在聯繫咱們頁面中使用到了百度地圖,同時點擊地址列表,會對地圖信息進行切換和定位,以下:
下面簡單介紹一下在vue組件中百度地圖的使用方法。
首先進入百度地圖API官網(http://lbsyun.baidu.com/index.php?title=jspopular),點擊【獲取密鑰】,而後驗證郵箱,以後根據提示(參照【開發指南】)進行配置,提交後就能得到一串密鑰,這在引入的api庫須要用到。
在 index.html 中引入百度地圖API
<script src="http://api.map.baidu.com/api?v=2.0&ak=您的密鑰" type="text/javascript"></script>
在組件中使用:
mounted () { this.showMap(121.407585, 31.176521); }, methods: { showMap (x, y, locationId) { this.locationId = locationId; this.showNumber = !this.showNumber; var map = new BMap.Map("container"); // 建立地圖實例 var point = new BMap.Point(x, y); // 建立點座標 map.centerAndZoom(point, 17); // 初始化地圖,設置中心點座標和地圖級別 } }
這裏定義了一個 showMap() 方法,在裏面初始化了地圖並經過傳入的經緯度參數來建立座標。這部分代碼直接參照百度地圖api的實例便可。在方法中還傳入了一個 locationId,這是由於這裏有三個地址,因此要經過這個 id 進行區分。
<div class="location-item"> <div class="location-info clearfix" @click="showMap(121.407585, 31.176521, 1)"> <div class="location-icon"> <img src="/images/home1.png"> </div> <div class="location-content"> <h3>上海總部</h3> <p>徐彙區宜山路1009號18樓</p> </div> </div> <div class="contact-way" v-show="showNumber && locationId == 1"> <p>電話:<a href="tel: 021-54268114">021-54268114</a></p> <p>傳真:<a href="tel: 021-54278114">021-54278114</a></p> </div> </div>
能夠看到,在點擊地址列表的時候觸發了showMap()方法,並傳入了當前地址的經緯度和列表項的 id,從而觸發地圖信息的更新。其中經緯度能夠在百度地圖中獲取,這裏推薦百度地圖生成器,http://api.map.baidu.com/lbsapi/creatmap/index.html,在這裏能夠經過輸入地名進行定位,並獲取經緯度,同時能夠設置級別,添加標註等等,更便捷的是,在設置了相關信息後能夠直接獲取代碼,所以使用起來十分方便,以下所示:
百度地圖還提供了不少其餘的功能,好比縮放按鈕,地圖標註、實時交通等等,能夠根據須要進行配置。這裏就不一一介紹了。
關於項目中的其餘問題,歡迎你們和我交流:QQ 596291080