vue.js本身沒有提供網路訪問能力,但是可以通過外掛完成。vue-resource就是這樣一個不錯的外掛。它封裝了XMLHttpRequest和JSONP,實現非同步載入服務端資料。
我們現在搭建一個測試環境,由伺服器提供json資料,啟動後等待客戶端的請求。資料為user資訊,內容為:
var users = [
{"name" : "1"},
{"name" : "2"},
{"name" : "3"},
]
我們首先從最簡單的GET方法入手,場景如下:
-
客戶端使用HTTP GET方法來訪問/users
-
服務端返回整個json格式的user
-
客戶端檢查返回的結果,和期望做驗證
我使用瞭如下庫:express.js做HTTP Server,且它本身就已經提供了GET方法監聽的內建支援
首先初始化專案,並安裝依賴:
npm init
npm i express –save
然後建立index.js檔案,內容為:
var express = require(`express`);
var app = express();
var path = require(`path`)
var public = path.join(__dirname, `public`)
app.use(`/`,express.static(public))
var users = [
{"name" : "1"},
{"name" : "2"},
{"name" : "3"},
]
app.get(`/users`, function (req, res) {
res.end( JSON.stringify(users));
})
var server = app.listen(8080, function () {
var host = server.address().address
var port = server.address().port
console.log("listening at http://%s:%s", host, port)
})
程式碼行:
var public = path.join(__dirname, `public`)
app.use(`/`,express.static(public))
則是指明執行後,客戶端url的根目錄指向的是伺服器的public目錄內。此目錄用來放置靜態檔案,html+js+css等。程式碼行:
app.get(`/users`, function (req, res) {
res.end( JSON.stringify(users));
})
會監聽對/users的GET請求,如果發現請求到來,就會呼叫回撥函式,並在在req、res內傳遞Request物件和Response物件。我們在res物件內把users物件做一個字串化,然後由res物件傳遞給客戶端。
客戶端訪問程式碼:
<script src="https://unpkg.com/vue@2.0.6/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/vue.resource/1.0.3/vue-resource.min.js"></script>
<div id="app">
{{msg}}
</div>
<script>
var app = new Vue(
{
el:`#app`,
data:{
msg:`hello`
},
mounted(){
this.$http.get(`/users`).then((response) => {
var j = JSON.parse(response.body)
console.log(j.length == 3,j[0].name == `1`,j[1].name == `2`,j[2].name == `3`)
}, (response) => {
console.log(`error`,response)
});
}
})
</script>
現在啟動伺服器:
node index.js
訪問
localhost:8080
在控制檯內發現:
true true true true
列印出來的結果全部為true,就表明我們已經完整的取得了users物件,因為我們的程式碼和期望是一致的。
對於GET類的HTTP請求方法,這樣做就OK了。另外幾種請求方法,監聽的做法是類似的。不同的地方,主要是客戶端可能會傳遞json過來到伺服器,比如POST方法,可以用來新增一個user,此時就需要客戶端傳遞一個JSON物件過來,伺服器則需要解析JSON物件。此時有一個庫可以幫我們做這件事,它就是body-parser庫。程式碼:
var bodyParser = require(`body-parser`)
app.use(bodyParser.json())
把body-parser庫的.json()作為外掛,插入到express內,這樣我們就可以使用:
response.body
取得客戶端發來的json物件了。
完整程式碼如下(index.js):
var express = require(`express`);
var app = express();
var path = require(`path`)
var bodyParser = require(`body-parser`)
app.use(bodyParser.json())
var public = path.join(__dirname, `public`)
app.use(`/`,express.static(public))
var users = []
function rs(){
users = [
{"name" : "1"},
{"name" : "2"},
{"name" : "3"},
]
}
rs()
app.put(`/user/:id`, function (req, res) {
var userkey = parseInt(req.params.id)
users[userkey] = req.body
res.end( JSON.stringify(users));
rs()
})
app.delete(`/user/:id`, function (req, res) {
var userkey = parseInt(req.params.id)
users.splice(userkey,1)
res.end( JSON.stringify(users));
rs()
})
app.get(`/user/:id`, function (req, res) {
var userkey = parseInt(req.params.id)
res.end( JSON.stringify(users[userkey]));
})
app.get(`/users`, function (req, res) {
res.end( JSON.stringify(users));
})
app.post(`/user`, function (req, res) {
users.push(req.body)
res.end(JSON.stringify(users))
rs()
})
var server = app.listen(8080, function () {
var host = server.address().address
var port = server.address().port
console.log("listening at http://%s:%s", host, port)
})
這段伺服器的程式碼,提供了對5個url的監聽,其中兩個是GET方法,一個POST,一個PUT,一個DELETE。其中的rs()函式有些特別,目的是為了測試方便。它讓每個會修改資料物件的方法執行後都可以恢復原狀,以便供其他客戶端訪問前都和初始值是一樣的。
node index.js
此時伺服器已經就緒,等待客戶端的連線。然後是客戶端檔案index.html。此時vue-resource派上用場。使用vue-resource首先需要載入vue.js,然後載入自己。我們偷個懶,就不下載這些程式碼到本地,而好似直接使用網路上現成的程式碼:
<script src="https://unpkg.com/vue@2.0.6/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/vue.resource/1.0.3/vue-resource.min.js"></script>
完整程式碼如下:
<script src=”https://unpkg.com/vue@2.0.6/d…
<script src="https://cdn.jsdelivr.net/vue.resource/1.0.3/vue-resource.min.js"></script>
<div id="app">
{{msg}}
</div>
<script>
var app = new Vue(
{
el:`#app`,
data:{
msg:`hello`
},
mounted(){
this.a()
this.b()
this.c()
this.d()
this.e()
},
methods:{
a(){
this.$http.get(`/users`).then((response) => {
var j = JSON.parse(response.body)
console.log(`getall`,j.length == 3,j[0].name == `1`,j[1].name == `2`,j[2].name == `3`)
}, (response) => {
console.log(`error`,response)
});
},
b(){
this.$http.get(`/user/0`).then((response) => {
var j = JSON.parse(response.body)
console.log(`getone`,j.name == `1`)
}, (response) => {
console.log(`error`,response)
});
},
c(){
this.$http.put(`/user/0`,{name:`1111`}).then((response) => {
var j = JSON.parse(response.body)
console.log(`put`,j.length == 3,j[0].name == `1111`)
}, (response) => {
console.log(`error`,response)
});
},
d(){
this.$http.post(`/user`,{name:`4`}).then((response) => {
var j = JSON.parse(response.body)
// console.log(j)
console.log(`post`,j.length == 4,j[3].name == `4`)
}, (response) => {
console.log(`error`,response)
});
},
e(){
this.$http.delete(`/user/2`).then((response) => {
var j = JSON.parse(response.body)
// console.log(j)
console.log(`delete`,j.length == 2)
}, (response) => {
console.log(`error`,response)
});
}
}
})
</script>
最後,列印出來的結果全部為true,就表明我們的程式碼和期望是一致的。