1. 程式人生 > >Vue.js2.0從入門到放棄---入門例項(三)

Vue.js2.0從入門到放棄---入門例項(三)

已經有幾周沒有更新部落格了,最近自己也在學習就沒有能及時抽身來寫部落格。

今天就來簡單說一下vue-resource,這是vue的一個與伺服器端通訊的HTTP外掛,用來從伺服器端請求資料。話不多說,直接上乾貨吧。

這裡PS一下,有人反映之前的程式碼下載下來,執行會報錯而且會有上百個之多,這是因為在我初始化專案的時候沒有啟用eslint,eslint是用來檢測程式碼風格的,我是覺得格式要求嚴的有點過分,所以禁用了eslint。如果對eslint感興趣的朋友,可以看 eslint的官網 瞭解一下格式的要求和一些相應的配置。

我們主要來了解一下以下內容:

  • 模擬服務端返回資料
  • 用vue-resource向伺服器請求資料

模擬伺服器返回資料

我們用vue-cli建立的專案中,已經給我們提供了模擬伺服器端返回資料的地方和介面。如下圖所示,在專案目錄的build目錄下,有一個dev-server.js,在這個檔案中,我們就可以來做一些模擬資料的工作。

1、準備一個data.json檔案

在專案根目錄下,新建一個data.json。這個檔案裡的內容就是我們要模擬的服務端返回的資料。 data.json的內容如下:
{
	"books": [
	    { "price": "111.00", "title": "語文", "img": "http://imgsrc.baidu.com/forum/w%3D580/sign=688d19b6422309f7e76fad1a420f0c39/0e143912b31bb051dfdebf0a327adab44bede0f9.jpg" },
	    { "price": "123.00", "title": "數學", "img": "http://shopimg.kongfz.com.cn/20130826/1746508/1746508YTGtm0_b.jpg"},
	    { "price": "113.00", "title": "英語", "img": "http://www.shiyi910.com/UploadFiles/2014-01/170/2014011322414554305.jpg"},
	    { "price": "112.00", "title": "物理", "img": "http://f.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=b62ac53d4b36acaf59b59ef849e9a126/f603918fa0ec08fa2cf895a359ee3d6d55fbda3e.jpg"}
	]
}
這裡,books欄位裡的每一個物件表示一本書的資訊。

2、“寫介面”

修改dev-server.js檔案,在大概第19行左右的 var app = express()之後,新增上如下內容
var appData = require('../data.json')
var books = appData.books

var apiRoutes = express.Router()
apiRoutes.get('/books', function(req, res){
  res.json({
    data: books
  })
})

app.use('/api', apiRoutes)

簡單說明一下,這段程式碼就是通過請求醒目根目錄下的data.json檔案,拿到檔案的內容並賦值給appData變數,取到裡面的books欄位內容儲存在books變數中。然後,通過express提供的Router物件,以及Router物件的一些方法(這裡是get方法)來設定請求的路徑,以及請求成功後的回撥函式來處理要返回給請求端的資料。最後,我們要“使用”這個Router物件,為了統一管理api介面,我們在要請求的路由前邊都加上‘api/’來表明這個路徑是專門用來提供api資料的。在這個“介面”中,當我們訪問“http://localhost:8080/api/books”路徑的時候,就會返回data.json裡的books物件給我們。 這裡我們先來簡單驗證一下是否能成功返回資料,開啟命令列,cd到當前專案目錄,執行 npm run dev ,等專案執行成功之後,在瀏覽器位址列輸入http://localhost:8080/api/books,看到如下圖所示,資料正常返回,OK!“介面”就開發完成了。 PS:在你的瀏覽器上可能看到的是沒有經過格式化的資料,我的瀏覽器上裝了一個json格式化的外掛,這不是重點,重點是“介面”正常工作了,不是嗎得意

用vue-resource向伺服器請求資料

1、安裝vue-resource

開啟命令列,cd到專案目錄,執行 npm install vue-resource --save或者cnpm install vue-resource --save,等待安裝完成即可。

2、在main.js裡匯入並使用vue-resource

修改main.js如下
// main.js

// 匯入Vue,這個是必需的,在使用Vue之前,必須先匯入
import Vue from 'vue'

// 匯入 vue-router,並使用
import VueRouter from 'vue-router'
Vue.use(VueRouter)

// 匯入 vue-resource,並使用
import VueResource from 'vue-resource'
Vue.use(VueResource)

// 匯入 pages 下的 Home.vue 
import Home from './pages/Home'
import Detail from './pages/Detail'

// 定義路由配置
const routes = [
	{
		path: '/',
		component: Home
	},
	{
		path: '/detail',
		component: Detail
	}
]

// 建立路由例項
const router = new VueRouter({
	routes
})

// 建立 Vue 例項
new Vue({
  el: '#app',
  data(){
  	return {
  		transitionName: 'slide'
  	}
  },
  router,
  watch: {
  	// 監視路由,引數為要目標路由和當前頁面的路由
  	'$route' (to, from){
  		const toDepth = to.path.substring(0, to.path.length-2).split('/').length
  		// 官方給出的例子為 const toDepth = to.path.split('/').length 由於現在只有兩個路由路徑'/'和'/detail'
  		// 按照官方給的例子,這兩個路由路徑深度都為 2 ,所以,這裡稍作調整,不知道有什麼不妥
  		// 但目前在這個demo中能正常執行,如果知道更好的方法,歡迎留言賜教
  		const fromDepth = from.path.substring(0, from.path.length-2).split('/').length
  		this.transitionName = toDepth < fromDepth ? 'slide_back' : 'slide'
  		// 根據路由深度,來判斷是該從右側進入還是該從左側進入
  	}
  }
})

3、修改Home.vue和List.vue來接收服務端返回的資料

Home.vue修改如下:
<!-- Home.vue -->
<template>
	<div class="container">
		<!-- 由於html不區分大小寫,所以js中駝峰命名方式在html中要改成用短橫線連線的形式 -->
		<home-header></home-header>
		<div class="content">
			<ul class="cont_ul">
				<list
					v-for="item in items"
					:price="item.price"
					:title="item.title"
					:img="item.img">
				<!-- 通過v-bind(簡寫為“:”)繫結props來從父元件給子元件傳值 -->
				</list>
			</ul>
		</div>
	</div>
</template>
<style>
	.container {
		max-width: 640px;
		margin: 0 auto;
		overflow-x: hidden;
	}
	.cont_ul {
		padding-top: 0.05rem;
		margin: 0 -0.12rem;
	}
	.cont_ul:after {
		content: "";
		display: block;
		width: 0;
		height: 0;
		clear: both;
	}
</style>
<script>
	// 匯入要用到的子元件
	import HomeHeader from '../components/HomeHeader'
	import List from '../components/List'
	export default {
		data () {
			return {
				items: []
			}
		},
		// 在components欄位中,包含匯入的子元件
		components: {
			HomeHeader,
			List
		},
		// 在元件建立完成時,執行的鉤子函式
		created (){
			// 在main.js裡匯入並使用vue-resource之後,就可以通過this.$http來使用vue-resource了,這裡我們用到了get方法
			this.$http.get('/api/books').then((data) => {
				// 由於請求成功返回的是Promise物件,我們要從data.body.data拿到books陣列
				this.items = data.body.data;
			})
		}
	}
</script>


List.vue修改如下:
<!-- List.vue -->
<template>
	<li class="sec_li">
		<router-link to="/detail" class="lp_li_a">
			<div class="lp_li_imgWrap">
				<img :src="img" alt="">
			</div>
			<p class="lp_li_name">{{ title }}</p>
			<p class="lp_li_price">¥{{ price }}元</p>
		</router-link>
	</li>
</template>

<style scoped>
	.sec_li {
		float: left;
		width: 50%;
		margin-bottom: 0.1rem;
	}
	.lp_li_a {
		display: block;
		padding: 0.3rem 0;
		margin: 0 0.05rem;
		text-align: center;
		background: #fff;
	}
	.lp_li_imgWrap {
		padding: 0.24rem 0;
	}
	.lp_li_imgWrap > img {
		width: auto;
		height: 2.3rem;
	}
	.lp_li_name {
		height: 0.5rem;
		line-height: 0.5rem;
		font-size: 16px;
		color: #333;
	}
	.lp_li_price {
		height: 0.5rem;
		line-height: 0.5rem;
		font-size: 16px;
		color: #fb3b3b;
	}
</style>

<script>
	export default {
		// 接收父元件傳過來的以下幾個屬性
		props: ['price', 'title', 'img'],
	}
</script>

然後,再回到瀏覽器,應該會看到如下圖的效果了。
搞定!資料成功接入,可以來杯咖啡放鬆一下,回味一下整個過程的實現了。 還有一個“/detail”介面,就是每本書的詳情,我著急下班,就先不寫了。前面是我拋磚,後邊的引玉部分,你可以自己嘗試著來實現,你可以的! 我要下班了,如果沒有練習原始碼的同學,看上一篇部落格,裡面有github地址。好了,撤!