0

I am doing my first steps in vue starting with this little example. I am trying to achieve a sum of items according to data provided. (The complete example can be found in this jsffile)

The component:

Vue.component('items-table', {
    props: ['items', 'item', 'total'],
    template: `
        <div>
                <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Price</th>
                    </tr>
                </thead>
                <tbody>
                    <tr
                        v-for="item of items"
                        v-bind:key="item.id"
                    >
                      <td>{{item.desc}}</td>
                      <td class="price">{{item.price}}</td>
                    </tr>
                </tbody>
            </table>
            
            
            <div>Total items: {{items.length}}</div>
            <div>Total price: {{total}}</div>
        </div>
    `
});

In the app below, the console prints an empty array, in consequence always returns 0:

new Vue({
  el: '#app',
    data:{
        items: []
    },
    computed: {
        total: function(){
            console.log(this.items);
            return this.items.reduce(function(total, item){

                return total + item.price;
            },0);
        }
    },
    mounted() {
        console.log('app mounted');
    }
});

Finally, I provide the initial data that will be used to display, manipulate and make some calculations:

<div id="app">
  <items-table v-bind:total="total" v-bind:items="[
            { id: 1, desc: 'Banana', price: 10 },
            { id: 2, desc: 'Pen', price: 5 },
            { id: 3, desc: 'Melon', price: 5 }
        ]"></items-table>

</div>

My problem is that the sum of the prices in {{total}} always is 0. Looks like the items array are never set when it is provided via v-bind:items (is it not reactive?). I appreciate the help in advance.

Edit: Backgrounds

All data that will be used for components comes from PHP plain files. CRUD operations are not available yet. Said that is very important that the data could be bind from tags directly.

8
  • just remove data from your component and iterate over items props Commented Jul 26, 2018 at 16:49
  • 1
    Does this work as expected? fiddle Commented Jul 26, 2018 at 17:18
  • 1
    The total calculated value should be part of the items-table component, not the parent component. The items-table should have an items prop, and it would iterate through that for its contents. The total calculated value would reference this.items to calculate the total. Commented Jul 26, 2018 at 17:21
  • 1
    computed counts your local items not a props Commented Jul 26, 2018 at 17:31
  • 1
    @TheReason said, uses computed inside of the component like this fiddle Commented Jul 26, 2018 at 17:32

1 Answer 1

1

Your function calculating the total price uses the items object declared in the data tag of your view. Since its empty, the price is always 0. YOu should do something like:

    new Vue({
  el: '#app',
    data:{
        items: [
            { id: 1, desc: 'Banana', price: 10 },
            { id: 2, desc: 'Pen', price: 5 },
            { id: 3, desc: 'Melon', price: 5 }
        ]
    },
    computed: {
        total: function(){
            console.log(this.items);
            return this.items.reduce(function(total, item){

                return total + item.price;
            },0);
        }
    },
    mounted() {
        console.log('app mounted');
    }
})

And the vue should be more like this:

    <div id="app">
  <h2>List of items</h2>
  <items-table v-bind:total="total" v-bind={items}></items-table>

</div>

Hope it helps you with your problem

Edit: JSFiddle: https://jsfiddle.net/eywraw8t/210901/

Sign up to request clarification or add additional context in comments.

2 Comments

Hello. This is the case that I am trying to avoid. The data should be set from the tag.
William, your comment has too much sense for me. I can do it how you said: get the HTML element from his ID/ClassName, extract the items. But now my fear is weather choose the correct framework for my needs. I just need to redesign a web page, but the data could not be fetch via CRUD. I do not know what Vue recommends for this cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.