admin管理员组文章数量:1420279
I have a list of Profiles that open an "edit profile" screen. This screen slided in from the left. When I select a profile, if there is a screen already selected, I want it to slide out first, change the selected profile data and then slide in.
What happens now is: when I first select one element, the screen slides in. When I change the selected element, screen stays and don't slide out and back in.
Here is a gif to show how it's behaving now:
My code is:
Vue Method:
editProfile: function (index){
// this.editingProfile = false;
this.setProfile(index);
this.editingProfile = true;
}
Html View:
<transition name="fade" mode="out-in">
<div v-if="editingProfile" id="edit-profile">
<input placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
</div>
</transition>
CSS:
.fade-enter-active, .fade-leave-active {
transition: all .2s;
/* transform:translateX(0); */
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform:translateX(-100%);
}
How do I make it properly slide out and then back in when changing a profile?
I have a list of Profiles that open an "edit profile" screen. This screen slided in from the left. When I select a profile, if there is a screen already selected, I want it to slide out first, change the selected profile data and then slide in.
What happens now is: when I first select one element, the screen slides in. When I change the selected element, screen stays and don't slide out and back in.
Here is a gif to show how it's behaving now:
My code is:
Vue Method:
editProfile: function (index){
// this.editingProfile = false;
this.setProfile(index);
this.editingProfile = true;
}
Html View:
<transition name="fade" mode="out-in">
<div v-if="editingProfile" id="edit-profile">
<input placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
</div>
</transition>
CSS:
.fade-enter-active, .fade-leave-active {
transition: all .2s;
/* transform:translateX(0); */
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform:translateX(-100%);
}
How do I make it properly slide out and then back in when changing a profile?
Share Improve this question asked Aug 13, 2018 at 17:04 sigmaxfsigmaxf 8,51215 gold badges70 silver badges133 bronze badges 5-
Are you properly toggling
this.editingProfile
true falsey – Helping hand Commented Aug 13, 2018 at 17:18 - if I toggle it false and then true again, nothing happens. – sigmaxf Commented Aug 13, 2018 at 17:21
- I think you'll need a set of panels as apposed to a single panel that you adjust the content of. Otherwise Vue is going to try to recycle that panel and ignore the transition. You want more of a list transition with item in-out animations. – zero298 Commented Aug 13, 2018 at 17:24
-
inside
editProfile
, you can set false first, then inthis.$nextTick
, set to true again insidesetTimeout(()=>{}, 200)
, please check this fiddle. As @zero298 mentioned, group transition should be the solution for slide in/out. – Sphinx Commented Aug 13, 2018 at 17:27 - You can try with single element i.e profile1 if true false toggle slide in & out is working or not. Also do you call editProfile when clicked one of the vertical list element – Helping hand Commented Aug 13, 2018 at 17:34
2 Answers
Reset to default 4I think I was incorrect with my ment. One way you can do this is to leverage :key
and a v-if
so that you can tell Vue to render a panel if you have selected one and then transition between panels that way. You won't need to have a transition-group
then.
The thing is :key
is what tells Vue that everything has changed. If you leave it off, Vue tries to recycle as much as it can. See the docs: Transitioning Between Elements
When toggling between elements that have the same tag name, you must tell Vue that they are distinct elements by giving them unique
key
attributes. Otherwise, Vue’s piler will only replace the content of the element for efficiency. Even when technically unnecessary though, it’s considered good practice to always key multiple items within a<transition>
ponent.
Consider the minimal example below:
const panels = [{
title: "Hello"
},
{
title: "World"
},
{
title: "Foo"
},
{
title: "Bar"
}
];
const app = new Vue({
el: "#app",
data() {
return {
panels,
activePanel: null
};
},
puted: {
titles() {
return this.panels.map(panel => panel.title);
}
},
methods: {
handleTitleClick(idx) {
if (this.activePanel === idx) {
this.activePanel = null;
return;
}
this.activePanel = idx;
}
}
});
body {
margin: 0;
padding: 0;
}
#app {
display: flex;
align-items: stretch;
height: 100vh;
}
#panel-set {
flex: 1 0 70%;
display: flex;
}
#side-panel {
flex: 1 0 30%;
}
.panel {
padding: 1em;
flex: 1 0;
background-color: rgba(0, 0, 0, 0.2);
}
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: transform 500ms ease-in-out;
}
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateX(-100%);
}
<script src="https://cdn.jsdelivr/npm/vue/dist/vue.min.js"></script>
<div id="app">
<div id="panel-set">
<transition name="slide-fade" mode="out-in">
<div class="panel" v-if="activePanel !== null" :key="activePanel">
<h2>{{panels[activePanel].title}}</h2>
<p>Lorem ipsum</p>
</div>
</transition>
</div>
<div id="side-panel">
<ul>
<li v-for="(title, idx) in titles" @click="handleTitleClick(idx)">{{title}}</li>
</ul>
</div>
</div>
The root cause is v-if="editingProfile"
always true after showing one profile in your codes.
One solution is set it to false first, then in this.$nextTick
to set it to true again. But you have to put this.editingProfile = true
inside one setTimeout
and delay time = transition time. Otherwise, slide out
effect will be overwritten.
Like below demo:
new Vue({
el: '#emit-example-simple',
data() {
return {
editingProfile: false,
synced : {
profiles: [{'name':'A'}, {'name':'B'}, {'name':'C'}],
selectedProfile: 0
},
}
},
methods: {
editProfile: function (index){
this.editingProfile = !this.editingProfile
this.$nextTick(() => {
setTimeout(()=> {
this.synced.selectedProfile = index
this.editingProfile = true
}, 1200)
})
}
}
})
.fade-enter-active, .fade-leave-active {
transition: all 1.2s;
/* transform:translateX(0); */
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform:translateX(-100%);
border: 1px solid white;
}
<script src="https://unpkg./vue/dist/vue.js"></script>
<div id="emit-example-simple">
<button @click="editProfile(0)">Profile 1</button>
<button @click="editProfile(1)">Profile 2</button>
<button @click="editProfile(2)">Profile 3</button>
<transition name="fade" mode="out-in">
<div v-if="editingProfile" id="edit-profile">
<input style="border: 5px solid red;" placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
</div>
</transition>
</div>
Or you can consider to use Group transition
like below simple demo:
new Vue({
el: '#emit-example-simple',
data() {
return {
editingProfile: false,
profileContainers: [true, false],
synced : {
profiles: [{'name':'A'}, {'name':'B'}, {'name':'C'}],
selectedProfile: 0
},
}
},
methods: {
editProfile: function (index){
this.synced.selectedProfile = index
this.profileContainers = this.profileContainers.map((x)=>!x)
}
}
})
.list-items-enter-active {
transition: all 1.2s;
}
.list-items-leave-active {
transition: all 1.2s;
}
.list-items-enter, .list-items-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform:translateX(-100%);
border: 1px solid white;
}
.list-item {
display: inline-block;
border: 6px solid red;
}
<script src="https://unpkg./vue/dist/vue.js"></script>
<div id="emit-example-simple">
<button @click="editProfile(0)">Profile 1</button>
<button @click="editProfile(1)">Profile 2</button>
<button @click="editProfile(2)">Profile 3</button>
<transition-group name="list-items" tag="p">
<div v-for="(item, index) in profileContainers" :key="index" v-if="item">
<input style="border: 5px solid red;" placeholder="Profile Name" v-model="synced.profiles[synced.selectedProfile].name">
</div>
</transition-group>
</div>
本文标签: javascriptVuejs transition on changing selected element from a listStack Overflow
版权声明:本文标题:javascript - Vue.js transition on changing selected element from a list - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745331156a2653817.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论