2017-01-04 58 views
1

我有一個Vue實例。Vuejs和Request:計算屬性函數不顯示GET JSON值

// create a root instance 
var app = new Vue({ 
    el: '#app', 
    data: 
    { 
     album: '', 
     artist: '', 
     link: '', 
     genre: '', 
     rating: '', 
     genres: ["Memphis Rap", "R&B\Soul", "Pop", "Vaporwave", "Alt-Lat"], 
     length: 0 
    }, 
    methods: { 
     addAlbum: function (event) { 
      this.youtubeAlbumList.push({ album: this.album, artist: this.artist, link: this.link, genre: this.genre, rating: this.rating }); 
      request.post(
       'http://localhost:3000/album', 
       { json: { album: this.album, artist: this.artist, link: this.link, genre: this.genre, rating: this.rating } }, 
       function (error, response, body) { 
        if (!error && response.statusCode == 201) { 
         console.log(body) 
        } 
       } 
      ); 
      this.length = this.youtubeAlbumList.length; 
      this.album = ''; 
      this.link = ''; 
      this.genre = 'Genre'; 
      this.rating = ''; 
     } 
    }, 
    computed: { 
     albumList: 
     { 
      get: function() { 
       request.get(
        'http://localhost:3000/album', 
        function (err, res, body) { 
         var info = JSON.parse(body); 
         //.forEach(function(obj) { console.log(obj.id); }); 
         return info; 
        } 
       ) 
      } 
     } 
    } 
}); 

我想使用Request的get方法來填充'albumList'。服務器成功返回200狀態碼。在開發工具中,我看到JSON正在返回。

enter image description here

的問題是,該名單(雖然短)沒有顯示在網頁上。生成列表,我用了以下組件:

Vue.component('album-component', { 
    template: ` 
    <div class="content"> 
      <div class="col-sm-6 col-md-4"> 
        <div class="thumbnail"> 
        <img src="#" alt="#"> 
        <div class="caption"> 
         <h3>{{x.album}}</h3> 
         <div class="message-body"> 
          <h2>Artist:&nbsp{{x.artist}}</h2> 
          <h3>Link:&nbsp<a v-bind:href="x.link">Link</a></h3> 
          <div>Genre:&nbsp{{x.genre}}</div> 
          <div>Rating:&nbsp{{x.rating}}</div> 
         </div> 
         <p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#" class="btn btn-default" role="button">Button</a></p> 
        </div> 
        </div> 
       </div> 
      </div>`, 
    props: ['album'], 
    data: function() { 
     return { 
      x:this.album 
     } 
    } 
}); 


// register 
Vue.component('youtube-album-list-component', { 
    template: `<div class="row"> 
        <album-component v-for="album in albumList" :album="album"> </album-component>   
      </div>` 
    , 
    props: ['albums'], 
    data: function() { 
     return { 
      albumList: this.albums 
     } 
    } 
}) 

而且

<div id="app"> 
     <div> 
     <div class="input-group input-group-med"> 
      <span class="input-group-addon">Album</span> 
      <input v-model="album" class="form-control" placeholder="Title"> 
     </div><br> 
     <div class="input-group input-group-med"> 
      <span class="input-group-addon">Artist</span> 
      <input type="text" class="form-control" placeholder="Name" v-model="artist"> 
     </div><br> 
     <div class="input-group input-group-med"> 
      <span class="input-group-addon">Link</span> 
      <input type="text" class="form-control" placeholder="Link" v-model="link"> 
     </div><br> 

     <div v-cloak class="input-group input-group-med"> 
      <select v-model="genre"> 
      <option v-for="genre in genres" v-bind:values="genre">{{genre}}</option> 
     </select> 
     </div> 
     <br> 
     <div class="input-group input-group-med"> 
      <span class="input-group-addon">Rating</span> 
      <input type="text" class="form-control" placeholder="Rating" v-model="rating"> 
     </div><br> 
     </div> 
     <button v-on:click="addAlbum" type="button" class="btn btn-danger btn-lg">Left</button> 
     <br> 
     <br> 
     <div> 
     <div class="page-header result-header"> 
      <h1>Album list</h1> 
     </div> 
     </div> 
     <youtube-album-list-component :albums="albumList"></youtube-album-list-component> 
    </div> 

我試圖通過計算albumList在我的YouTube專輯列表組分作爲道具中的index.html 。然後使用該列表創建相冊組件。我試圖找出原因,儘管info變量有一個返回的數組,但它沒有被渲染。有任何想法嗎?

+0

屬性,計算或其他,不能是異步。 –

+0

@MathewJibin Vuejs通常如何處理渲染異步數據?我是否必須使用[vue-async-computed](https://github.com/foxbenjaminfox/vue-async-computed)來實現這一目標? – TYMG

+1

您必須調用一個操作來請求異步資源,或者您可以在vue組件的任何生命週期事件掛鉤中執行該操作,然後設置一個支持屬性。如果沒有進一步處理,您可以綁定到其他屬性,您可以使用計算屬性,該屬性將根據支持屬性自動更新。 –

回答

2

你可以重新設計這樣的東西, 基本上你會有一個屬性來保存你的列表在組件的data屬性,你用ajax更新它,然後轉換並公開你的計算屬性。

Vue.component('album-component',{ 
template:"#album-template", 
props: ['album'] 
}); 

Vue.component('youtube-album-list-component', { 
template:"#youtube-list-template", 
props: ['albums',"isLoading"] 
}); 



var app = new Vue({ 
    el: '#app', 
    data: 
    { 
     album: '', 
     artist: '', 
     link: '', 
     genre: '', 
     rating: '', 
     genres: ["Memphis Rap", "R&B\Soul", "Pop", "Vaporwave", "Alt-Lat"], 
     length: 0, 
     albumStore:[], //This will be your backing store 
     limit:2, 
     isBusy:true 
    }, 
    created:function(){ 
     var me=this; 

     //*********REPLACE WITH YOUR AJAX CALL HERE********* 

     //moke a ajax request 
     setTimeout(function(){ 
     me.albumStore.push.apply(me.albumStore,[ 
     {album:"Album 1",artist:"Artist 1",genre:"Pop",rating:4}, 
     {album:"Album 2",artist:"Artist 1",genre:"Vaporwave",rating:3}, 
     {album:"Album 3",artist:"Artist 1",genre:"Memphis Rap",rating:5}, 
     ]); 
     me.isBusy=false; 
     },3000); 
    }, 
    methods: { 
     addAlbum: function (event) { } 
    }, 
    computed: { 
     albumList: 
     { 
      get: function() { 
        //do some for loop or $.map processing here and return the result. 
        var list=[]; 
        for(var i=0; i<this.limit && i < this.albumStore.length;i++) 
        { 
        list.push(this.albumStore[i]); 
        } 

        return list; 
       } 
     } 
    } 
}); 

正在工作fiddle is here。添加功能沒有完成,您可以在此基礎上構建或根據自己的喜好進行調整。

+0

我認爲「支持商店」通常被稱爲「初始價值」,它更簡單易懂。 –

+0

謝謝。我現在明白'備份店'的含義。在發佈我的問題後,我開始使用'before created'生命週期事件來進行異步調用。它工作得很好,但不如你的答案。最後一個問題:我認爲顯示異步數據並不是框架的一個不尋常的問題,是我還是這個功能是Vuejs的弱點? – TYMG

+1

對不起,我的主要堆棧是c#的.net,它被稱爲屬性:)的後臺字段。這不是一個弱點,但這是通常推薦的方式,具有默認值的屬性,當新值可用時會更新。 vue中的計算屬性用於對已有數據進行轉換,而不用於異步操作。對於複雜的場景,請查看[Vuex](https://github.com/vuejs/vuex),但如果你是初學者,我建議在考慮vuex之前首先熟悉vue的做法。 –

2

計算屬性不能異步,你不能稱之爲從它的API,因爲這是異步的,你可以寫在方法的代碼,它應該工作:

methods: { 
     albumList: 
     { 
      get: function() { 
       request.get(
        'http://localhost:3000/album', 
        function (err, res, body) { 
         var info = JSON.parse(body); 
         //.forEach(function(obj) { console.log(obj.id); }); 
         return info; 
        } 
       ) 
      } 
     } 

如果你是堅定的或有這是一個強大的使用情況,只有在計算屬性中使用這種情況,才能使用像vue-async-computed這樣的東西,這使得可以在Vue中計算異步計算的屬性。

但我確定使用方法應該是非常好的。

+0

我試過這個解決方案,但之後,雖然albumList仍然被傳入列表組件,但get函數沒有被調用。但我會研究vue-async-computed模塊。 – TYMG

+0

@TYMG任何具體的原因,你不希望ti使用方法,因爲這是做它的vue方式? – Saurabh

+0

我試過使用Vue提供的方法,但我認爲我錯誤地使用了它們。我將嘗試MatthewJbin的解決方案,因爲它不需要外部庫。 – TYMG