基于数组值的动态 Vuetify 文本框或 Select

Dynamic Vuetify Textbox or Select based on Array Values

我正在开发一种模态形式,它将显示多个 v-select or v-text-field...但是,这些元素的数量和类型是从数据库中提取的,这意味着 vuetify 代码可以创建元素需要是动态的。首先,我有一个 json 对象,它是从描述每个输入元素的数据库返回的。如果输入是 v-select,则名为 InputType 的 json 属性 设置为 'Combobox'。如果它是一个 v-text-field,那么 InputType 设置为 'Textbox'。这是一个示例。

{
  tags: [
    {
      TagDefinitionId: '1',
      InputType: 'Combobox',
      Name: 'Tag1',
      TagValueOptions: [
        {
          Value: 'Option 1',
        },
        {
          Value: 'Option 2',
        },
        {
          Value: 'Option 3',
        },
      ],
    },
    {
      TagDefinitionId: '2',
      InputType: 'Textbox',
      Name: 'Project Name',
      TagValueOptions: [],
    },
  ],
}

然后,我使用 vuex 将模式中的状态映射到名为 documentTags.

的值
<script>
import { mapState } from 'vuex';

export default {
  name: 'MyModal',
  computed: {
    ...mapState(['documentTags']),
  },
};
</script>

现在,在我的模式 vuetify 模板中,我知道如何为我的 documentTags 数组中的元素数量创建单独的列。我可以这样做:

<template>
  <v-dialog v-model="show" max-width="600px">
    <v-row>
      <v-col
        v-for="n in this.documentTags.tags.length"
        :key="n"
        cols="18"
        sm="8"
        md="6"
      >
        <v-card class="pa-2" outlined tile>
          This v-card needs to be replaced with a v-select or v-text-field
        </v-card>
      </v-col>
    </v-row>
  </v-dialog>
</template>

但是,我真的不知道如何遍历我的 documentTags 数组并确定哪个元素(即 v-select 或 v-text-field ) 需要使用 Vue and/or Vuetify 语法放置在适当的列中。任何人都可以提供有关如何完成此操作的指导吗?

更新

因此,我根据 Leonardo 的建议(有效)更新了我的代码,但现在我 运行 遇到了问题。我不知道如何将标签名称分配给每个输入对象的标签。我以为我可以尝试 'tag.Name' 之类的方法,但这不起作用。有什么想法吗?

<template>
  <v-dialog v-model="show" max-width="600px">
    <v-row>
      <v-col
        v-for="tag in this.documentTags.tags"
        :key="tag.TagDefinitionId"
        cols="18"
        sm="8"
        md="6"
      >
        <v-select
          v-if="tag.InputType === 'Combobox'"
          :items="tag.TagValueOptions"
          item-text="Value"
          label="tag.Name"
          required
        >
        </v-select>
        <v-text-field
          v-else-if="tag.InputType === 'Textbox'"
           label="tag.Name"
           required
        >
        </v-text-field>
      </v-col>
    </v-row>
  </v-dialog>
</template>

更新2

有谁知道如何从 v-select 或 v-text-field 访问值,因为这些元素是动态创建的?通常,我会使用 v-model="name" 之类的东西,然后在 中声明 name 属性 ]data 道具部分...但是,我不确定在这种情况下该怎么做。理想情况下,我想将输入打包到带有标签名称及其值的 JSON 对象中。所以,以这样的例子为例(假设我们在这个场景中有两个标签)。

"userDocumentTags": [{
    "Name": "Project Name",
    "Value": "My Project Name"
   },{
    "Name": "Project Number",
    "Value": "0001"
  }
]

我想我可以通过做这样的事情来绑定 属性:

<v-select
  v-if="tag.InputType === 'Combobox'"
  :v-model="tag.Name"
  :items="tag.TagValueOptions"
  item-text="Value"
  label="tag.Name"
  required
></v-select>

在我的数据道具部分,我有这样的东西:

data: () => ({
  userDocumentTags: [],   
}),

但是,我不知道如何将名称和值对推送到 userDocumentTags 对象中。有人可以在这里提供任何指导吗?

您可以尝试这样的操作:

<template>
  <v-dialog v-model="show" max-width="600px">
    <v-row>
      <v-col
        v-for="tag in this.documentTags.tags"
        :key="tag.TagDefinitionId"
        cols="18"
        sm="8"
        md="6"
      >
        <v-select v-if="tag.InputType === 'Combobox'">
           // you can customize this v-select
        </v-select>
        <v-text-field v-else-if="tag.InputType === 'Textbox'">
           // you can customize this v-text-field
        </v-text-field>
      </v-col>
    </v-row>
  </v-dialog>
</template>

更新:

嘿伙计,关于你的新疑问,在 vue.js 中,当你需要将变量作为属性传递时,你应该使用 :attribute="var".

检查一些示例:

label="tag.Name" // label is equal a string "tag.Name"
label="7" // label is equal a string "7"
:label="tag.Name" // label is equal a value of tag.Name
:label="7" // label is equal a number 7

在你的情况下,将 label="tag.Name" 切换为 :label="tag.Name"

还有一件事... 在您的模板中,您不需要使用指令 this 来访问您的数据值。在您的 for 语句中尝试使用 v-for="tag in documentTags.tags"

更新2

如果您想为所有应用程序“实时”应用更改,您可以使用这种方式:
https://vuex.vuejs.org/guide/forms.html#form-handling

您将创建一个变异方法来更新您的 vuex 数据,并使用 inputchange 事件来调用这个变异方法。

否则,如果您只想在用户按下保存按钮后应用更改(例如),那么您不能将 documentTags 用作计算数据。您需要将 documentTags 值复制到本地数据 userDocumentTags。我想你可以在你的 mounted 挂钩中这样做:

mounted() {
   this.userDocumentTags = [...this.$store.getters['documentTags']];
}

不幸的是,我无法在我的机器上重现这个例子,所以我不确定它是否有效。也许你应该打开一个新问题,询问具体解决这个新问题的最佳方法是什么。