我一直在解决一个问题,在嵌套的v-for
循环内部,一个简单的v-show
指令正朝着 4秒实际应用DOM中的display: none;
属性。
基本布局是这样的。我已将实际命名改为汽车;因为为什么不呢!
我为代码墙道歉,但我觉得包含组件结构的基本要点是相关的。
<div class="vehicle-history" v-if="fetchComplete && !fetchError">
<h3 class="header-bold">History</h3>
<div class="history-container" v-for="car in vehicles.cars" :key="car.id">
<div class="vehicle-header">
<div class="toyota" v-if="car.model == 'toyota'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
<div class="audi" v-if="car.model == 'audi'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
<div class="benz" v-if="car.model == 'benz'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
<div class="rolls" v-if="car.model == 'rolls'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div><br />
<small v-for="color in car.colors">@{{ color.name }} </small>
</div>
<div class="vehicle-body">
<div class="description">@{{ car.description }}</div>
<div class="review-container" v-if="car.reviews.length > 5">
<div class="review" v-for="n in (0, 4)" :key="car.reviews[n].id">
<strong>@{{ car.reviews[n].rating }}</strong> - @{{ car.reviews[n].content }}<br />
<small>@{{ car.reviews[n].created_at.date }} @{{ car.reviews[n].created_at.timezone }}</small>
<span v-show="n == 4 && !car.displayFull"><br />
<button type="button"
class="btn btn-link"
data-toggle="collapse"
v-on:click="car.displayFull = true"
v-bind:data-target="'#expanded-reviews-' + car.id">More details
</button>
</span>
</div>
<div class="collapse" v-bind:id="'expanded-reviews-' + car.id">
<div class="review" v-for="n in (4, car.reviews.length-1)" :key="car.reviews[n].id">
<strong>@{{ car.reviews[n].rating }}</strong> - @{{ car.reviews[n].content }}<br />
<small>@{{ car.reviews[n].created_at.date }} @{{ car.reviews[n].created_at.timezone }}</small>
<span v-if="n == car.reviews.length-1"><br />
<button type="button"
class="btn btn-link"
data-toggle="collapse"
v-on:click="car.displayFull = false"
v-bind:data-target="'#expanded-reviews-' + car.id">Less details
</button>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
我尝试了什么
:key
添加到相关循环v-show
属性从按钮(原来位于此处)移动到父级别。<keep-alive>
(根本不起作用,整体上打破了知名度)v-show
交换v-if
,反之亦然预期输出
我想要完成的是确保按钮为&#34;更多细节&#34;在手风琴扩展时隐藏起来(也就是说,当最初点击&#34;更多细节&#34;按钮时),并且如果&#34; Less details&#34;单击按钮。
实际输出
虽然它完成了上述操作,但是从单击按钮到在DOM中应用display: none;
属性的延迟时间为2-5秒。然而,对Vue变量的更改似乎是即时的。
您是否知道为什么会这样,如果有一个好的解决方法呢?谢谢你,一如既往!
更新
根据一些建议修改了以下代码示例。这是现有代码的扁平副本,因此这次没有更改命名。
<div class="incident-history text-center col-xs-12 padding-bottom" v-if="fetchComplete && !fetchError">
<h3 class="heading3 black-text">Incident History</h3>
<div class="incident-container" v-for="incident in responseData.incident.resolved" :key="incident.id">
<div class="incident-header">
<div :class="'title-' + incident.classification">
<span class="incident-id">@{{ incident.type }}_@{{ incident.id }}</span> - @{{ incident.title }}
</div><br />
<small v-for="monitor in incident.monitors">@{{ monitor.name }} </small>
</div>
<div class="incident-body">
<div class="description">@{{ incident.content }}</div>
<div class="update" v-for="(comment, index) in incident.comments.slice(0,5)">
<strong>@{{ comment.type }}</strong> - @{{ comment.content }}<br />
<small>@{{ comment.created_at.date }} @{{ comment.created_at.timezone }}</small>
</div>
<div class="collapse"
v-bind:id="'expanded-update-' + incident.id"
v-if="incident.comments.length > 4">
<div class="update" v-for="(comment, index) in incident.comments.slice(5)">
<strong>@{{ comment.type }}</strong> - @{{ comment.content }}<br />
<small>@{{ comment.created_at.date }} @{{ comment.created_at.timezone }}</small>
</div>
</div>
<button type="button"
class="btn btn-link"
data-toggle="collapse"
v-show="incident.comments.length > 4 && !incident.displayFull"
v-on:click="incident.displayFull = !incident.displayFull"
v-bind:data-target="'#expanded-update-' + incident.id">Show more
</button>
<button type="button"
class="btn btn-link"
data-toggle="collapse"
v-show="incident.comments.length > 4 && incident.displayFull"
v-on:click="incident.displayFull = !incident.displayFull"
v-bind:data-target="'#expanded-update-' + incident.id">Show less
</button>
</div>
</div>
</div>
我会注意到上面的代码块是在另一个for循环中运行的。基本拓扑结构是这样的(长度可能会有所不同)
responseData: Object
incident: Object
active: Array[4]
0: Object
1: Object
Property: SomeValue
Property: SomeValue
Property: SomeValue
Property: SomeValue
Property: SomeValue
Comments: Array[3]
0: Object
1: Object
Property: SomeValue
Property: SomeValue
2: Object
2: Object
3: Object
替代解决方案
我已经想出了一个可行的,可能更好的替代方案来改变&#34;阅读更多&#34;到&#34;阅读更少&#34;反之亦然。
button.full-details[aria-expanded="true"]:after {
content: 'Show less';
}
button.full-details[aria-expanded="false"]:after {
content: 'Show more';
}
这很好用,只需要在按钮上添加几行CSS和一个类(或者以Bootstrap按钮类为目标,但由于很多原因,这并不是很好)。
那就是说,我打算稍微打开这个,希望能够理解为什么问题首先出现在Vue上。
答案 0 :(得分:1)
在显示屏上听到2-5秒滞后是令人惊讶的,但在那个模板中有相当多的进展。如果没有测试系统,很难判断建议的更改是否会影响页面视觉效果。
按钮似乎最成问题,每次评论创建一个,但每辆车只需要一个,必须评估v-show或v-if所有这些。
在评论圈外面有一个按钮,
<button class="btn btn-link" type="button"
data-toggle="collapse" :data-target="'#expanded-reviews-' + car.id"
@click="car.displayFull = !car.displayFull">
{{ buttonPrompt(car.displayFull) }}
</button>
我还考虑创建汽车子组件,甚至是评论孙子组件,因为当布局变得困难时,布局变得困难忙。
最后一件事是如此明显,我认为它必须是域重命名的工件。
这个
<div class="toyota" v-if="car.model == 'toyota'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
<div class="audi" v-if="car.model == 'audi'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
<div class="benz" v-if="car.model == 'benz'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
<div class="rolls" v-if="car.model == 'rolls'">
<span class="model-id">@{{ car.type }}_@{{ car.id }}</span> - @{{ car.title }}
</div>
可能会成为这个
<div :class="car.model">
<span class="model-id">{{ car.type }}_{{ car.id }}</span> - {{ car.title }}
</div>
另外,这是什么? @{{
?
评论后编辑 - 关于创建了多少按钮的问题
听起来你只想要渲染一两个按钮?这是一个测试。
使用模板创建的Cars.vue
规范
测试数据有6条评论,
<script>
export default {
data () {
return {
fetchComplete: true,
fetchError: false,
cars: [
{
model: 'toyota',
type: 'hatch',
id: 1,
title: 'corolla',
description: 'grey corolla',
colors: [{name: 'grey'}, {name: 'grey'}, {name: 'grey'}],
reviews: [
{rating: 2, content: 'its grey', created_at: {date: ''}},
{rating: 2, content: 'its grey', created_at: {date: ''}},
{rating: 2, content: 'its grey', created_at: {date: ''}},
{rating: 2, content: 'its grey', created_at: {date: ''}},
{rating: 2, content: 'its grey', created_at: {date: ''}},
{rating: 2, content: 'its grey', created_at: {date: ''}},
]
}
]
}
},
测试,
it('count the buttons', () => {
const buttons = wrapper.element.querySelectorAll('button');
console.log(buttons)
})
结果,
LOG LOG: Object{
0: <button type="button" data-toggle="collapse" data-target="#expanded-reviews-1" class="btn btn-link">More details</button>,
1: <button type="button" data-toggle="collapse" data-target="#expanded-reviews-1" class="btn btn-link">More details</button>,
2: <button type="button" data-toggle="collapse" data-target="#expanded-reviews-1" class="btn btn-link">More details</button>,
3: <button type="button" data-toggle="collapse" data-target="#expanded-reviews-1" class="btn btn-link">More details</button>,
4: <button type="button" data-toggle="collapse" data-target="#expanded-reviews-1" class="btn btn-link">Less details</button>,
length: 5}
然后,问题是变更检测周期是否足够智能 不 ,以便在每个周期重新评估按钮创建。我会看看我们是否也可以测试一下。
放置v-if
我刚刚想到这个,
<button class="btn btn-link" ... >
<span v-if="n === car.reviews.length-1">Less details</span>
</button>
可能 会更好
<button class="btn btn-link" ... v-if="n === car.reviews.length-1">
Less details
</button>
缺少第一次审核
v-for="n in (0, 4)"
循环似乎错过了第一次审核。如果我将评级设置为顺序号,则不会显示第一个。
<div class="review" v-for="n in (0, 4)">
<strong>@{{ car.reviews[n].rating }}</strong> - @{{ car.reviews[n].content }}
尝试
<div class="review" v-for="(review,n) of car.reviews.slice(0,5)" :key="review.id">
<strong>@{{ review.rating }}</strong> - @{{ review.content }}
...
<div class="review" v-for="(review,n) of car.reviews.slice(5)">
(保持n为按钮v-if表达式。)