vue-resource 小抄

1000copy發表於2016-12-05

vue.js本身沒有提供網路訪問能力,但是可以通過外掛完成。vue-resource就是這樣一個不錯的外掛。它封裝了XMLHttpRequest和JSONP,實現非同步載入服務端資料。

我們現在搭建一個測試環境,由伺服器提供json資料,啟動後等待客戶端的請求。資料為user資訊,內容為:

var users = [
   {"name" : "1"},
   {"name" : "2"},
   {"name" : "3"},
]

我們首先從最簡單的GET方法入手,場景如下:

  1. 客戶端使用HTTP GET方法來訪問/users

  2. 服務端返回整個json格式的user

  3. 客戶端檢查返回的結果,和期望做驗證

我使用瞭如下庫: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,就表明我們的程式碼和期望是一致的。

相關文章