使用 Vue3 在下拉列表 select 上填充新输入
Populate new inputs on dropdown select with Vue3
我需要有关使用 Vue 3 在表单上填充一些输入字段的帮助。当用户 select 在我的下拉列表中选择一个选项时,表单应该输出必要的输入。相反,它会显示每个选项的所有输入。
这是我的 select 下拉菜单
<select
v-model="selectedInverter"
@change="onChange($event)" >
<option
v-for="(item, index) in options"
:value="item.inverter"
:key="index" >
{{ item.inverter }}
</option>
</select>
这是我的选择
export default {
name: "ExampleOptions",
data() {
return {
address: "",
stakeAddress: "",
selectedInverter: null,
addressError: "",
apiKey: null,
filteredOptions: "",
options: [
{
inverter: "None",
options: []
},
{
inverter: "Eagle",
options: [
{
name: "Cloud ID",
value: null,
description:
"The Rainforest cloud id used to access your system data",
type: "text",
required: true
},
{
name: "User",
value: null,
description: "The Rainforest cloud username",
type: "text",
required: true
},
{
name: "Password",
value: null,
description: "The Rainforest cloud password",
type: "password",
required: true
}
]
},
{
inverter: "Efergy",
options: [
{
name: "Token",
value: null,
description: "The Efergy token used to access your system data",
type: "text",
required: true
},
{
name: "Power",
value: null,
description:
"The Efergy power key, usually 'PWER' or 'PWER.1234' where 1234 is the sid",
type: "text",
required: true
}
]
}
]
};
},
这是我的代码笔示例:https://codepen.io/pistell/pen/BaJPjgq
如您所见,所有下拉示例始终显示。我怎样才能让 selected 在下拉列表中显示?如果有影响的话,我也在使用 Tailwind CSS。
如果我没理解错的话,试试下面的代码片段:
new Vue({
el: "#demo",
data() {
return {
address: "",
stakeAddress: "",
selectedInverter: null,
addressError: "",
apiKey: null,
filteredOptions: "",
// TODO: Create a way to iterate over these values and populate the HTML elements that go along with each of these
//
options: [
{
inverter: "None",
options: []
},
{
inverter: "Eagle",
options: [
{
name: "Cloud ID",
value: null,
description:
"The Rainforest cloud id used to access your system data",
type: "text",
required: true
},
{
name: "User",
value: null,
description: "The Rainforest cloud username",
type: "text",
required: true
},
{
name: "Password",
value: null,
description: "The Rainforest cloud password",
type: "password",
required: true
}
]
},
{
inverter: "Efergy",
options: [
{
name: "Token",
value: null,
description: "The Efergy token used to access your system data",
type: "text",
required: true
},
{
name: "Power",
value: null,
description:
"The Efergy power key, usually 'PWER' or 'PWER.1234' where 1234 is the sid",
type: "text",
required: true
}
]
}
]
};
},
computed: {
computed_items() {
const selected = this.selectedInverter;
return this.options.filter((item) => item.inverter.includes(selected));
}
},
methods: {
async registerInverter() {
this.addressError = this.address.length > 1 ? "" : "Not a valid address";
if (!this.addressError) {
await this.validateAddress();
// Values to send to Firebase
console.log({
address: this.address,
api_key: this.apiKey,
date_registered: new Date().toUTCString(),
inverter: this.selectedInverter,
stake_address: this.stakeAddress
});
}
},
async validateAddress() {
// Evaluate the address and check if its valid
console.log(this.address);
return this.address;
},
onChange(event) {
this.selectedInverter = event.target.value;
}
}
})
.error {
color: red;
margin-top: 10px;
font-size: 0.8rem;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div class="flex items-center justify-center">
<div class="w-full max-w-md">
<form
class="bg-white shadow-lg rounded px-12 pt-6 pb-8 mb-4"
@submit.prevent="registerInverter"
>
<!-- @csrf -->
<div
class="text-gray-800 text-2xl flex justify-center border-b-2 py-2 mb-4"
>
Register your Inverter
</div>
<div class="mb-4">
<label
class="block text-gray-700 text-sm font-normal mb-2"
for="address"
>
Wallet Address
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="address"
v-model="address"
type="text"
required
autofocus
placeholder="Input your address"
/>
<div v-if="addressError" class="error">{{ addressError }}</div>
</div>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-normal" for="inverter">
Inverter Model
</label>
<div class="inline-block relative w-full py-4 flex-1">
<select
class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
v-model="selectedInverter"
@change="onChange($event)"
>
<option
v-for="(item, index) in options"
:value="item.inverter"
:key="index"
>
{{ item.inverter }}
</option>
</select>
<div
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"
>
<svg
class="fill-current h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
width="20px"
>
<path
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
/>
</svg>
</div>
</div>
</div>
<div class="mb-4">
<div
v-for="(item, index) in computed_items"
:value="item.inverter"
:key="index"
>
<h2>{{ item.inverter }}</h2>
<div
v-for="(item, index) in item.options"
:value="item.name"
:key="index"
>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline mt-1 mb-1"
:name="item.name"
:type="item.type"
:required="item.required"
:placeholder="item.description"
/>
</div>
</div>
</div>
<div class="registerButton">
<button
class="px-4 py-2 rounded text-white inline-block shadow-lg bg-blue-500 hover:bg-green-500 focus:bg-blue-700"
type="submit"
>
Register
</button>
</div>
</form>
</div>
</div>
</div>
我需要有关使用 Vue 3 在表单上填充一些输入字段的帮助。当用户 select 在我的下拉列表中选择一个选项时,表单应该输出必要的输入。相反,它会显示每个选项的所有输入。
这是我的 select 下拉菜单
<select
v-model="selectedInverter"
@change="onChange($event)" >
<option
v-for="(item, index) in options"
:value="item.inverter"
:key="index" >
{{ item.inverter }}
</option>
</select>
这是我的选择
export default {
name: "ExampleOptions",
data() {
return {
address: "",
stakeAddress: "",
selectedInverter: null,
addressError: "",
apiKey: null,
filteredOptions: "",
options: [
{
inverter: "None",
options: []
},
{
inverter: "Eagle",
options: [
{
name: "Cloud ID",
value: null,
description:
"The Rainforest cloud id used to access your system data",
type: "text",
required: true
},
{
name: "User",
value: null,
description: "The Rainforest cloud username",
type: "text",
required: true
},
{
name: "Password",
value: null,
description: "The Rainforest cloud password",
type: "password",
required: true
}
]
},
{
inverter: "Efergy",
options: [
{
name: "Token",
value: null,
description: "The Efergy token used to access your system data",
type: "text",
required: true
},
{
name: "Power",
value: null,
description:
"The Efergy power key, usually 'PWER' or 'PWER.1234' where 1234 is the sid",
type: "text",
required: true
}
]
}
]
};
},
这是我的代码笔示例:https://codepen.io/pistell/pen/BaJPjgq
如您所见,所有下拉示例始终显示。我怎样才能让 selected 在下拉列表中显示?如果有影响的话,我也在使用 Tailwind CSS。
如果我没理解错的话,试试下面的代码片段:
new Vue({
el: "#demo",
data() {
return {
address: "",
stakeAddress: "",
selectedInverter: null,
addressError: "",
apiKey: null,
filteredOptions: "",
// TODO: Create a way to iterate over these values and populate the HTML elements that go along with each of these
//
options: [
{
inverter: "None",
options: []
},
{
inverter: "Eagle",
options: [
{
name: "Cloud ID",
value: null,
description:
"The Rainforest cloud id used to access your system data",
type: "text",
required: true
},
{
name: "User",
value: null,
description: "The Rainforest cloud username",
type: "text",
required: true
},
{
name: "Password",
value: null,
description: "The Rainforest cloud password",
type: "password",
required: true
}
]
},
{
inverter: "Efergy",
options: [
{
name: "Token",
value: null,
description: "The Efergy token used to access your system data",
type: "text",
required: true
},
{
name: "Power",
value: null,
description:
"The Efergy power key, usually 'PWER' or 'PWER.1234' where 1234 is the sid",
type: "text",
required: true
}
]
}
]
};
},
computed: {
computed_items() {
const selected = this.selectedInverter;
return this.options.filter((item) => item.inverter.includes(selected));
}
},
methods: {
async registerInverter() {
this.addressError = this.address.length > 1 ? "" : "Not a valid address";
if (!this.addressError) {
await this.validateAddress();
// Values to send to Firebase
console.log({
address: this.address,
api_key: this.apiKey,
date_registered: new Date().toUTCString(),
inverter: this.selectedInverter,
stake_address: this.stakeAddress
});
}
},
async validateAddress() {
// Evaluate the address and check if its valid
console.log(this.address);
return this.address;
},
onChange(event) {
this.selectedInverter = event.target.value;
}
}
})
.error {
color: red;
margin-top: 10px;
font-size: 0.8rem;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div class="flex items-center justify-center">
<div class="w-full max-w-md">
<form
class="bg-white shadow-lg rounded px-12 pt-6 pb-8 mb-4"
@submit.prevent="registerInverter"
>
<!-- @csrf -->
<div
class="text-gray-800 text-2xl flex justify-center border-b-2 py-2 mb-4"
>
Register your Inverter
</div>
<div class="mb-4">
<label
class="block text-gray-700 text-sm font-normal mb-2"
for="address"
>
Wallet Address
</label>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
name="address"
v-model="address"
type="text"
required
autofocus
placeholder="Input your address"
/>
<div v-if="addressError" class="error">{{ addressError }}</div>
</div>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-normal" for="inverter">
Inverter Model
</label>
<div class="inline-block relative w-full py-4 flex-1">
<select
class="block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline"
v-model="selectedInverter"
@change="onChange($event)"
>
<option
v-for="(item, index) in options"
:value="item.inverter"
:key="index"
>
{{ item.inverter }}
</option>
</select>
<div
class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700"
>
<svg
class="fill-current h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
width="20px"
>
<path
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
/>
</svg>
</div>
</div>
</div>
<div class="mb-4">
<div
v-for="(item, index) in computed_items"
:value="item.inverter"
:key="index"
>
<h2>{{ item.inverter }}</h2>
<div
v-for="(item, index) in item.options"
:value="item.name"
:key="index"
>
<input
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline mt-1 mb-1"
:name="item.name"
:type="item.type"
:required="item.required"
:placeholder="item.description"
/>
</div>
</div>
</div>
<div class="registerButton">
<button
class="px-4 py-2 rounded text-white inline-block shadow-lg bg-blue-500 hover:bg-green-500 focus:bg-blue-700"
type="submit"
>
Register
</button>
</div>
</form>
</div>
</div>
</div>