【问题标题】:How To Properly Initialize Form Data In VueVue中如何正确初始化表单数据
【发布时间】:2019-04-09 06:08:33
【问题描述】:

所以我有一个渲染表单的组件,它还使用从 ajax 请求接收到的数据预填充字段。

我的问题是,我不仅希望能够编辑字段,还希望同时添加要提交的新字段,因此我正在尝试将我的预填充数据和新数据初始化为与我的 ajax 请求一起提交的相同对象。在我当前的设置下,表单数据在呈现表单之前并没有始终如一地填写字段。

这是表单模板

<form @submit.prevent="editThisWorkflow" class="d-flex-column justify-content-center" >

 <div>
   <input type="text" v-model="workflowData.workflow">
    </div>
    <div >
    <div v-for="object in workflowData.statuses" :key="object.id">
    <input type="text" v-model="object.status">
    </div>
    <div v-for="(status, index) in workflowData.newStatuses" :key="index">
    <input type="text" placeholder="Add Status" v-model="status.value">
    <button type="button" @click="deleteField(index)">X</button>
    </div>
    <button type="button" @click="addField">
      New Status Field
    </button>
    </div>
    <div>
    <div>
    <button type="submit">Save</button>
    <router-link  :to="{ path: '/administrator/workflows'}" >Cancel</router-link>
  </div>
 </div>

</form>

这是脚本

data() {
        return {
            workflowData: {
                id: this.$store.state.workflow.id,
                workflow: this.$store.state.workflow.workflow,
                statuses: this.$store.state.workflow.statuses,
                newStatuses: []
            },
            workflowLoaded: false
        }
    },
    computed: {
    ...mapGetters(['workflow']),
  },
  methods: {
    ...mapActions(['editWorkflow']),
    editThisWorkflow() {
        this.editWorkflow({
           id: this.workflowData.id,
           workflow: this.workflowData.workflow,
           statuses: this.workflowData.statuses,
           newStatuses: this.workflowData.newStatuses
        })
    },
    addField() {
        this.workflowData.newStatuses.push({ value: ''});
    },
    deleteField(index) {
        this.workflowData.newStatuses.splice(index, 1);
    }

这是提交数据的store方法

editWorkflow(context, workflowData) {
      axios.patch('/workflowstatuses/' + workflowData.id, {
        workflow: workflowData.workflow,
        statuses: workflowData.statuses,
        newStatuses: workflowData.newStatuses
      })
      .then(response => {
          context.commit('editWorkflow', response.data)
      })
      .catch(error => {
          console.log(error.response.data)
      })           
    },

我的问题来了

 data() {
        return {
            workflowData: {
                id: this.$store.state.workflow.id,
                workflow: this.$store.state.workflow.workflow,
                statuses: this.$store.state.workflow.statuses,
                newStatuses: []
            },
            workflowLoaded: false
        }
    },

有没有更好的方法来设置这部分?

workflowData: {
    id: this.$store.state.workflow.id,
    workflow: this.$store.state.workflow.workflow,
    statuses: this.$store.state.workflow.statuses,
    newStatuses: []
},

【问题讨论】:

    标签: forms vue.js vuex v-model


    【解决方案1】:

    如果您只需要为表单分配一次存储值,那么您可以使用挂载函数。

    mounted: function() {
       this.id = this.$store.state.workflow.id
       this.workflow = this.$store.state.workflow.workflow
       this.statuses = this.$store.state.workflow.statuses
    },
    data() {
          return {
              workflowData: {
                  id: '',
                  workflow: '',
                  statuses: '',
                  newStatuses: []
              },
              workflowLoaded: false
          }
     },
    

    【讨论】:

    • 所以数据被正确挂载,但是并不一致。希望我能正确解释这一点,但是当我取消表单并选择要编辑的不同工作流时,它会使用以前的工作流数据填充表单。但是,如果我再次取消并重新选择相同的工作流程,它将正确填充表单...
    【解决方案2】:

    data 属性不接受这个,我通常在这个问题中使用箭头函数,因为它禁止我使用 this,并且禁止我的团队在数据中也使用 this。 在数据中声明所有必要的项目以保持反应性,并在已加载的页面中分配值。

    mounted() {
       this.workflowData.id = this.$store.state.workflow.id
       this.workflowData.workflow = this.$store.state.workflow.workflow
       this.workflowData.statuses = this.$store.state.workflow.statuses
    },
    
    data: () => ({
       workflowData: {
                    id: '',
                    workflow: '',
                    statuses: '',
                    newStatuses: []
                },
                workflowLoaded: false
            }
        },
    })
    

    【讨论】:

    • 所以数据被正确挂载,但是并不一致。希望我能正确解释这一点,但是当我取消表单并选择要编辑的不同工作流时,它会使用以前的工作流数据填充表单。但是,如果我再次取消并重新选择相同的工作流程,它将正确填充表单...
    【解决方案3】:

    事实证明,我解决此问题的方法比这里介绍的大多数解决方案都简单。由于 Vuejs 的生命周期,我发现很难从 this.$store.state 获取数据。并且为v-mode 赋值是不可能的,因为"v-model will ignore the initial value, checked or selected attributes found on any form elements. It will always treat the Vue instance data as the source of truth."

    解决方案

    使用从 ajax 请求接收到的数据预填充字段,例如电子邮件类型的输入字段我做了如下。

    第一个。我将 ajax 请求的输出保存在应用程序的存储(Cookie)中 - 它可以是本地存储或会话,取决于适合您的方式。

    第二次。我用我的应用程序存储中的数据填充了我的Vuex's store (single source of truth)。我每次重新加载页面时都会这样做。

    3rd. 而不是在 Vuejs 生命周期中将数据绑定到 v-model,或者使用 html 输入 (&lt;input type="email" value="email@example.com"&gt;) 的 value 属性。我通过使用来自 Vuex 存储的数据填充 html 的 placeholder 属性 来预填充输入,如下所示:

    <input v-model="form.input.email" type="email" name="email" v-bind:placeholder="store.state.user.data.email">
    

    【讨论】:

    • 你怎么能说这种方法简单?
    猜你喜欢
    • 2021-02-21
    • 2022-08-11
    • 2021-09-07
    • 2017-10-24
    • 2020-09-25
    • 2014-10-15
    • 2022-01-01
    • 2010-11-11
    • 1970-01-01
    相关资源
    最近更新 更多