Vue/Nuxt 是否有合适的模式来加载和编辑没有生命周期钩子的组件数据

Vue/Nuxt is there a proper pattern for loading and editing component data without lifecycle hooks

用例:我有一个包含数据表的组件,它列出了应用程序,我单击一行,它打开了一个组件,其中包含适当加载的字段(新建或编辑)。

问题:一个组件加载了我可以在组件中绑定到的新数据或现有数据的 ** 引用 **。因为不是副本,所以无法编辑。

代码快速解释: New() 调用 Open(),两者都加载 Component ViewApplication。

数据表组件

<template>
  <div id="inspire" data-app>
      <v-card>
        <v-banner single-line>
              <v-btn @click="New">New</v-btn>
        </v-banner>
        <v-card>
          <v-layout>
            <v-list-item>
              <v-list-item-content>
                <v-row>
                  <v-col>
                    <v-data-table
                      :items="items"
                      return-object
                      @click:row="Open"
                    >
                      <template #top>
                        <v-dialog v-model="dialog" max-width="600">
                          <ViewApplication
                            :loadedapp="loaded"
                            @reload="Load"
                            @close="close"
                          />

                        </v-dialog>
                      </template>
                    </v-data-table>
                  </v-col>
                </v-row>
              </v-list-item-content>
            </v-list-item>
          </v-layout>
        </v-card>
      </v-card>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
export default {
  data: () => ({
    dialog: false,
    items: this.LoadApplications(),
  }),
  computed: {
    ...mapGetters({
      applications: 'modules/Manage/getApplications',
    }),
  },
  methods: {
    ...mapActions({ LoadApplications: 'modules/Manage/LoadApplication' }),
    Open(item) {
      console.log('Open item: ' + item)
      this.loaded = item
      this.$store.commit('modules/Manage/setApplication', item)
      this.dialog = true
    },
    New() {
      let item = { app_name: '', roles: `[]`, api: '' }
      this.Open(item)
    },

  },
}
</script>

ViewApplication 组件

<template>
  <v-card v-if="loadedapp">
    <v-col>
      <v-text-field v-model="app_name" dense label="Application Name" />
      <v-row>
        <v-col col="6">
          <v-text-field
            v-model="role"
            label="Role"
            :append-outer-icon="'mdi-send'"
            @click:append-outer="roles.push(role)"
          />
        </v-col>
        <v-col col="6">
          <v-select
            v-model="roles"
            :items="roles"
            :menu-props="{ maxHeight: '400' }"
            label="Roles"
            multiple
          ></v-select>
        </v-col>
      </v-row>

      <v-text-field v-model="api" dense label="API" />
    </v-col>
    <v-card-actions>Save, Delete</v-card-actions>
  </v-card>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  props: {
    loadedapp: {
      type: Object,
      default: () => {
        return { app_name: '', roles: `[]`, api: '' }
      },
    },
  },
  data() {
    return {
      localapp1: this.getApp,
      localapp2: { ...this.getApp },
      localapp3: this.loadedapp,
      localapp4: { ...this.loadedapp },
      role: '',
      app_name: '',
      roles: [],
      api: '',
    }
  },
  computed: {
    ...mapGetters({
      path: 'modules/Auth/gutCustomerURL',
      getApp: 'modules/Manage/getApp',
    }),
  },
}
</script>

发现这些链接很有帮助: https://vuex.vuejs.org/guide/forms.html https://markus.oberlehner.net/blog/form-fields-two-way-data-binding-and-vuex/

实际解决方案:

  props: {
    loadedapp: {
      type: Object,
      default: () => {
        return { app_name: '', roles: `[]`, api: '' }
      },
    },
  },
  data() {
    return {
      role: '',
      app_name: '',
      roles: [],
      api: '',
    }
  },
  watch: {
    loadedapp: {
      immediate: true,
      handler() {
        this.init()
      },
    },
  },
  methods: {
    init() {
      if (this.loadedapp) {
        this.app_name = this.loadedapp.app_name
        this.roles = JSON.parse(this.loadedapp.roles)
        this.api = this.loadedapp.api
      }
    },}