2017-08-29 73 views
2

我試圖構建一個簡單的列表系統,該系統顯示不同平臺的項目列表,每個平臺都位於單獨的選項卡上。我從零開始通過VueJS創建了標籤切換邏輯。指令v-if在更改選項卡時不起作用

我在做什麼

基本上我有兩個平臺:Twitter和Facebook上的標籤之一,當用戶點擊,前端發送一個Ajax請求到我的服務器,以獲取該平臺帖並通過v-for呈現它們。

我爲每個帖子添加了一個按鈕edit,當用戶按下它時,它調用一個函數edit(p),其中p是用戶想要編輯的當前帖子。

in edit(p)我更改了atrribute p.editing,它使用v-if顯示文本區域和timepicker(我使用的是flatpicker)。

什麼錯:

所有時,我第一個選項卡上,但一旦我切換選項卡,它停止工作,調試後我發現,V型,如果不工作的事件P此工作正常當編輯(p)被稱爲.editing被更新,下面的代碼:

var posts_app = new Vue({ 
    el: "#posts_app", 
    data: { 
     platforms : ['facebook','twitter'], 
     current_tab: { 
      'facebook' : true, 
      'twitter': false 
     }, 
     platform_posts: { 
      'facebook': [], 
      'twitter': [] 
     }, 
     posts: undefined, 
    }, 
    methods:{ 
     showTab: function(i){ 
      platform = this.platforms[i] 
      // UI stuff : to make the clicked tab active 
      for(p in this.current_tab){ 
       if(p == platform){ 
        this.current_tab[p] = true 
       } 
       else{ 
        this.current_tab[p] = false 
       } 
      } 
      // Show content by platform 
      this.posts = this.platform_posts[platform] 
     }, 
     edit: function(p){ 
      p.editing = true 
      console.log(p) 
      Vue.nextTick(function(){ 
       document.getElementsByClassName("dt-input")[0].flatpickr({enableTime : true}); 
      }) 
     }, 
     save: function(p){ 
      p.editing = false 
     } 
    }, 
    created(){ 
     self = this 
     posts_loaded = false 

     for(var i = 0;i < this.platforms.length; i++){ 
      (function(index){   
       self.$http.get('/fan/posts',{params:{platform : self.platforms[index]}}).then(function(resp){ 
       self.platform_posts[self.platforms[index]] = resp.body 
       posts_loaded = true 

      })//Promise of Ajax call 
      }// Closure body 
      )(i)//Closure 
     } 

     this.showTab(0) 
    }, 
    delimiters: ['[[',']]'] 

}) 

和我的基本HTML模板:

<div class = "panel-body"> 
     <img class = "pull-right responsive" v-bind:src = "p.image"/> 
     <textarea v-if = "p.editing" class = "post-text-input" v-model = "p.text"></textarea> 
     <p class = "post-text" v-if = "!p.editing">[[p.text]]</p> 
     <p class = "post-source" v-if = "p.type == 'article'"> Source : [[post_source(p)]]</p> 
     <p class = "post-time"><b>Scheduled on <i v-if = "!p.editing">[[p.time]] </i></b> 
      <input placeholder="Choose a date and a time" class = "flatpickr dt-input" v-model = "p.time" v-if = "p.editing" /> 
     </p> 

     </div> 
     <div class = "panel-footer clearfix"> 
     <button class = "btn btn-danger">Delete</button> 
     <button class = "btn btn-info pull-right" @click = "edit(p)" v-if = "!p.editing">Edit</button> 
     <button class = "btn btn-success pull-right" @click = "save(p)" v-if = "p.editing">Save</button> 

     </div> 

代碼解釋:

所以,當點擊選項卡時,showTab(指數)被稱爲其中index爲標籤的數量,如果指數爲0,那麼我們跳槽到Facebook選項卡,如果是1,那麼我們在twitter標籤,我們發送一個AJAX請求來獲取當前平臺(標籤)的帖子,並將其填充到platform_posts [current_platform]中,然後通過v-for呈現它們。所有這一切都像一個魅力。

第二部分,當用戶點擊某個文章的編輯按鈕時,它使用v-model替換texttarea的文本段落元素以跟蹤更改並更新具有充當日期時間選擇器的輸入的時間段落通過flatpickr庫。基本上,這可以LIB使用這行代碼把任何輸入到日期時間pickr:

elemnt.flatpickr({config_options})

當元件是一個HTML元素。您可以注意到我正在使用Vue.nextTick,這是爲了確保輸入不再隱藏(不應該因爲p.editing已更新)。當我在第一個選項卡上時,所有這些工作都像一個魅力,問題是當我切換選項卡時它停止工作。

這裏有一個GIF我做給你看的錯誤:http://imgur.com/a/QME4P

正如你所看到的,行爲是非常奇怪的,它完美Twitter的標籤,它是Facebook標籤上怪異。

回答

1

看起來你打破了反應性的地方。 Read about Reactivity。簡而言之,您不能改變數組或將一個新屬性添加到已創建的對象。

例如,而不是p。編輯=真你可以做:

this.$set(p, 'editing', true) 

另一個關鍵的概念是取代數組而不是變異數組。

我建議將您的帖子移出created()並移入created()所調用的方法中,因爲您可能需要重新使用它來再次拉取帖子。你也應該將帖子設置爲空數組而不是未定義。

+0

非常感謝你,是的,事實上,我以某種方式打破了反應,我做了所有必要的改變,你建議,它的工作! –

+0

很高興你的工作!我對Vue的最大提示是,如果某些東西不起作用,首先要注意的是打破反應。 –