简体   繁体   English

反应性vue.js数组不使用v-for显示其内容

[英]Reactive vuejs array does not display its content using v-for

ERROR FOUND: Finally I found the error, I make a brief explanation of it in the next paragraph, since the code below, although it solves the error, does not do it for the error itself, but for changing the approach of the code, Exactly what was said below, by putting the indexes of the array with its own name, vue, understand that those indexes are attributes of the array object and not indexes of the array. 发现错误:最终我找到了错误,我在下一段中对其进行了简要说明,因为以下代码虽然可以解决错误,但并不是针对错误本身,而是为了更改代码的方式,确切地说,通过将数组的索引加上自己的名称vue,可以使您理解这些索引是数组对象的属性,而不是数组的索引。 To correct it the way I wanted to do it initially, I should go through the properties of the array and not index them. 要以最初想要的方式进行更正,我应该遍历数组的属性,而不是对其进行索引。

BEGINNING OF THE POST: I'm having trouble showing my array data in an HTML list. 帖子的开头:我无法在HTML列表中显示数组数据。 Every time I drop an image on a specific div element, an object is inserted into the array whose position becomes the name of the object and not numbered as is usually the case, if an image is dragged again and the object already exists in the array, the quantity attribute of the object in the array is increased. 每当我将图像放到特定的div元素上时,如果将图像再次拖动并且该对象已存在于数组中,则将一个对象插入到数组中,该数组的位置将成为该对象的名称,并且通常不进行编号,数组中对象的数量属性增加。 The problem is when I try to show the contents of that array in an HTML list using v-for , the behavior it has is as if the array were empty. 问题是当我尝试使用v-for在HTML列表中显示该数组的内容时,其行为就好像该数组为空。 I have already verified that the array is not empty and I do not know what else to do. 我已经验证了数组不为空,并且不知道该怎么办。

<template>
<div>
    <div id="wrapper-ingredients">
        <div id="base">
            <img src="../img/base.svg" usemap="#image-map" alt="base">
            <drop id="pizza-base" @drop="handleDrop">
                <map name="image-map" id="image-map">
                    <area target="_self" alt="pizza-base" title="pizza-base"
                          coords="133,387,93,308,79,217,119,119,168,69,231,32,308,17,381,14,448,36,489,64,526,99,555,142,576,195,586,251,575,314,546,359,488,412,416,446,317,454,205,436"
                          shape="poly">
                </map>
            </drop>
        </div>

        <div id="ingredients">
            <drag class="drag" :transfer-data="bellpepper">
                <img src="../img/bellpepper-512.png" id="bellpepper" alt="pimiento amarillo" width="512"
                     height="512">
            </drag>
            <drag class="drag" :transfer-data="cheese">
                <img src="../img/cheese-512.png" alt="queso" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="corn">
                <img src="../img/corn-512.png" alt="maiz" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="mushroom">
                <img src="../img/mushroom-512.png" alt="seta" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="olive">
                <img src="../img/olive-512.png" alt="oliva" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="onion">
                <img src="../img/onion-512.png" alt="cebolla" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="pepperoni">
                <img src="../img/pepperoni-512.png" alt="pepperoni" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="tomato">
                <img src="../img/tomato-512.png" alt="tomate" width="512" height="512">
            </drag>
        </div>
    </div>
    <div id="wrapper-ticket">
        <ul>
            <li v-for="ingRec in ingredientsReceipt" >{{ingRec}}</li>
        </ul>
    </div>
</div>
</template>

<script>

import {Ticket} from "../model/Ticket.js"
import {Bellpepper} from "../model/Bellpepper.js"
import {Cheese} from "../model/Cheese.js"
import {Corn} from "../model/Corn.js"
import {Mushroom} from "../model/Mushroom.js"
import {Olive} from "../model/Olive.js"
import {Onion} from "../model/Onion.js"
import {Pepperoni} from "../model/Pepperoni.js"
import {Tomato} from "../model/Tomato.js"
import {Drag, Drop} from 'vue-drag-drop'

export default {
    components: {Drag, Drop},
    data() {
        return {
            ingredientsReceipt: [],
            bellpepper: new Bellpepper(2),
            cheese: new Cheese(3),
            corn: new Corn(1),
            mushroom: new Mushroom(2),
            olive: new Olive(3),
            onion: new Onion(4),
            pepperoni: new Pepperoni(5),
            tomato: new Tomato(6),
            ticket: new Ticket()
        }
    },
    methods: {
        handleDrop(data) {
            let x = event.clientX
            let y = event.clientY
            let img = document.createElement("img")
            img.setAttribute('src', data.img)
            img.setAttribute('name', data.name)
            img.style.position = 'absolute'
            img.style.width = '3.5%'
            img.style.height = '7%'
            img.style.left = x - img.offsetWidth / 2 - 50 + 'px'
            img.style.top = y - img.offsetHeight / 2 - 25 + 'px'
            img.style.zIndex = '1'
            document.querySelector('#pizza-base').appendChild(img)
            if (this.ingredientsReceipt[data.name] !== data) {
                this.ingredientsReceipt[data.name] = data

            } else {
                this.ingredientsReceipt[data.name].quantity++

            }
            img.addEventListener("click", () => {
                if (this.ingredientsReceipt[data.name].quantity > 0) {
                    this.ingredientsReceipt[data.name].quantity--
                    img.remove()
                } else {
                    img.remove()
                    delete this.ingredientsReceipt[data.name]
                }
            })
        },
    },
}
</script>

I tried to show the array directly without using v-for , showing only an empty array on the screen. 我尝试不使用v-for直接显示数组,而是在屏幕上仅显示一个空数组。 If someone knows where to find the error, it would be very helpful. 如果有人知道在哪里可以找到错误,那将非常有帮助。

You add elements to this.ingredientsReceipt[data.name] = data Vue can't detect changes to the array using this direct access, you can read about it here: 您将元素添加到this.ingredientsReceipt[data.name] = data Vue无法使用此直接访问来检测对阵列的更改,您可以在此处阅读有关内容:

https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating

They also offer a solution - try ingredientsReceipt.$set(data.name, data) 他们还提供了解决方案-尝试ingredientsReceipt.$set(data.name, data)

ok, I finally managed to fix it, the problem was that it was renaming each of the positions of the array. 好的,我终于设法修复它,问题是它正在重命名数组的每个位置。 To solve it I used some functional programming, I have left the positions of the array numbered and I have applied a .filter() to them and I have worked with that obtained value. 为了解决这个问题,我使用了一些函数式编程,我留下了编号为数组的位置,并对其应用了.filter() ,并使用获得的值进行了处理。 Now it works, but I will investigate more to know why it does not work with the renamed array positions. 现在它可以工作了,但是我将进行更多调查,以了解为什么它不适用于重命名的数组位置。

I leave the new code with the changes made, I will also comment on the code that I had to delete, and which I guess is where the problem lies, in case someone is able to find the error. 我将保留所做的更改,保留新代码,我还将对必须删除的代码发表评论,以防有人发现错误,这可能是问题所在。

<template>
<div>
    <div id="wrapper-ingredients">
        <div id="base">
            <img src="../img/base.svg" usemap="#image-map" alt="base">
            <drop id="pizza-base" @drop="handleDrop">
                <map name="image-map" id="image-map">
                    <area target="_self" alt="pizza-base" title="pizza-base"
                          coords="133,387,93,308,79,217,119,119,168,69,231,32,308,17,381,14,448,36,489,64,526,99,555,142,576,195,586,251,575,314,546,359,488,412,416,446,317,454,205,436"
                          shape="poly">
                </map>
            </drop>
        </div>

        <div id="ingredients">
            <drag class="drag" :transfer-data="bellpepper">
                <img src="../img/bellpepper-512.png" id="bellpepper" alt="pimiento amarillo" width="512"
                     height="512">
            </drag>
            <drag class="drag" :transfer-data="cheese">
                <img src="../img/cheese-512.png" alt="queso" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="corn">
                <img src="../img/corn-512.png" alt="maiz" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="mushroom">
                <img src="../img/mushroom-512.png" alt="seta" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="olive">
                <img src="../img/olive-512.png" alt="oliva" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="onion">
                <img src="../img/onion-512.png" alt="cebolla" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="pepperoni">
                <img src="../img/pepperoni-512.png" alt="pepperoni" width="512" height="512">
            </drag>
            <drag class="drag" :transfer-data="tomato">
                <img src="../img/tomato-512.png" alt="tomate" width="512" height="512">
            </drag>
        </div>
    </div>
    <div id="wrapper-ticket">
        <ul>
            <li v-for="ingRec in ingredientsReceipt">{{ingRec.name + " X " + ingRec.quantity}}</li>
        </ul>
    </div>
</div>
</template>
<script>
import {Ticket} from "../model/Ticket.js"
import {Bellpepper} from "../model/Bellpepper.js"
import {Cheese} from "../model/Cheese.js"
import {Corn} from "../model/Corn.js"
import {Mushroom} from "../model/Mushroom.js"
import {Olive} from "../model/Olive.js"
import {Onion} from "../model/Onion.js"
import {Pepperoni} from "../model/Pepperoni.js"
import {Tomato} from "../model/Tomato.js"
import {Drag, Drop} from 'vue-drag-drop'

export default {
    components: {Drag, Drop},
    data() {
        return {
            ingredientsReceipt: [],
            bellpepper: new Bellpepper(2),
            cheese: new Cheese(3),
            corn: new Corn(1),
            mushroom: new Mushroom(2),
            olive: new Olive(3),
            onion: new Onion(4),
            pepperoni: new Pepperoni(5),
            tomato: new Tomato(6),
            ticket: new Ticket()
        }
    },
    methods: {
        handleDrop(data) {
            let x = event.clientX
            let y = event.clientY
            let img = document.createElement("img")
            img.setAttribute('src', data.img)
            img.setAttribute('name', data.name)
            img.style.position = 'absolute'
            img.style.width = '3.5%'
            img.style.height = '7%'
            img.style.left = x - img.offsetWidth / 2 - 50 + 'px'
            img.style.top = y - img.offsetHeight / 2 - 25 + 'px'
            img.style.zIndex = '1'
            document.querySelector('#pizza-base').appendChild(img)
            if (this.ingredientsReceipt.indexOf(data) === -1) {
                this.ingredientsReceipt.push(data)
            } else {
                let x = this.ingredientsReceipt.filter(arrayItem =>
                    arrayItem.name === data.name
                )
                x[0].quantity++
                console.log(x,this.ingredientsReceipt)
            }

            //HERE IS WHERE THE PROBLEM WILL BE...

            /*
            this.ingredientsReceipt[data.name] = (this.ingredientsReceipt[data.name] || 0) + 1
            if (this.ingredientsReceipt[data.name] !== data) {
                this.ingredientsReceipt[data.name] = data

            } else {
                this.ingredientsReceipt[data.name].quantity++

            }
            */
            img.addEventListener("click", () => {
                let x = this.ingredientsReceipt.filter( arrayItem => arrayItem.name === data.name)
                if (x[0].quantity > 0) {
                    x[0].quantity--
                    img.remove()
                } else {
                    img.remove()
                    delete this.ingredientsReceipt[data.name]
                }
            })
            /*console.log(this.ingredientsReceipt)*/
        },
    },
}
</script>

Thank You All for your help!! 谢谢大家的帮助!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM