如何在 vuetify 组合框中添加项目并维护 v-model JSON 结构

How to have add items in vuetify combobox and maintain v-model JSON structure

我有一个 vuetify 组合框,我将 v-model 设置为某个 JSON 数组,该数组具有 属性“EMAIL_ADDRESS”和关联的电子邮件地址。如果我使用这个 v-model 中已经存在的项目,数据格式与原始 JSON 数组匹配,我也设置它的值:

[
  {
    "EMAIL_ADDRESS": "testemail1@mail.com"
  },
  {
    "EMAIL_ADDRESS": "testmail2@mail.com"
  }
]

如果我将一个项目添加到组合框中,这可能会发生,因为它是一个发送电子邮件表单。该数组不维护原始项数组的 v-model 结构,如下所示:

[
  {
    "EMAIL_ADDRESS": "testemail1@mail.com"
  },
  "addedemail@mail.com",
  "addedemail2@gmail.com"
]

有没有什么方法可以维护项目数组的结构,以便它实际上将新值推送到该数组?

<v-combobox label="To"                                                                          
            v-model="emailToModel"
            required
            multiple
            :items="emailTo"
            item-text="EMAIL_ADDRESS"
            class="ma-3"
            filled
            dense
            return-object
            hide-details="auto">
</v-combobox>

您可以简单地通过迭代 emailToModel 数组来实现它,并根据类型检查将字符串转换为对象,然后将其推入 emailTo 数组。

演示 :

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      emailToModel: [
        {
          "EMAIL_ADDRESS": "testemail1@mail.com"
        },
        {
          "EMAIL_ADDRESS": "testmail2@mail.com"
        }
      ],
      emailTo: []
    }
  },
  mounted() {
    this.emailTo = this.emailToModel
  },
  methods: {
    getUpdatedValue() {
      this.emailToModel = this.emailToModel.map(item => {
        if (typeof item !== 'object') {
          const newObj = {
            "EMAIL_ADDRESS": item
          };
          item = newObj
          this.emailTo.push(newObj);
        }
        return item;
      })
      console.log(this.emailToModel);
    }
  }
})
<script src="https://unpkg.com/vue@2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@2.6.6/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify@2.6.6/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/@mdi/font@6.x/css/materialdesignicons.min.css"/>
<div id="app">
  <v-app id="inspire">
    <v-container fluid>
          <v-combobox
            label="To"
            v-model="emailToModel"
            item-text="EMAIL_ADDRESS"
            :items="emailTo"
            multiple
            filled
            dense
            hide-details="auto"
            @change="getUpdatedValue"
          ></v-combobox>
    </v-container>
  </v-app>
  
  <pre>{{ emailToModel }}</pre>
</div>

更新: 根据作者的评论,创建一个通用的通用方法,该方法将动态更新模型和项目值,而不考虑任意数量的组合框。

演示 :

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      emailToModel: [
        {
          "EMAIL_ADDRESS": "testemail1@mail.com"
        },
        {
          "EMAIL_ADDRESS": "testmail2@mail.com"
        }
      ],
      emailCcModel: [
        {
          "EMAIL_ADDRESS": "testemailCc1@mail.com"
        }
      ],
      emailTo: [],
      emailCc: []
    }
  },
  mounted() {
    this.emailTo = this.emailToModel
    this.emailCc = this.emailCcModel
  },
  methods: {
    getUpdatedValue(modelValue, comboboxItems) {
      this[modelValue] = this[modelValue].map(item => {
        if (typeof item !== 'object') {
          const newObj = {
            "EMAIL_ADDRESS": item
          };
          item = newObj
          this[comboboxItems].push(newObj);
        }
        return item;
      })
    }
  }
})
<script src="https://unpkg.com/vue@2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@2.6.6/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify@2.6.6/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/@mdi/font@6.x/css/materialdesignicons.min.css"/>
<div id="app">
  <v-app id="inspire">
    <v-container fluid>
          <v-combobox
            label="To"
            v-model="emailToModel"
            item-text="EMAIL_ADDRESS"
            :items="emailTo"
            multiple
            filled
            dense
            hide-details="auto"
            @change="getUpdatedValue('emailToModel', 'emailTo')"
          ></v-combobox>
    </v-container>
    
     <v-container fluid>
          <v-combobox
            label="Cc"
            v-model="emailCcModel"
            item-text="EMAIL_ADDRESS"
            :items="emailCc"
            multiple
            filled
            dense
            hide-details="auto"
            @change="getUpdatedValue('emailCcModel', 'emailCc')"
          ></v-combobox>
    </v-container>   
  </v-app>
</div>