我正在使用Vue、Vuex和Vuetify在数据表中显示课程,并希望将在线编辑作为一项功能.请参阅下面的相关组件代码.

#Courses.vue

<template>
  <v-data-table 
  :headers="headers"
  :items="courses"
  :search="search"
  :loading="loading"
  no-data-text="No Courses Available"
  >

    <template slot="items" slot-scope="props">
      <tr>
        <td>
          <v-edit-dialog
          :return-value.sync="props.item.title"
          lazy
          >
            {{ props.item.title }}
            <v-text-field
            slot="input"
            label="Enter New Course Title"
            v-model="props.item.title"
            single-line
            counter
            @keyup.enter="onUpdateCourse({ id: props.item.id, title: props.item.title})"
            ></v-text-field>
          </v-edit-dialog>
        </td>

        <td>{{ props.item.category }}</td>
        <td>{{ props.item.startDate | date }}</td>
        <td>{{ props.item.endDate | date }}</td>
        <td>{{ props.item.location }}</td>
      </tr>
    </template>
  </v-data-table>
</template>

<script>
  export default {
    data() {
      return {
        headers: [** table headings **],
      };
    },
    computed: {
      courses() {
        return this.$store.getters.courses;
      },
    },
    methods: {
      onUpdateCourse(itemToUpdate) {
        debugger;
        this.$store.dispatch('updateCourse', itemToUpdate);
      },
    },
  };
</script>

它起作用了;但我不同意这种方法直接改变Vuex状态的事实:发送('updateCourse',itemToUpdate'的唯一原因是更新db(在本例中是firestore).我本以为最好是更新$store.仅通过Vuex操作/Mutations 进行状态设置,而不是直接在此处同步.

所以,我的第一个问题是:我应该对此提出异议吗?如果不是,为什么?

因为它让我感到困扰,我在计算部分添加了Vuex courses数组的本地副本:

localCopy() {
  return this.courses.map(x => Object.assign({}, x));
},

并用:items="localCopy"建立了数据表.这允许我从Vuex操作中更新课程,但数据表在我单击应用程序中的其他位置之前不会更新.

所以,我的第二个问题是:如果这是正确的方法,我如何保持组件的react 性?

谢谢你的帮助.

(PS–当剪切和粘贴代码,或在文本框中编辑时,似乎有些双引号"不幸地被转换成了花哨的引号.更不幸的是,我患有诵读困难症,尽管我已经尽了最大努力找到了它们,但我实际上大部分时间都看不到它们.请不要恨我)

推荐答案

要不将更改分配给props.item.title,请执行以下操作:

  • 取下<v-edit-dialog :return-value="props.item.title"中的.sync.
  • v-model替换为<v-text-field :value="props.item.title"中的:value.

.sync has an implicit @return-value:update="props.item.title = $event"v-model has an implicit @input="props.item.title = $event (roughly)一样,仅上述内容(删除.sync并将v-model替换为:value)将阻止title被直接修改.

要通过dispatch对其进行修改,还需要添加一个@input侦听器来调用dispatch:@input="onUpdateCourse({ id: props.item.id, title: props.item.title})".

最后,您的代码应该是这样的:

<td>
  <v-edit-dialog
  :return-value="props.item.title"
  lazy
  >
    {{ props.item.title }}
    <v-text-field
    slot="input"
    label="Enter New Course Title"
    :value="props.item.title"
    @input="onUpdateCourse({ id: props.item.id, title: props.item.title})"
    single-line
    counter
    @keyup.enter="onUpdateCourse({ id: props.item.id, title: props.item.title})"
    ></v-text-field>
  </v-edit-dialog>
</td>

Vue.js相关问答推荐

虚拟DOM在Vue中姗姗来迟

Vue3组合-如何在组件卸载时注销回调

Vue 3组合式API如何测试是否发出正确的事件

当用户在嵌套路由中时激活链接

Nuxt 和 Vite 有什么区别?

使用 Nuxt 动态获取文件夹中的图像路径

Vue.js 和观察者模式

将 Vue 应用程序挂载到主 Vue 应用程序的容器中

是否可以让 html-webpack-plugin 从 css 生成