将Vuex与动态创建的组件结合使用

时间:2019-06-16 01:39:55

标签: vue.js vuejs2 vuex

我想使用Vuex来管理动态创建的组件。在我的应用程序中,我有多个页面,并且每个页面上都有“字段”组件。可以在每个页面上添加多个字段组件。每个字段组件都将具有用户可以编辑的文本字段。我想在用户输入时跟踪这些值,以便状态始终是最新的(例如v-model)。也可以添加多个页面。

我很难找到Vuex跟踪用户添加或删除的新页面和字段组件的方法。

//example of how my state looks
const state = {
    pages: [ 
        {
            id: '1',
            name: 'Contact Information',
            fields: [ 
                {
                    name: 'First Name',
                    type: 'text-field',
                    required: true
                }
            ]
        },
        {
            id: '2',
            name: 'Activities',
            fields: [ 
                {
                    name: 'Summary',
                    type: 'textarea-field',
                    required: true
                }
            ]
        }
    ]
}
//pages are just tabs
<a @click="addPage">Add Page</a>
<ul class="nav nav-tabs" data-tabs="tabs">
    <li class="nav-item"  v-for="(page,key) in allPages" :key="key">
         <a class="nav-link" data-toggle="tab">
         {{page.name}}
         </a>
    </li>
</ul>

//example of how the field html looks
<div class="tab-pane" v-for="(page, key) in allPages" :key="key">
     <div v-for="(field, key) in page.fields" :key="key">
          <page-field :value="field.name" :type="field.type"/>
     </div>
     <a @click="addField">Add Field</a>
</div>

//field component example
<template>
<div>
    <input type="text"> //I want to keep track of this input with Vuex every time a new field component is added
</div>
</template>

每次添加新页面或字段组件时;或当有人在字段组件内的文本字段中键入内容时,我希望更新我的状态。

1 个答案:

答案 0 :(得分:0)

您可以添加一个input事件处理程序,该处理程序调用Vuex变异来设置页面字段...

  1. 在商店中,将fields数组元素更新为包含value属性,该属性将保存用户输入:
/* store.js */
const state = {
  pages: [
    {
      // ...
      fields: [
        {
          // ...
          value: null ?
        }
      ]
    },
    {
      // ...
      fields: [
        {
          // ...
          value: null ?
        }
      ]
    }
  ]
}
  1. 还添加一个设置页面字段的Vuex突变:
/* store.js */
const mutations = {
  SET_PAGE_FIELD(state, { pageId, fieldName, fieldValue }) {
    const page = state.pages.find(page => page.id === pageId)
    if (page) {
      const field = page.fields.find(field => field.name === fieldName)
      if (field) {
        field.value = fieldValue
      }
    }
  }
}

export default new Vuex.Store({
  state,
  mutations ?
})
  1. 更新page-field的输入元素以发出带有目标值的input事件:
/* PageField.vue */
<template>
  <div class="page-field">
    <input @input="$emit('input', $event.target.value)" ...> ?
    <textarea @input="$emit('input', $event.target.value)" .../> ?
  </div>
</template>
  1. 通过更改商店中的页面字段(通过步骤2中的更改)来处理父项中的input事件:
/* App.vue */
<template>
  <div class="tab-pane" v-for="page in allPages" :key="page.id">
    <div v-for="field in page.fields" :key="field.name">
      <page-field
        @input="setField(page.id, field.name, $event)" ?
        :type="field.type"
      />
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    setField(pageId, fieldName, fieldValue) {
      this.$store.commit('SET_PAGE_FIELD', { ?
        pageId,
        fieldName,
        fieldValue
      });
    }
  }
}
</script>

Edit Using v-model with Vuex state