接着上一篇咱們接着講,關於這個網站的專題頁面和2015精選頁面,若是有小夥伴沒看過上一篇文章,這裏附上上一篇文章的的連接基於Vue,Vue-router,Vuex的簡書網站模仿
這裏是網站的源碼下載地址 Github Repo
這裏是Demo地址,在線感覺vue的魅力vue
App.vue
:黃色框部分和紫色框部分git
Topic.vue
:橙色框部分github
Topic_article.vue
:藍色框部分(同時也是重點部分,實現點擊排序)vuex
學會分析頁面結構,是用vue開發一個比較重要的地方(我猜的),因此我再次分析了一次。頁面結構分析結束後,接下來就是上代碼的時候了。segmentfault
topic.vue
部分和上一篇文章的home.vue
部分是一模一樣的,爲了讓你們加深印象,我就再講一次(我不會講我是來湊字數的,嘿嘿)。上代碼:數組
<template> <div> <div class="showbar"> <div class="cover-image_2"></div> <div class="text" style="text-shadow:1px 1px 1px #000000"> <h1>專題</h1> <h3>讓思想匯聚,流傳</h3> <p style="font-size:14px;margin-bottom:5px">專題內容由多位寫做者提供</p> <a href="#"><i class="fa fa-pencil"></i> 新建專題</a> </div> </div> <div class="article-page"> <nav> <span class="search clearfloat"> <span class="input"> <input type="search" placeholder="搜索"> </span> <span class="search-icon"><i class="fa fa-search"></i></span> </span> </nav> <div class="article-list"> <ul class="btn-group"> <li :class="{active: show === 'hot'}"> <a @click="displayTopic('hot')" v-link="'/topic/topic_article'" >熱門</a></li> <li :class="{active: show === 'recommend'}"> <a @click="displayTopic('recommend')" v-link="'/topic/topic_article'" >推薦</a></li> </div> <router-view></router-view> </div> </div> </template> <script> import {displayTopic} from '../vuex/actions' export default { vuex:{ getters:{ show: state => state.show_2 }, actions:{ displayTopic } } } </script>
因爲橙色框部分裏熱門和推薦兩個導航按鈕,要根據兩個按鈕展現不一樣的文章,這就和上一篇文章裏的Home.vue裏實現的方式同樣,咱們經過:class="{active: show === 'hot'}
來判斷當前按鈕是否處於被點擊狀態,這裏的show來自於vuex(getters)獲取到的show,而且給它加上不同的樣式。經過@click="displayTopic('hot')
點擊事件來更換不一樣的show值和文章內容。這樣咱們就實現了點擊切換按鈕狀態和文章區域內容。下面放上點擊事件的代碼:
actions.js:微信
export const displayTopic = ({ dispatch },show) => { dispatch('DISPLAY_TOPIC',show) }
store.js:函數
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { topics:{ fir: { img:'../../static/topic_1.jpg', title:'遊戲', par:'玩轉簡書的第一步,從這個專題開始。\ 想上首頁熱門榜麼?好內容想被更多人看到麼?來投稿吧!\ 若是被拒也不要灰心哦~入選文章會進一個隊列挨個上首頁,請耐心等待。\ 投稿必須原創。若是發現有非...', number:'97233', concern:'121.7', keys:'故事、連載', time:'20160620' }, sec: { img:'../../static/topic_3.jpg', title:'詩', par:'詩,讓你感覺本身的心靈。\ 專題主編:蘇錦年 投稿須知:\ 1.本專題收錄古詩、詞、現代詩以及詩詞點評及指導。\ 2.內容必須爲原創,切勿用其餘詩人的詩句。\ 3.文章排版整潔,注意...', number:'35420', concern:'146.6', keys:'詩', time:'20160630' } }, show_2:'hot' } const mutations = { DISPLAY_TOPIC (state, show) { const topic = { hot: { fir: { img:'url../../static/vue-demo-hot.jpg', title:'遊戲', par:'玩轉簡書的第一步,從這個專題開始。\ 想上首頁熱門榜麼?好內容想被更多人看到麼?來投稿吧!\ 若是被拒也不要灰心哦~入選文章會進一個隊列挨個上首頁,請耐心等待。\ 投稿必須原創。若是發現有非...', number:'97233', concern:'121.7k', keys:'故事、連載' }, sec: { img:'../../static/topic_3.jpg', title:'詩', par:'詩,讓你感覺本身的心靈。\ 專題主編:蘇錦年 投稿須知:\ 1.本專題收錄古詩、詞、現代詩以及詩詞點評及指導。\ 2.內容必須爲原創,切勿用其餘詩人的詩句。\ 3.文章排版整潔,注意...', number:'35420', concern:'146.6k', keys:'詩', time:'20160630' } }, recommend: { fir: { img:'../../static/topic_1.jpg', title:'遊戲', par:'玩轉簡書的第一步,從這個專題開始。\ 想上首頁熱門榜麼?好內容想被更多人看到麼?來投稿吧!\ 若是被拒也不要灰心哦~入選文章會進一個隊列挨個上首頁,請耐心等待。\ 投稿必須原創。若是發現有非...', number:'97233', concern:'121.7', keys:'故事、連載', time:'20160620' }, sec: { img:'../../static/topic_3.jpg', title:'詩', par:'詩,讓你感覺本身的心靈。\ 專題主編:蘇錦年 投稿須知:\ 1.本專題收錄古詩、詞、現代詩以及詩詞點評及指導。\ 2.內容必須爲原創,切勿用其餘詩人的詩句。\ 3.文章排版整潔,注意...', number:'35420', concern:'146.6', keys:'詩', time:'20160630' }, thi: { img:'../../static/topic_2.jpg', title:'@IT互聯網', par:'@IT 專題 由 IT大分類,轉定位於IT·互聯網行業觀察與思考,數碼產品極客體驗。\ 主編:向右奔跑 http://www.jianshu.com/users/54b5900965ea...', number:'8409', concern:'111.1', keys:'互聯網、產品、科技', time:'20160625' } } } state.show_2 = show state.topics = topic[show] } } export default new Vuex.Store({ state, mutations })
這裏面我省掉了上一章的代碼。這裏面我才用模擬的數據,能夠清楚的看到實現方式。接下來說解排序部分,這裏算是一個重點吧,由於我在這裏遇到了坑。網站
這部分咱們要實現根據小導航的切換來顯示不一樣的順序(熱門,推薦,最新更新),這裏我只作了推薦和最新更新這兩部分。首先要實現這種效果,咱們第一時間想到的就應該是和大導航同樣給小導航添加class綁定和點擊事件。接下來看代碼,先是Topic_article.vue的代碼:this
<template> <div class="topic_article_container"> <div class="sequence-nav" v-if="show === 'recommend'"> <a @click="sortContent('time'), change = 'new'" :class="{active: change === 'new'}">最新更新 ·</a> <a @click="change = 'hot'" :class="{active: change === 'hot'}">熱門排序 ·</a> <a @click="sortContent('concern'), change = 'new'" :class="{active: change === 'concern'}">關注度排序</a> </div> <ul> <li v-for="content in topic"> <a href="" class="topic_article_img"><img :src="content.img"></a> <div class="topic_content"> <h5>{{ content.title }}</h5> <p>{{ content.par }}</p> <div class="topic_button"> <a href="#"><i class="fa fa-fw fa-plus"></i><span>添加關注</span></a> </div> <p> <a href="#" style="color:#4094c7">{{ content.number}}篇文章</a> · {{content.concern}}k人關注 <span class="topic_tag"><i class="fa fa-tags"></i>{{ content.keys}}</span> </p> </div> </li> </ul> </div> </template> <script> import { sortContent } from '../vuex/actions' export default { data (){ let change = 'hot' return {change} }, vuex: { getters: { topic: state => state.topics, show: state => state.show_2 }, actions: { sortContent } } } </script>
由於這個小導航欄在熱門頁面裏是沒有的,這裏才用了vue的v-if功能實現,經過getters得到此時的show變量,判斷是不是推薦頁面,若是是就顯示。這裏的文章依然採用vue的列表渲染功能(真好用),同時給小導航欄設置了點擊事件,和改變背景的一個變量。接下來放上actions.js裏面的代碼:
export const sortContent = ({ dispatch },method) => { dispatch('SORTCONTENT',method) }
也是那麼短小精悍,畢竟我只用於分發事件。下面是store.js裏面的代碼:
SORTCONTENT (state, method){ const temp = state.topics let arr = [] let Arr = objClone(state.topics) switch(method){ case 'time': arr = [temp.fir.time, temp.sec.time, temp.thi.time].sort() break case 'concern': arr = [temp.fir.concern, temp.sec.concern, temp.thi.concern].sort() break default: break } for(let keys in state.topics){ if(Arr[keys][method] == arr[2]){ state.topics.fir = Arr[keys] } else if(Arr[keys][method] == arr[1]){ state.topics.sec = Arr[keys] } else if(Arr[keys][method] == arr[0]){ state.topics.thi = Arr[keys] } } function objClone(myObj){ if(typeof(myObj) != 'object') return myObj; if(myObj == null) return myObj; var myNewObj = new Object(); for(var i in myObj){ myNewObj[i] = objClone(myObj[i]); } return myNewObj; } }
這個事件的代碼也很好理解,經過對不一樣的method,把不一樣的變量進行排序後賦值給一個數組,而後依次與topics作匹配,由於我這裏只模擬了三個數據,故這部分操做比較簡單。重點的是當我匹配topics裏第三個屬性(thi)的值的時候,這個時候topics裏的第三個屬性值已經變了(由於若是第二個屬性(sec)的值是最小的,就會把這個屬性賦給第三個屬性,這時候第三個屬性就變了,因此第三次匹配的時候仍是得出和第二次一樣的結果)。這時候個人作法是克隆一個和topics相同的對象,用這個對象去匹配,匹配好了以後把這個對象裏相應的值賦值給topics。我講的有點囉嗦,具體看代碼實現。(ps:克隆對象的時候,我居然直接進行賦值克隆,卻不知都是指向同一個地址空間,後來瞭解到須要從新開一個地址空間才能克隆,故有了上面那段objClone函數。)
到這裏簡書兩個主要的部分就講完了(Home.vue,Topic.vue)
接下來講一說2015年精選頁面
這個頁面相對來講比較簡單,就一個vue的列表渲染(不用列表渲染的話代碼太多,太長,關鍵是逼格不高),先上頁面:
圖中相似的標籤有12個,故才用列表渲染來簡化重複的代碼,接下來是代碼部分:
<template> <div class="bonus-container"> <div class="bonus-header"> <span class="yellow"> 簡書2015</span> <i> · </i> <span>每個月一篇好文章 </span> </div> <div class="share"> <span><a href="#"><i class="fa fa-mobile"></i>手機查看效果更佳</a></span> <span><a href="#"><i class="fa fa-weibo"></i>分享到微博</a></span> <span><a href="#"><i class="fa fa-wechat"></i>分享到微信</a></span> <span><a href="#">更多分享</a></span> </div> <ul class="text-list"> <li v-for="article in articles" :style="{ background: article.article.bg, backgroundSize: '100%', backgroundRepeat: 'no-repeat', backgroundColor: '#ffffff'}" <div class="content"> <a class="mask" href="#"> <div class="button">閱讀全文></div> </a> <div class="bonus-text"> <div class="bonus-text-title">{{ article.article.title}}</div> <div class="line"></div> <div class="bonus-text-content"> {{article.article.content_1}}<br> {{article.article.content_2}}<br> {{article.article.content_3}}<br> {{article.article.content_4}}<br> {{article.article.content_5}}<br> {{article.article.content_6}}<br> </div> </div> <div class="author"></div> </div> </li> </template> <script> export default { data () { let articles = '' return {articles} }, vuex: { getters: { texts: state => state.texts } }, ready: function() { this.articles = [{article: this.texts.Jan}, {article: this.texts.Feb}, {article: this.texts.Mar}, {article: this.texts.Apr}, {article: this.texts.May}, {article: this.texts.Jun}, {article: this.texts.Jul}, {article: this.texts.Aug}, {article: this.texts.Sep}, {article: this.texts.Oct}, {article: this.texts.Nov}, {article: this.texts.Dec}] } } </script>
下面是store.js裏面模擬的數據
texts:{ Jan:{ title:'給你90天,成爲不同的本身', content_1:"若是你應付不了如今的生活和工做", content_2:"不管你走到哪裏,", content_3:"不管你換了什麼工做,什麼公司,", content_4:"都無濟於事。", content_5:"由於你根本沒想讓本身成熟起來,", content_6:"想讓變的更優秀也不過是一句口頭禪。", author:'', bg:'url(../../static/bonus_1.jpg)' }, Feb:{ title:'使你更有思想的20本書', content_1:"真正偉大的當代文學,", content_2:"正如人們藉由狄更斯來了解十九世紀的英國,", content_3:"後人也能夠經過《自由》來了解", content_4:"二十一世紀初期的美國。", content_5:"", content_6:"", author:'', bg:'url(../../static/bonus_2.jpg)' }, Mar:{ title:'無感是最溫馨的愛情', content_1:"愛情本來就是個很嬌氣的東西,", content_2:"它經不起太多的矯情,你死我活和無理取鬧,", content_3:"也經不起任何的假裝,刻意討好和忍辱負重。", content_4:"當她拂去全部的驚喜,榮幸,不敢置信和當心翼翼,", content_5:"纔是愛情最本來的樣子。", content_6:"當她再也不刻意的感覺他的存在,", author:'', bg:'url(../../static/bonus_3.jpg)' }, Apr:{ title:'無感是最溫馨的愛情', content_1:"愛情本來就是個很嬌氣的東西,", content_2:"它經不起太多的矯情,你死我活和無理取鬧,", content_3:"也經不起任何的假裝,刻意討好和忍辱負重。", content_4:"當她拂去全部的驚喜,榮幸,不敢置信和當心翼翼,", content_5:"纔是愛情最本來的樣子。", content_6:"當她再也不刻意的感覺他的存在,", author:'', bg:'url(../../static/bonus_4.jpg)' }
這裏我只給出5條數據,後面都是重複的,代碼就不過多講解了,實現方式和前面的同樣。看到這裏是否是感受寫一個網頁很簡單,是否是以爲Vue可好玩了,是的話那就對了,加油吧!騷年!結尾仍是那句話,求個收藏什麼的,若有錯誤,歡迎斧正。