从数组删除元素时未定义索引

时间:2019-08-25 14:56:22

标签: javascript html vue.js vuejs2

如果动画结束,我正在尝试从数组中删除元素,但出现错误:未定义索引。

如何正确找到特定索引并在动画结束时将其删除? 它们是drop()和remove()方法。 drop()方法效果很好(我认为),并且元素已正确添加到DOM。

单个文件组件如下所示:

<template>
    <div class="card" :class="classObject">
        <div class="card-image">
            <figure class="image" @click="randomImage">
                <img src="../../img/one.png" alt="Placeholder image" v-if="selected === 0">
                <img src="../../img/two.jpg" alt="Placeholder image" v-else-if="selected === 1">
                <img src="../../img/three.jpg" alt="Placeholder image" v-else>
            </figure>
        </div>
        <div class="card-content has-text-centered">
            <div class="content">

                <div class="title is-size-1 has-text-weight-bold">
                    <span v-show="score >= 10">?</span>
                    {{score}}
                    <span v-show="score >= 10">?</span>
                </div>

                <div v-if="score >= 5" class="has-text-grey">
                    ╮ (. ❛ ᴗ ❛.) ╭
                </div>
                <div v-else-if="score < 5 && score > 0" class="has-text-grey">
                    ༼ つ ◕_◕ ༽つ
                </div>
                <div v-else class="has-text-grey">
                    (・_・ヾ
                </div>

            </div>
        </div>
        <footer class="card-footer">
            <a class="card-footer-item" @click="score++">more ?</a>
            <a class="card-footer-item" @click="score--">less ?</a>
            <a class="card-footer-item" @click="drop" :disabled="score < 1">butt ?</a>
        </footer>

        <transition-group name="drop" v-on:after-enter="remove(index)">
            <img src="../../img/image.png" class="image" alt="an image" v-for="(item, index) in items" :key="index">
        </transition-group>
    </div>

</template>



<script>
export default {
    data() {
        return {
            score: 23,
            selected: 0,
            images: [
                './img/one.png',
                './img/two.jpg',
                './img/three.jpg'
            ],
            items: []
        }
    },
    methods: {
        debug(data) {
            console.log(data);                    
        },
        randomImage() {
            this.selected = Math.floor((Math.random() * 3))
        },
        drop() {
            this.items.push(this.item);
        },
        remove(item) {         
            this.items.splice(item, 1);
        }
    },
    computed: {
        image() {
            return this.selected;
        },
        classObject() {
            return {
                hard: this.score >= 42,
                sixnine: this.score == 69
            }
        }
    }
}
</script>


<style>
.image {
    position: absolute;
    top: calc(0vh - 500px);
    left: 0;
    right: 0;
    /* pointer-events: none; */
    /* top: 50%;
    left: 50%;
    transform: translate(-50%); */
}

.drop-enter-active {
    transition: transform 3s;
}

.drop-enter {
    transform: translateY(0vh);
}

.drop-enter-to {
    transform: translateY(calc(100vh + 500px));
}
</style>

4 个答案:

答案 0 :(得分:0)

您可以使用findIndex方法在数组中找到元素的索引:

remove(item) {   
         const index = this.items.findIndex(arrayItem => arrayItem === item);   
         this.items.splice(index, 1);
       }

答案 1 :(得分:0)

查找特定索引并将其从数组中删除的实例。

在下面的代码段中,找到具有{ id: 2 }的索引并将其从数组中删除。

const array = [{ id: 1 }, { id: 2 }, 
{ id: 3 }];
const index = array.findIndex((f) => 
{ return f.id && f.id === 2; });
console.log(index);
if(index > -1) {
// remove entry from found index
array.splice(index, 1);
   console.log(array);
   }
 

答案 2 :(得分:0)

当您需要引用时尝试调用函数时,就会出现问题。尝试使用v-on:after-enter="remove(index)"代替v-on:after-enter="remove"。因此,当触发v-on:after-enter时,它将使用您已经给它的引用来调用remove(item)。如果要引用某个功能,则只能使用该功能的名称。

答案 3 :(得分:0)

我修改了代码,使我想做的事情更加明显

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css" integrity="sha256-vK3UTo/8wHbaUn+dTQD0X6dzidqc5l7gczvH+Bnowwk=" crossorigin="anonymous" />
    <title>life is vuetiful</title>
</head>
<body class="has-background-primary">
<style>
html {
	background-color: transparent;
}

body {
	width: 42%;
	margin: 2em auto;
}

a[disabled] {
	color: grey;
	cursor: default;
	background-color: lightgray;
}

.hard {
	border: 10px solid purple;
}

.sixnine {
	background-color: pink;
	border: 20px solid hotpink;
	outline: 15px solid pink;
}

.image {
    position: absolute;
    top: calc(0vh - 500px);
    left: 0;
    right: 0;
    /* pointer-events: none; */
    /* top: 50%;
    left: 50%;
    transform: translate(-50%); */
}

.drop-enter-active {
    transition: transform 3s;
}

.drop-enter {
    transform: translateY(0vh);
}

.drop-enter-to {
    transform: translateY(calc(100vh + 500px));
}
</style>
    
    <div id="app">
        <test></test>
    </div>



    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
    Vue.component('test', {
    template: 
        `
        <div class="card">
            <footer class="card-footer">
                <a class="card-footer-item" @click="drop">run</a>
            </footer>

            <transition-group name="drop" v-on:after-enter="remove(index)">
                <img src="https://picsum.photos/id/237/200/300" class="image" v-for="               (item, index) in items" :key="index" alt="an image">
            </transition-group>
        </div>
        `
    ,
    data() {
        return {
            items: []
        }
    },
    methods: {
        drop() {
            this.items.push(this.item);
        },
        remove (index) {
            this.$delete(this.items, index);
        }
    }
})
    </script>
    <script>
        const vue = new Vue({
            el: '#app'
        })
    </script>

</body>
</html>