指令v-if在更改选项卡时不起作用

问题描述:

我试图构建一个简单的列表系统,该系统显示不同平台的项目列表,每个平台都位于单独的选项卡上。我从零开始通过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标签上怪异。

看起来你打破了反应性的地方。 Read about Reactivity。简而言之,您不能改变数组或将一个新属性添加到已创建的对象。

例如,而不是p。编辑=真你可以做:

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

另一个关键的概念是取代数组而不是变异数组。

我建议将您的帖子移出created()并移入created()所调用的方法中,因为您可能需要重新使用它来再次拉取帖子。你也应该将帖子设置为空数组而不是未定义。

+0

非常感谢你,是的,事实上,我以某种方式打破了反应,我做了所有必要的改变,你建议,它的工作! –

+0

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