在Vue中按类名称动态求和子元素

时间:2018-11-21 02:50:09

标签: vue.js vuejs2

我有一个页面,允许用户将图像拖放到预定义的DIV中,然后根据图像的类名计算图像的总值。我正在尝试做的事情是从每个外部div.answer读取值并获取子图像的类名。

我的源代码是:

<div
    is="box-answers"
    v-for="box in boxes.slice().reverse()"
    v-bind:key="box.id"
    v-bind:level="box.level"
    v-bind:hint="box.hint"
></div>

<script>
Vue.component('box-answers', {
    props: ['level','hint'],
    template: '<div class="droppable answer :id="level" :title="hint"></div>'
});

new Vue({ 
    el: '#mainapp',
    data: {
        boxes: [
            { id: 1, level: 'baselevel-1', hint: 'x 1' },
            { id: 2, level: 'baselevel-2', hint: 'x 20' },
            { id: 3, level: 'baselevel-3', hint: 'x 400' },
            { id: 4, level: 'baselevel-4', hint: 'x 8,000' },
            { id: 5, level: 'baselevel-5', hint: 'x 160,000' }
        ]
    }
</script>

这将转换为以下HTML(通过拖动,嵌套的DIV和SPAN是用户可能的条目):

    <div id="baselevel-5" class="droppable answer" title="x 160,000">
      <div><img src="images/line.gif" alt="Five" class="imgfive"></div>
      <span><img src="images/dot.gif" alt="One" class="imgone"></span>
    </div>
    ...
    <div id="baselevel-1" class="droppable answer" title="x 1">
      <span><img src="images/line.gif" alt="One" class="imgone"></span>
    </div>

当前,我使用以下方法通过jQuery / JavaScript计算点值:

$(function(j) {
var arAnswers = Array(1);
count = 0; //
j("div.answer").each(function( idx ) {
    currentId = j(this).attr('id');
    ones = 0;
    fives = 0;

    if ( j("#" + currentId).children().length > 0 ) {
        ones = j("#" + currentId).children().find("img.imgone").length * 1;
        fives = j("#" + currentId).children().find("img.imgfive").length * 5;
        arAnswers[count] = ones + fives; //Tally box value

        count++;
    }
});
});

我希望Vue执行类似的迭代和加法运算,以返回基于图像类名找到的1和5的总值。

1 个答案:

答案 0 :(得分:2)

当前,您正在通过纯DOM操作来解决此问题。如果这是您需要的,那么您只需使用$refs

<!-- NOTICE ref -->
<div ref="boxAnswers"
    is="box-answers"
    v-for="box in boxes.slice().reverse()"
    v-bind:key="box.id"
    v-bind:level="box.level"
    v-bind:hint="box.hint">
</div>

在高级组件中,您将具有类似以下功能:

function calculate() {
    // NOTICE $refs
    const arAnswers = this.$refs.boxAnswers.map((x) => {

        // $el is the DOM element
        const once = x.$el.querySelectorAll('img.imgone').length * 1;
        const fives = x.$el.querySelectorAll('img.imgfive').length * 5;

        return once + fives

    });

    return arAnswers;

}

但这不是正确的Vue处理方式。您必须考虑事件和数据模型(MVVM-请勿触摸DOM。DOM只是数据的一种表示形式)模型)。由于您有一个基于拖放的应用程序,因此您必须侦听dragdragstartdragend和其他drag事件。例如:

<!-- NOTICE drop event -->
<div @drop="onDropEnd(box, $event)"
    is="box-answers"
    v-for="box in boxes.slice().reverse()"
    v-bind:key="box.id"
    v-bind:level="box.level"
    v-bind:hint="box.hint">
</div>

您的onDropEnd事件处理程序将如下所示:

function onDrop(box, $event) {

    // box - on which box drop is happening
    // $event.data - which image is being dropped

    // Verify $event.data is actually the image you are intending
    if ($event.data === 'some-type-image') {
        // Do the counting manipulations here
        // ... remaining code
    }

}

这不是完整的代码,因为我不知道其他组件。但这应该可以帮助您确定所需的方向。