我遇到了vue.js官方文档here中描述的问题,但与kidna有不同的数据。我想创建树状结构,用项目和子项来描述树(文件和文件夹结构就是很好的例子)。为了做一些视觉增强,我想让它们滑动,但得到了。 mode="out-in"
已设置且无效。
知道如何解决这种转变吗?
Vue.component('booster', {
props: {
item: {
type: Object
}
},
template: '<div class="booster" @click="$emit(\'click\')"><img :src="item.image"></div>'
});
Vue.component('boosters', {
data: function() {
return {
boosters: this.items,
path: [],
root: this.items
};
},
props: {
items: {
type: Array
},
item_up: {
type: Object,
default: function() {
return {
name: "Up",
image: "http://via.placeholder.com/128x178/000000/ffffff?text=↑"
};
}
}
},
methods: {
navigate: function(item) {
var self = this;
if (item === self.item_up && self.path.length) {
self.root = self.path.pop();
} else if ("undefined" !== typeof item.items) {
self.path.push(self.root);
self.root = [self.item_up].concat(item.items);
} else {
console.log(item.name);
}
}
},
template: '<transition-group name="slide" mode="out-in" tag="div" class="boosters"><template v-for="item in root"><booster :item="item" :key="item.name" @click="navigate(item)"></booster></template></transition-group>'
});
var vue = new Vue({
el: '#content'
});
&#13;
#content {
margin: 4rem;
}
.boosters {
display: flex;
flex-wrap: wrap;
align-content: center;
}
.booster {
box-shadow: 0px 0px 6px 3px black;
box-sizing: border-box;
margin: 15px;
}
.booster img {
width: 128px;
height: 178px;
display: block;
}
.slide-enter-active, .slide-leave-active {
transition: all 0.6s ease-in-out;*/
}
.slide-move {
transition: transform 0.5s;
}
.slide-enter {
transform: translateY(-100%);
}
.slide-leave-to {
transform: translateY(100%);
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.3/vue.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="content">
<boosters :items='[
{name:"First",image:"http://via.placeholder.com/128x178?text=1",items:[
{name:"Sub-first-1",image:"http://via.placeholder.com/128x178?text=1.1"},
{name:"Sub-first-2",image:"http://via.placeholder.com/128x178?text=1.2"}
]},
{name:"Second",image:"http://via.placeholder.com/128x178?text=2", items:[
{name:"Sub-second-1",image:"http://via.placeholder.com/128x178?text=2.1"},
{name:"Sub-second-2",image:"http://via.placeholder.com/128x178?text=2.2"}
]},
{name:"Third",image:"http://via.placeholder.com/128x178?text=3"}
]'>
</booster>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
</div>
</body>
</html>
&#13;
答案 0 :(得分:2)
transition-group
没有mode
道具。它已从transition-group.js
component source中的道具中明确删除:
const props = extend({
tag: String,
moveClass: String
}, transitionProps)
delete props.mode
由于纯粹的复杂性,这种情况不太可能发生 - 它可能会为相对非关键的用例引入过多的额外代码,并且多个项目的转换模式的行为可能很模糊且难以定义。即使我们要实现它,我们也可能将其作为单独的插件而不是作为核心的一部分发布。
我在列表转换的文档中打开了an issue来提及。现在它在documentation:
Transition modes不可用,因为我们不再在互斥元素之间交替。
out-in
转换提到by NonPolynomial in the issue的一个小解决方法是使用transition-delay
在完成离开动画后延迟输入动画。
new Vue({
el: '#app',
data: {
elements: [
[1, 2, 3],
[4, 5, 6, 7]
],
index: 0
},
});
&#13;
.fade-out-in-enter-active,
.fade-out-in-leave-active {
transition: opacity .5s;
}
.fade-out-in-enter-active {
transition-delay: .5s;
}
.fade-out-in-enter,
.fade-out-in-leave-to {
opacity: 0;
}
&#13;
<div id="app">
<button type="button" @click="index = (index + 1) % elements.length">Swap</button>
<transition-group tag="ul" name="fade-out-in">
<li v-for="num in elements[index]" :key="num">
{{num}}
</li>
</transition-group>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
&#13;
作为替代方案,Staggering List Transitions上的文档提供了一个很好的示例,说明如何使用JavaScript处理完全控制的转换。
new Vue({
el: '#staggered-list-demo',
data: {
query: '',
list: [
{ msg: 'Bruce Lee' },
{ msg: 'Jackie Chan' },
{ msg: 'Chuck Norris' },
{ msg: 'Jet Li' },
{ msg: 'Kung Fury' }
]
},
computed: {
computedList: function () {
var vm = this
return this.list.filter(function (item) {
return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
})
}
},
methods: {
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)
}
}
})
&#13;
<div id="staggered-list-demo">
<input v-model="query">
<transition-group
name="staggered-fade"
tag="ul"
v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
>
<li
v-for="(item, index) in computedList"
v-bind:key="item.msg"
v-bind:data-index="index"
>{{ item.msg }}</li>
</transition-group>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
&#13;