我正在尝试构建一个简单的列表系统,该系统显示不同平台的项目列表,每个平台都位于单独的选项卡上。我从头开始通过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标签上很奇怪。
答案 0 :(得分:1)
看起来你在某个地方打破了反应。 Read about Reactivity。简而言之,您不能改变数组或向已创建的对象添加新属性。
例如,您可以执行以下操作:
,而不是p.editing = truethis.$set(p, 'editing', true)
另一个关键概念是替换数组而不是改变数组。
我建议将你的帖子从created()转移到created()调用的方法中,因为你可能想重复使用它来再次提取帖子。您还应将帖子设置为空数组而不是未定义。