动态 Vuetify 文本框或基于数组值选择

Posted

技术标签:

【中文标题】动态 Vuetify 文本框或基于数组值选择【英文标题】:Dynamic Vuetify Textbox or Select based on Array Values 【发布时间】:2021-08-07 23:58:21 【问题描述】:

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


  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->
    <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 数组并使用Vue 和/或 Vuetify 语法。任何人都可以就如何做到这一点提供指导吗?

更新

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

<template>
  <v-dialog v-model="show" max->
    <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" 之类的东西,然后在 data 属性部分中声明 name 属性......但是,我不确定在这种情况下该怎么做。理想情况下,我想将输入打包到带有标签名称及其值的 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 对象中。任何人都可以在这里提供任何指导吗?

【问题讨论】:

【参考方案1】:

你可以试试这样的:

<template>
  <v-dialog v-model="show" max->
    <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']];

不幸的是,我无法在我的机器上重现这个示例,所以我不确定它是否会起作用。也许您应该提出一个新问题,询问具体解决这个新问题的最佳方法是什么。

【讨论】:

我有最后一个跟进问题。如何将这些组合框或文本字段的值绑定到可以在我的方法中使用的属性?通常,我会做类似v-model="option" 的操作,然后在我的data 属性中声明option。但是,由于这些组件是动态的(这意味着我不完全知道元素的数量或它们在编译时间之前的数量)......我真的不知道如何访问这些值。能否指点一下? @andyopayne 我不确定这次能不能帮到你。也许你应该提出一个关于它的新问题。

以上是关于动态 Vuetify 文本框或基于数组值选择的主要内容,如果未能解决你的问题,请参考以下文章

将动态文本框向上移动(如果它换行),以阻止它覆盖下面的下一个文本框或

如何动态更改 C# 组合框或文本框中的自动完成条目?

如何在选择框内垂直对齐文本? (不是在谈论选择框或 div 框)

基于动态选择启用文本框并对文本框应用验证

使用 vuetify 规则进行验证的时间

如何允许用户在他选择的位置拖动动态创建的控件