gpt4 book ai didi

javascript - 单击按钮不会触发 Vue Transition

转载 作者:搜寻专家 更新时间:2023-10-30 22:28:22 25 4
gpt4 key购买 nike

我是 Vue JS 的新手,我正在创建一个缩略图查看器,我将在其中获取图像和视频列表作为对象数组。起初,我将只显示 5 个元素,当用户单击顶部/底部按钮时,我想垂直滑动缩略图。

我创建了一个 codepen通过引用 StackOverflow 上的一些链接。

我正在使用 Vue Transitions,我的数据似乎是 react 性的,但是当我单击“顶部”和“底部”按钮时,不知何故我看不到平滑的过渡(滑动到顶部/底部 100 像素)。

HTML 代码:

<div id="app" class="container-fluid">
<div class="row row-eq-height">
<div class="thumbnail-container">
<button class="up" @click="moveTop" :disabled="currentTopIndex === 0">Top</button>
<div :class="'slider' + (isSlidingToPrevious ? ' sliding-to-previous' : '')">
<transition-group name='list' tag="ul">
<li v-for="(item,index) in currentCarouselData" v-bind:key="index" class="list-item"><img :src="item.itemImage" :alt="item.itemImageAlt" /></li>
</transition-group>
</div>
<button @click="moveBottom" class="down" :disabled="currentBottomIndex === totalCount">Down</button>
</div>
</div>
<pre>
totalCount {{totalCount}}
currentTopIndex {{currentTopIndex}}
currentBottomIndex {{currentBottomIndex}}
itemsToDisplay {{itemsToDisplay}}
currentCarouselData {{currentCarouselData}}
</pre>
</div>

CSS/LESS 代码:

.row-eq-height {
display: flex;
ul {
list-style-type: none;
display: flex;
flex-direction: column;
overflow: hidden;
height: auto;
border: 1px solid black;
}
li {
flex: 1;
width: 64px;
height: 64px;
position: relative;
margin: 8px 0;
border: 1px solid red;
img {
max-width: 100%;
max-height: 100%;
}
}
}

.list-leave-active,
.list-enter-active {
transition: 0.5s;
}
.list-enter {
transform: translate(0, 100px);
}
.list-leave-to {
transform: translate(0, -100px);
}
.sliding-to-previous {
.list-enter {
transform: translate(0, -100px);
}
.list-leave-to {
transform: translate(0, 100px);
}
}

Javascript/VUE 代码:

new Vue({
el: "#app",
data() {
return {
totalCarouselData: [{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test1"
},
{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test2"
},
{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test3"
},
{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test4"
},
{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test5"
},
{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test6"
},
{
itemImage: "https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test7"
}
],
currentCarouselData: [],
isSlidingToPrevious: false,
totalCount: 0,
currentTopIndex: 0,
currentBottomIndex: 0,
itemsToDisplay: 5
};
},
computed: {},
mounted() {
//At first show only 5 items
this.currentCarouselData = this.totalCarouselData.slice(
this.currentTopIndex,
this.itemsToDisplay
);
//Get Total Count
this.totalCount = this.totalCarouselData.length;
//Update current bottom index
this.currentBottomIndex = this.itemsToDisplay;
},
methods: {
moveTop() {
this.isSlidingToPrevious = true;
this.currentTopIndex += 1;
this.currentBottomIndex -= 1;
this.addToTopComputedArr(this.currentBottomIndex);
},
moveBottom() {
this.isSlidingToPrevious = false;
this.currentTopIndex -= 1;
this.currentBottomIndex += 1;
this.addToBottomComputedArr(this.currentBottomIndex);
},
addToBottomComputedArr(index) {
//Splice the first item
this.currentCarouselData.splice(0, 1);
//Add the next item to the array
this.currentCarouselData.push(this.totalCarouselData[index - 1]);
},
addToTopComputedArr(index) {
//Splice the last item
this.currentCarouselData.splice(index - 1, 1);
//Add item to the beginning of the array
this.currentCarouselData.unshift(
this.totalCarouselData[index - this.itemsToDisplay]
);
}
}
});

最佳答案

没有转换问题您遇到的是由 :key="index" 引起的。

检查 Vue Guide: key of v-for ,

When Vue is updating a list of elements rendered with v-for, bydefault it uses an “in-place patch” strategy.

This default mode is efficient, but only suitable when your listrender output does not rely on child component state or temporary DOMstate (e.g. form input values).

To give Vue a hint so that it can track each node’s identity, and thusreuse and reorder existing elements, you need to provide a unique keyattribute for each item.

在您的代码中,您的五张图片始终具有相同的键=[1, 2, 3, 4, 5],因此 Vue 将就地修补它们, 它导致转换没有被触发。

所以只需将 :key="index" 修改为 :key="item.itemImageAlt" 即可。

最后自行调整css,使转场效果达到你的要求。

下面是一个工作演示:

Vue.config.productionTip = false
new Vue({
el: "#app",
data() {
return {
totalCarouselData: [
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test1"
},
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test2"
},
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test3"
},
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test4"
},
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test5"
},
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test6"
},
{
itemImage:
"https://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg",
itemImageAlt: "Test7"
}
],
currentCarouselData: [],
isSlidingToPrevious: false,
totalCount: 0,
currentTopIndex: 0,
currentBottomIndex: 0,
itemsToDisplay: 5
};
},
computed: {
computedCarouseData: function () { // added computed property
return this.totalCarouselData.slice(
-this.currentTopIndex,
this.itemsToDisplay-this.currentTopIndex
)
}
},
mounted() {
//At first show only 5 items
this.currentCarouselData = this.totalCarouselData.slice(
this.currentTopIndex,
this.itemsToDisplay
);
//Get Total Count
this.totalCount = this.totalCarouselData.length;
//Update current bottom index
this.currentBottomIndex = this.itemsToDisplay;
},
methods: {
moveTop() {
this.isSlidingToPrevious = true;
this.currentTopIndex += 1;
this.currentBottomIndex -= 1;
this.addToTopComputedArr(this.currentBottomIndex);
},
moveBottom() {
this.isSlidingToPrevious = false;
this.currentTopIndex -= 1;
this.currentBottomIndex += 1;
this.addToBottomComputedArr(this.currentBottomIndex);
},
addToBottomComputedArr(index) {
//Splice the first item
this.currentCarouselData.splice(0, 1);
//Add the next item to the array
this.currentCarouselData.push(this.totalCarouselData[index - 1]);
},
addToTopComputedArr(index) {
//Splice the last item
this.currentCarouselData.splice(index - 1, 1);
//Add item to the beginning of the array
this.currentCarouselData.unshift(
this.totalCarouselData[index - this.itemsToDisplay]
);
}
}
});
.row-eq-height {
display: flex;
}
.row-eq-height ul {
list-style-type: none;
display: flex;
flex-direction: column;
overflow: hidden;
height: auto;
border: 1px solid black;
}
.row-eq-height li {
flex: 1;
width: 64px;
height: 64px;
position: relative;
margin: 8px 0;
border: 1px solid red;
}
.row-eq-height li img {
max-width: 100%;
max-height: 100%;
}
.list-leave-active,
.list-enter-active {
transition: all 2s ease;
}
.list-enter {
opacity: 0;
transform: translateX(-300px);
}
.list-leave-to {
opacity: 0;
transform: translateX(-300px);
}
.sliding-to-previous .list-enter {
transform: translateY(-100px);
}
.sliding-to-previous .list-leave-to {
transform: translateY(100px);
}
.list-move {
transition: transform 1s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app" class="container-fluid">
<div class="row row-eq-height">
<div class="thumbnail-container">
<button class="up" @click="moveTop" :disabled="currentTopIndex === 0">Top</button>
<button @click="moveBottom" class="down" :disabled="currentBottomIndex === totalCount">Down</button>
<div :class="'slider' + (isSlidingToPrevious ? ' sliding-to-previous' : '')">
<transition-group name='list' tag="ul">
<li v-for="(item,index) in computedCarouseData" v-bind:key="item.itemImageAlt" class="list-item"><img :src="item.itemImage" :alt="item.itemImageAlt" style=""/>{{item.itemImageAlt}}</li>
</transition-group>
</div>
</div>
</div>
<pre>
totalCount {{totalCount}}
currentTopIndex {{currentTopIndex}}
currentBottomIndex {{currentBottomIndex}}
itemsToDisplay {{itemsToDisplay}}
currentCarouselData {{computedCarouseData}}
</pre>
</div>

关于javascript - 单击按钮不会触发 Vue Transition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51022673/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com