javascript - Vue 与 VCalendar 组件 : Keep data in sync with another Vue instance

标签 javascript vue.js vuejs2 vue-component

我正在编写一个在表格中显示 session 列表的页面。还可以编辑和删除 session 。现在我想使用 VCalendar 提供替代 View .

页面加载时从服务器接收数据并将其存储在 JS 变量中。包含该表的 Vue 实例和 VCalendar 组件都共享此数据。如果我编辑表格单元格,更改将反射(reflect)在组件中。 但是当我删除表格 View 中的日期时,它仍保留在日历中。

这是相关的 HTML(编辑:向 td 添加了一些属性):

<calendar-component></calendar-component>

<table id='meetings-table'>
    <tr v-for='meeting in meetings' :key='date.id'>
        <td contenteditable @blur='handleInput($event,meeting,"name")>
            @{{ meeting.name }}
        </td>
        <td>
            <input type='checkbox' v-model='selected'
                   :value='meeting.id'>
        </td>
    </tr>
</table>

<div>
    <button v-if='selected.length' @click='deleteMeetings'>
        Delete selected rows
    </button>
</div>

我的JS(编辑:添加了handleInput方法):

let table = new Vue({
    el:'#meetings-table',
    data: {
        selected:      [],
        meetings:  window.meetings,
    },
    methods: {
        /**
         * Deletes selected meetings.
         */
        deleteMeetings: function () {
            let requests = [];

            // Make a single request and store it
            for (let id of this.selected) {
                requests.push(axios.delete('/termine/' + id)
                    .then(response => {
                        // Remove meetings
                        this.meetings = this.meetings.filter(t => t.id != id);
                        // Remove id from list of selected meetings
                        this.selected = this.selected.filter(elem => elem != id);
                    }));
            }

            const axiosArray = axios.all(requests);
        },
        /**
        * Handles edits in table cells.
        */
        handleInput: function($event, meeting, field) {
            const newValue = $event.target.textContent;

            // Update value in $data
            meeting[field] = newValue;

            // AJAX request follows, but is not necessary for this example to work
        }

    }
});

组件的相关部分:

<template>
  <v-calendar :attributes='attributes'>

    <div
      slot='meeting-row'
      slot-scope='{ customData }'>
      <!-- Popover content omitted -->
    </div>

  </v-calendar>
</template>

<script>

let meetings = window.meetings;

export default {
  data() {
    return {
      incId: meetings.length,
      editId: 0,
      meetings,
    };
  },
  computed: {
    attributes() {
      return [
        // Today attribute
        {
          // ...
        },
        // Meeting attributes
        ...this.meetings.map(meeting => ({
          key: meeting.id,
          dates: new Date('2018,11,31'),// moment(meeting.slot.date, 'DD.MM.YY').format('YYYY, MM, DD'), //meeting.dates,
          customData: meeting,
          order: meeting.id,
          dot: {
            backgroundColor: '#ff8080',
          },
          popover: {
            // Matches slot from above
            slot: 'meeting-row',
          }
        }))
      ];
    }
  }
};
</script>

这就是发生的事情:

  • 我加载仅包含一次 session 的页面。 session 是 显示在表格和日历组件中。 Vue 开发工具展示 它在两个 meetings 数组中(在组件中以及在其他数组中) Vue 实例)。使用控制台,我还可以在 window.meetings
  • 点击删除按钮(触发我的 JS 中的 deleteMeetings 方法)后, session 从表格中消失,但仍保留在 日历,在组件的 meetings 数组中和 window.meetings

即使在删除表中的 session 时,我也必须更改哪些内容才能保持 session 数组同步?请注意,我尚未为日历组件实现任何方法。

最佳答案

日历和表格组件应共享一个状态:当前选定的 session 。据我了解,现在您在 2 个不同的位置拥有该状态:table Vue 实例和 calendar-component,它是其他 Vue 实例的子级。

看起来您已经在共享状态(使用 window.meetings),但事实并非如此:您仅在创建组件时初始化同一组 session 。然后一个组件中的更改不会反射(reflect)在另一组件中。

您可以尝试做的是将 session 存储在页面上的“主”Vue 应用程序中,将它们作为 Prop 传递给表和日历组件,然后在修改 session 数组时触发表和日历组件中的事件。您还应该在“主”Vue 应用程序中定义事件处理程序,并监听组件。解决方案的粗略草图:

<div id="app">
    <table-component
        :meetings="meetings" 
        @meetingUpdated="handleMeetingUpdate" 
        @meetingDeleted="handleMeetingDeletion"
    ></table-component>
    <calendar-component 
        :meetings="meetings" 
        @meetingUpdate="handleMeetingUpdate" 
        @meetingDeleted="handleMeetingDeletion"
    ></calendar-component>
</div>

let app = new Vue({
    el:'#app',
    data: {
        meetings: []
    },
    methods: {
        handleMeetingUpdate(event) {
            //
        },
        handleMeetingDeletion(event) {
            //
        },
    }
    //
});

我希望以上内容足以为您指明正确的方向。如果没有,请告诉我,我会尽力进一步帮助您。

关于javascript - Vue 与 VCalendar 组件 : Keep data in sync with another Vue instance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53812455/

相关文章:

javascript - 获取 <TD> 的内容并使用 jQuery/JS 对其进行相应的乘法/除法

javascript - Vue.js2 - $emit 事件未被父组件捕获

javascript - 通过VueJS中的多个复选框将平面数组添加到v模型

javascript - 在属性中显示 react 组件名称

javascript - D3.js 在 Mozilla Firefox 上无法正确呈现

javascript - 如何摆脱 Chrome 控制台中的 VM 行?

typescript - typescript 中可选的必需参数

javascript - Vue.js - 在 Vuex 模块中获取当前路由

javascript - 使用 Vue 在表的 td 内显示 Div 不是 react 性的

javascript - Cordova cordova-plugin-qrscanner : Opaque camera view