tomhre
tomhre

Reputation: 315

Access data between components that have the same root with Vue.js

I am trying to extend data in one component, based on actions happening in a different component.

For example in one component I have a array of objects that I render in v-for loop, the array is part of data:

<template lang="html">
    <div class="calendar">
        <div class="calendar-header  row">
            <div class="col-sm-2 centered">
                <i class="fa fa-fw fa-chevron-left" @click="subtractWeek"></i>
            </div>
            <div class="col-sm-1 centered" v-for="(day, key, index) in days" data-date="">{{day}}<br>{{daysInWeek[key]}}</div>
            <div class="col-sm-2 centered">
                <i class="fa fa-fw fa-chevron-right" @click="addWeek"></i>
            </div>
            <div class="col-sm-1 centered">
                &nbsp;
            </div>
        </div>
        <div class="calendar-header row" v-for="task in tasksRows">
            <div class="col-sm-2 centered">{{task.name}}</div>
            <div class="col-sm-1 centered" v-for="(day, key, index) in days">
                <input style="width:100%;" type="text" :id="task.id" :data-date="daysInWeek[key]" value="" />
            </div>
            <div class="col-sm-2 centered">X</div>
        </div>
    </div>
</template>

<script>
export default {
    data(){
        return{
            today: moment(),
            dateContext: moment(),
            days: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
            tasksRows: [
                {"name": "1 task",  "id": 10 },
                {"name": "2 task",  "id": 20 }
            ]
        }
    },

    computed: {
        year: function () {
            var t = this;
            return t.dateContext.format('Y');
        },
        month: function () {
            var t = this;
            return t.dateContext.format('MMMM');
        },
        currentDate: function () {
            var t = this;
            return t.dateContext.get('date');
        },
        daysInWeek: function() {
            var t = this;
            var x = moment(t.dateContext).startOf('week');
            var days = [];
            days.push(x.get('year')+"-"+("0"+(parseInt(x.get('month'))+1)).slice(-2)+"-"+("0"+x.get('date')).slice(-2));
            for(var c=1;c<=6;c++) {
                x.add(1, 'days');
                days.push(x.get('year')+"-"+("0"+(parseInt(x.get('month'))+1)).slice(-2)+"-"+("0"+x.get('date')).slice(-2));
            }
            console.log(days);
            return days;
        },
        firstDayOfWeek: function () {
            var t = this;
            console.log(moment(t.dateContext).day());
            return moment(t.dateContext).startOf('week');
        },
        initialDate: function () {
            var t = this;
            return t.today.get('date');
        },
        initialMonth: function () {
            var t = this;
            return t.today.format('MMMM');
        },
        initialYear: function () {
            var t = this;
            return t.today.format('Y');
        }
    },

    methods: {
        addWeek: function () {
            var t = this;
            t.dateContext = moment(t.dateContext).add(1, 'week');
        },
        subtractWeek: function () {
            var t = this;
            t.dateContext = moment(t.dateContext).subtract(1, 'week');
        }
    }
}

Notice tasksRows this is the array I want to dynamically extend from different place. The other component is a form. They share same root I hope.

What I want is upon submission from form, is to add to array another entry, then my second template should update based on data.

Upvotes: 2

Views: 117

Answers (1)

Nikolai Borisik
Nikolai Borisik

Reputation: 1511

You should handle modification and store taskRows using parent component and pass it to your component via props. For example

{
      template: `
        <div>
           <task-list :tasks-rows="tasksRows" />
           <form-component @add="add />
        </div>`,
        data(){
          return {
               taskRows: []
          }
        },
    
        methods: {
          add(name, id){
             this.taskRows.push({name, id})
          }
        }
    }

Or you can use event bus for non parent child communication https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

Upvotes: 1

Related Questions