我正在尝试向表单添加过渡,以便当用户选择问题的特定答案时,它将动态显示下一个问题。目前,我看起来像这样:
<input type="text" :value="vueModel.question1" />
<div v-if="vueModel.question1 === 'hello'">
//Do something
</div>
<div v-else-if="vueModel.question1 === 'hihi'">
//Do something
</div>
<div v-else>
//Do something
</div>
我的问题是,我应该这样添加过渡吗? (为什么?)
<input type="text" :value="vueModel.question1" />
<transition-group name="slide-fade" mode="in-out">
<div v-if="vueModel.question1 === 'hello'" key="key1">
//Do something
</div>
<div v-else-if="vueModel.question1 === 'hihi'" key="key2">
//Do something
</div>
<div v-else key="key3">
//Do something
</div>
</transition-group>
还是这种方式? (为什么?)
<input type="text" :value="vueModel.question1" />
<transition name="slide-fade" mode="in-out">
<div v-if="vueModel.question1 === 'hello'" key="key1">
//Do something
</div>
<div v-else-if="vueModel.question1 === 'hihi'" key="key2">
//Do something
</div>
<div v-else key="key3">
//Do something
</div>
</transition>
或者,还有其他方法可以更好地做到这一点,并且该方法符合Vue的最佳做法吗?
答案 0 :(得分:1)
因此,当您有一个项目列表并且想要同时渲染和过滤时(例如,使用v-for
)?在这种情况下,您可以使用transition-group
组件。与transition
不同,这将呈现一个实际元素:在下一个截图中像div
。但是,您可以更改使用tag
属性呈现的元素。
注意
始终要求内部的元素具有唯一的键属性。
如果您有一个问题,然后想“做某事”,请像本示例中那样仅使用transition
。
transition
和transition-group
之间的主要区别在于过渡将影响一个组件。这意味着,如果您有一个组件要替换为另一个组件,则可以使用过渡。
new Vue({
el: '#vue-transition',
data: {
show: false,
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div id="vue-transition">
<button @click="show = !show"> Simple Transition </button>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">Teocci</p>
</transition>
</div>
另一方面,transition-group
从元素列表中渲染实际元素,因此始终要求内部的元素具有唯一的键属性。例如,如果您有9个问题,但您想要呈现每个元素随机过渡到 SAME 组中另一个位置的过渡。
new Vue({
el: '#list-complete-demo',
data: {
items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
},
methods: {
shuffle: function() {
this.items = _.shuffle(this.items)
}
}
})
.list-complete-item {
transition: all 1s;
display: inline-block;
margin-right: 10px;
}
.list-complete-enter,
.list-complete-leave-to {
opacity: 0;
transform: translateY(30px);
}
.list-complete-leave-active {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<div id="list-complete-demo" class="demo">
<button v-on:click="shuffle">Shuffle</button>
<transition-group name="list-complete" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-complete-item">
{{ item }}
</span>
</transition-group>
</div>
因此,如果您只想“做某事”,请使用本代码段中所示的transition
来实现所需的目的。
let app = new Vue({
el: '#vue-selector',
data: {
questions: [{
id: 0,
description: 'Question 01',
answer: 'hihi'
},
{
id: 1,
description: 'Question 02',
answer: 'lala'
},
{
id: 2,
description: 'Question 03',
answer: 'hello'
},
{
id: 3,
description: 'Question 04',
answer: 'none'
},
{
id: 4,
description: 'Question 05',
answer: 'teo'
},
],
answer: {
question: -1,
text: '',
},
answerText: '',
selected: '',
},
computed: {
computedQuestions: function() {
let vm = this;
return this.questions.filter(function(item, index) {
return index !== vm.answers;
})
}
},
methods: {
answerQuestion: function(index) {
this.answer.question = index;
this.answer.text = this.answerText;
},
beforeEnter: function(el) {
el.style.opacity = 0
el.style.height = 0
},
enter: function(el, done) {
var delay = el.dataset.index * 150
setTimeout(function() {
Velocity(
el, {
opacity: 1,
height: '1.6em'
}, {
complete: done
}
)
}, delay)
},
leave: function(el, done) {
var delay = el.dataset.index * 150
setTimeout(function() {
Velocity(
el, {
opacity: 0,
height: 0
}, {
complete: done
}
)
}, delay)
},
},
});
div.selector {
display: block;
padding-top: 25px;
padding-bottom: 125px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/2.0.3/velocity.min.js"></script>
<div id="vue-selector">
<div>Question 01</div>
<input v-model="answerText" placeholder="answer me">
<button @click="answerQuestion(0)"> Answer </button>
<transition name="slide-fade" mode="in-out">
<div v-if="answer.text === 'hello'">
Do something A
</div>
<div v-else-if="answer.text === 'hihi'">
Do something B
</div>
<div v-else>
Waiting for answer
</div>
</transition>
</div>