基于数组值的动态 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 数据,并使用 input
或 change
事件来调用这个变异方法。
否则,如果您只想在用户按下保存按钮后应用更改(例如),那么您不能将 documentTags 用作计算数据。您需要将 documentTags
值复制到本地数据 userDocumentTags
。我想你可以在你的 mounted
挂钩中这样做:
mounted() {
this.userDocumentTags = [...this.$store.getters['documentTags']];
}
不幸的是,我无法在我的机器上重现这个例子,所以我不确定它是否有效。也许你应该打开一个新问题,询问具体解决这个新问题的最佳方法是什么。
我正在开发一种模态形式,它将显示多个 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 数据,并使用 input
或 change
事件来调用这个变异方法。
否则,如果您只想在用户按下保存按钮后应用更改(例如),那么您不能将 documentTags 用作计算数据。您需要将 documentTags
值复制到本地数据 userDocumentTags
。我想你可以在你的 mounted
挂钩中这样做:
mounted() {
this.userDocumentTags = [...this.$store.getters['documentTags']];
}
不幸的是,我无法在我的机器上重现这个例子,所以我不确定它是否有效。也许你应该打开一个新问题,询问具体解决这个新问题的最佳方法是什么。