javascript - 何时使用过渡与过渡组
问题描述
我正在尝试向我的表单添加转换,以便当用户选择问题的特定答案时,它将动态显示下一个问题。目前我看起来像这样:
<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 最佳实践?
解决方案
因此,当您有一个项目列表并且您想同时渲染和过滤时,例如使用v-for
? 在这种情况下,您可以使用transition-group
组件。与 不同transition
的是,这将渲染一个实际的元素:就像div
在下一个 sniped 中一样。但是,您可以更改使用该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>
推荐阅读
- c# - 打开另一个应用程序(chrome)并在 android 中以统一 c# 传递一个 url
- aws-glue - 如何以编程方式重命名 AWS Glue 目录中的列名
- java - 如何在 Maven 中禁用 groovy 优化
- php - PHP - 服务器端控制台输出
- javascript - Three.js - 将多个图像映射到一个球体并控制每个图像
- hibernate - Jpa Criteria Api isFalse 和 isTrue 有什么区别?
- android-studio - 错误:注释处理器现在必须显式声明
- java - 使用字节数组创建单色位图
- java - 带有杰克逊 JsonProperty 的 Lombok 构建器模式
- java - 无法将服务自动装配到 AsyncUncaughtExceptionHandler 的实现中