指令v-if在更改标签

时间:2017-08-29 13:43:21

标签: javascript vue.js

我正在尝试构建一个简单的列表系统,该系统显示不同平台的项目列表,每个平台都位于单独的选项卡上。我从头开始通过VueJS创建了标签切换逻辑。

我正在做什么

基本上我有两个平台:twitter和facebook,当用户点击其中一个标签时,前端会向我的服务器发送ajax请求以获取该平台的帖子并通过v-for呈现它们。

我为每个帖子添加了一个名为edit的按钮,当用户按下它时,它会调用一个函数edit(p),其中p是用户想要编辑的当前帖子。

编辑中的

(p)我更改了一个属性,使用v-if为该帖子显示了一个文本区域和一个时间戳(我使用flatpicker)。

错误:

当我在第一个选项卡上时,所有这一切都正常工作,但是一旦我切换选项卡,它就会停止工作,经过调试我注意到v-if不工作事件p.editing在编辑时更新(p )被称为,这里是代码:

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),其中index是tab的数量,如果index为0,那么我们切换到facebook选项卡,如果它是1,那么我们就是在twitter选项卡中,我们发送一个AJAX请求来获取当前平台(tab)的帖子并将其填入platform_posts [current_platform],然后我们通过v-for渲染它们。所有这一切都像一个魅力。

第二部分,当用户点击给定帖子的编辑按钮时,它使用v-model将文本段落元素替换为textarea以跟踪更改并使用输入更新时间段落,该输入充当日期时间选择器flatpickr图书馆。基本上这个lib可以使用以下代码行将任何输入转换为日期时间选择器:

elemnt.flatpickr({config_options})

其中element是HTML元素。您可以注意到我正在使用Vue.nextTick,这是为了确保输入不再被隐藏(不应该更新p.editing)。当我在第一个标签上时,所有这些都像魅力一样,问题是当我切换标签时它停止工作。

这是我用来向您展示错误的gif: http://imgur.com/a/QME4P

正如你所看到的,这种行为非常奇怪,它在twitter标签上完美运行,而且在facebook标签上很奇怪。

1 个答案:

答案 0 :(得分:1)

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

例如,您可以执行以下操作:

,而不是p.editing = true
this.$set(p, 'editing', true)

另一个关键概念是替换数组而不是改变数组。

我建议将你的帖子从created()转移到created()调用的方法中,因为你可能想重复使用它来再次提取帖子。您还应将帖子设置为空数组而不是未定义。