參考:
Vue 2.0 起步(1) 腳手架工具 vue-cli + Webstorm 2016 + webpack
vue-router官方文檔
如果你是克隆git里源碼的,注意工程目錄名是vue-tutorial/,步驟:http://www.itdecent.cn/p/b3c76962e3d4
Github: https://github.com/kevinqqnj/vue-tutorial
請(qǐng)使用新的template: https://github.com/kevinqqnj/flask-template-advanced
什么是組件?
下面引自官網(wǎng):
組件(Component)是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。它提供了一種抽象,讓我們可以用獨(dú)立可復(fù)用的小組件來(lái)構(gòu)建大型應(yīng)用。如果我們考慮到這點(diǎn),幾乎任意類(lèi)型的應(yīng)用的界面都可以抽象為一個(gè)組件樹(shù):

目標(biāo):搭架一個(gè)SPA應(yīng)用 - “簡(jiǎn)讀 - 微信公眾號(hào)RSS”
公眾號(hào)平常是在微信里閱讀,經(jīng)常會(huì)給微信消息打斷,所以希望有一個(gè)不被打擾,能個(gè)人定制的安靜閱讀環(huán)境。
最終完成是這樣子的:
開(kāi)發(fā)步驟:
- 劃分功能區(qū)域 (本篇)
- 對(duì)應(yīng)每個(gè)區(qū)域,創(chuàng)建相應(yīng)的組件(component) (本篇)
- vue-router 管理各個(gè)組件的動(dòng)態(tài)加載 (本篇)
- 管理數(shù)據(jù)流vuex和LocalStorage 起步(3)
- 與后臺(tái)服務(wù)器端(Flask)的交互 - 用戶注冊(cè)及登錄 起步(4)
- 與后臺(tái)服務(wù)器端(Flask)的交互 - 數(shù)據(jù)持久化 起步(5)
UI選擇
一個(gè)吸引人的應(yīng)用,漂亮的UI是必須滴。
- 桌面應(yīng)用,適合入門(mén)的是 Bootstrap,最新是 4.0Alpha
- 手機(jī)端應(yīng)用,推薦 Material UI對(duì)應(yīng)于 Vue2.0的 Muse-UI,或element。
# 安裝
cnpm install bootstrap@4.0.0-alpha.5 -S
cnpm install font-awesome -S
1. 劃分功能區(qū)域
頂部是導(dǎo)航條【1】 -- NavBar
右側(cè)是狀態(tài)欄【2】 -- SideBar
左側(cè)是內(nèi)容展示【3】 -- Content (由路由決定)
如果安裝了 vue-devtools,會(huì)在Chrome里清晰地顯示各個(gè)組件的關(guān)系。
現(xiàn)在,我們?cè)?App.vue里定義整體框架:里面包含 Navbar, Sidebar和一個(gè)動(dòng)態(tài)路由View。
<router-view></router-view> 看不懂沒(méi)關(guān)系,下面 vue-router馬上講到。現(xiàn)在你可以把這一行認(rèn)為是一個(gè)組件 <home></home>。
/src/App.vue
<template>
<div id="app">
<div class="container">
<nav class="navbar navbar-dark bg-inverse navbar-fixed-top">
<router-link to="/" class="navbar-brand text-success"> 簡(jiǎn)讀</router-link>
<ul class="nav navbar-nav">
<li class="nav-item">
<router-link to="/home" class="nav-link"><i class="fa fa-home"></i> Home</router-link>
</li>
<li class="nav-item">
<a class="nav-link" href="#"><i class="fa fa-flag"></i> Hot</a>
</li>
</ul>
<form class="form-inline float-xs-right">
<input class="form-control" type="text" placeholder="搜索公眾號(hào)/文章">
<router-link to="/search"><i class="fa fa-search btn btn-outline-success" @click=""></i></router-link>
<i class="fa fa-user-o btn btn-outline-success"></i>
</form>
</nav>
</div>
<div class="container" style="margin-top: 80px">
<div class="row">
<div class="col-xs-12 col-md-3 push-md-9 col-xl-3 push-xl-9">
<sidebar></sidebar>
</div>
<div class="col-xs-12 col-md-9 pull-md-3 col-xl-9 pull-xl-3">
<router-view></router-view>
</div>
</div>
</div>
</div>
</template>
<script>
import Siderbar from './components/Sidebar.vue'
export default {
components: {
'sidebar': Siderbar
}
}
</script>
2. 創(chuàng)建組件
整體框架搭好了,我們現(xiàn)在來(lái)創(chuàng)建組件:
【1 - NavBar】不需要單獨(dú)組件,已經(jīng)直接寫(xiě)入 App.vue。
【2 - SideBar】需要?jiǎng)?chuàng)建組件,而且是一直固定顯示的,所以,我們已經(jīng)在 App.vue里引用了這個(gè)組件。(下面寫(xiě)成Siderbar了,多了個(gè)“r”,謝謝xmisspuff,已改)
/src/components/Sidebar.vue
<template>
<div class="card">
<div class="card-header" align="center">
<img src="http://avatar.csdn.net/1/E/E/1_kevin_qq.jpg"
class="avatar img-circle img-responsive" />
<p><strong> 非夢(mèng)</strong></p>
<p class="card-title">1天前 閱讀</p>
</div>
<div class="card-block">
<p>
<img src="http://wx.qlogo.cn/mmhead/Q3auHgzwzM6FDWDyWSNm2AFBwFV6SFMXa20hjbFlWOyGYFQqrryIPw/0"
class="mpavatar img-circle img-responsive" />
<span class="tag tag-danger tag-pill float-xs-right">12</span>
創(chuàng)意科技生活
</p>
<p>
<img src="http://wx.qlogo.cn/mmhead/Q3auHgzwzM5VP8rbv4fBibDLRoibcezeC7aMx2qs4hfUWtw8Cp6PDZ7Q/0"
class="mpavatar img-circle img-responsive" />
<span class="tag tag-danger tag-pill float-xs-right">3</span>
科技每日推送
</p>
</div>
</div>
</template>
<style>
.avatar {
height: 75px;
margin: 0 auto;
margin-top: 10px;
margin-bottom: 10px;
}
.mpavatar {
height: 30px;
margin: 0 auto;
margin-top: 2px;
margin-bottom: 2px;
}
.img-circle {
border-radius: 50%;
}
</style>
【3 - Content】 是變化的,我們希望打開(kāi)首頁(yè)時(shí),左邊顯示主頁(yè)(Home),這是一個(gè)新組件:
/src/components/Home.vue
<template>
<div>
<div class="jumbotron">
<h1 class="display-3 text-success">簡(jiǎn) 讀</h1>
<p class="lead">微信公眾號(hào)簡(jiǎn)單閱讀器 RSS</p>
<hr class="my-2">
<p>公眾號(hào)平常是在微信里閱讀,經(jīng)常會(huì)給微信消息打斷。這里是一個(gè)不被打擾、能個(gè)人定制的安靜閱讀環(huán)境。</p>
<p class="lead">
<a class="btn btn-outline-success btn-lg" href="#" role="button">Learn more</a>
</p>
</div>
</div>
</template>
3. vue-router管理各個(gè)組件的動(dòng)態(tài)加載
路由在 main.js里定義。vue-router負(fù)責(zé)管理:路由變化時(shí),框架內(nèi)哪一塊來(lái)動(dòng)態(tài)展某個(gè)組件。
進(jìn)一步了解 vue-router,請(qǐng)查看 vue-router官方文檔
我們的規(guī)劃:
- 路由 / & /home --> 左邊頁(yè)面顯示歡迎 Home.vue
- 路由 /login --> 左邊頁(yè)面顯示登錄 Login.vue
- 路由 /mp_list --> 左邊頁(yè)面顯示所有關(guān)注公眾號(hào)清單 MpList.vue
- 路由 /mp_history --> 左邊頁(yè)面顯示某個(gè)公眾號(hào)歷史 MpHistory.vue
- 路由 /search --> 左邊頁(yè)面顯示搜索結(jié)果 Search.vue
下面,我們來(lái)添加 Home和 Search組件的路由,它們都會(huì)由 vue-router在 App.vue中動(dòng)態(tài)加載到左邊:
/src/main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
import 'bootstrap/dist/css/bootstrap.css'
import 'font-awesome/css/font-awesome.css'
import Home from './components/Home'
import Search from './components/Search'
Vue.use(VueRouter)
const routes = [{
path: '/',
component: Home
},{
path: '/home',
component: Home
},{
path: '/search',
component: Search
}]
const router = new VueRouter( {
routes
})
new Vue({
router,
...App
}).$mount('#app')
Search組件,點(diǎn)擊搜索按鈕,這個(gè)組件會(huì)被動(dòng)態(tài)掛載到左邊(原來(lái)Home組件位置):
/src/components/Search.vue
<template>
<div class="card">
<div class="card-header" align="center">
<form class="form-inline">
<input class="form-control form-control-lg wide" type="text" placeholder="搜索公眾號(hào)/文章">
<i class="fa fa-search btn btn-lg btn-outline-success" @click=""></i>
</form>
</div>
<div class="card-block">
<div class="media">
<div class="media-left imgbox">
<a class="" href="#">
<img class="media-object rounded"
src="http://dl.bizhi.sogou.com/images/2014/04/22/587880.jpg">
</a></div>
<div class="media-body">
<h4>這個(gè)導(dǎo)演的新片,每一部我必二刷</h4>
<p class="text-muted" style="margin-bottom: 0px;">
11月的時(shí)候,魚(yú)叔采訪了自己的偶像——蒂姆·波頓。并有機(jī)會(huì)提前看到了他的新片,然后寫(xiě)了一篇推文。今天電影上映,魚(yú)叔去電影院二刷。這一次,又
</p>
<p><small class="text-muted s1">
<span> <i class="fa fa-star-o fa-lg float-xs-right text-danger"></i></span>
<i class="fa fa-eye"></i> 2348 </small>
<small class="text-muted"> 獨(dú)立魚(yú)電影</small>
<small class="text-muted s2"> 1小時(shí)前</small>
</p>
</div>
</div>
<div class="media">
<div class="media-left imgbox">
<a class="" href="#">
<img class="media-object rounded "
src="http://wx.qlogo.cn/mmhead/Q3auHgzwzM6FDWDyWSNm2AFBwFV6SFMXa20hjbFlWOyGYFQqrryIPw/0">
</a></div>
<div class="media-body">
<h4>現(xiàn)在的段子,不動(dòng)腦子根本就看不懂</h4>
<p class="text-muted" style="margin-bottom: 0px;">
周末,姑媽讓我?guī)兔Ρ碚疹?歲的表弟,晚上我給他洗澡的時(shí)候,女票打來(lái)電話。因?yàn)槭植环奖隳茫烷_(kāi)了免提,她問(wèn):在做什么呢?我說(shuō)...
</p>
<p><small class="text-muted s1">
<span> <i class="fa fa-star-o fa-lg float-xs-right text-danger"></i></span>
<i class="fa fa-eye"></i> 1181 </small>
<small class="text-muted s1"> 鳳凰網(wǎng) </small>
<small class="text-muted s2"> 3小時(shí)前</small>
</p>
</div>
</div>
</div>
</div>
</template>
<style>
.form-inline .wide {
width: 80%;
}
.imgbox {
width: 100px;
height: 120px;
overflow: hidden;
}
.imgbox img{
max-width: 100px;
/*max-height: 120px;*/
}
.s1 {
margin-right: 20px;
}
.s2 {
margin-left: 20px;
}
</style>
現(xiàn)在試一下,是不是已經(jīng)看到漂亮的主頁(yè)了?再點(diǎn)一下右上角搜索按鈕,搜索結(jié)果頁(yè)面也會(huì)顯示了,注意觀察瀏覽器地址的變化:
目前,我們的應(yīng)用里,還只是一些假數(shù)據(jù)。
下一篇,我們會(huì)討論如何采集和管理數(shù)據(jù)
Vue 2.0 起步(3) 管理數(shù)據(jù)流 vuex和LocalStorage實(shí)例