在 Vue 3 中加载异步选项时自动 select 第一个 <select> 选项
Auto-select first <select> option when loading async options in Vue 3
我有一个 <select>
HTML 元素,我想 v-model
绑定到 Vue.js 3 的 setup()
方法中的 ref
值.因此,当用户 select 选择不同的选项时,Form.ProductID
ref 会更新。
这里是 <select>
代码:
<select v-model="Form.ProductID" id="ProductID" name="ProductID">
<option value="1">Option A</option>
<option value="2">Option B</option>
<option value="3">Option C</option>
</select>
和setup()
:
export default {
name: "ComponentProductSelector",
setup() {
const Form = ref({
ProductID: '2',
Price: null,
Currency: null
})
onMounted(() => Form.value.ProductID)
document.querySelector("#ProductID option:first-of-type")
}
}
在 vue devtools 中首次加载时,它显示数据为:
Form (Object Ref)
ProductID: "[object HTMLOptionElement]"
当我 select <select>
元素中的一个选项时,Form.ProductID
按预期更新并显示我 select 编辑的选项,例如:
Form (Object Ref)
ProductID: 3
问题是在页面第一次加载时,<select>
元素没有 select 使用 value="2"
选择选项,即使我在 [=20] 中硬编码它=].它只是显示一个空白选项!但是,如果我将 <select>
元素更改为以下代码,则它会:
<select ref="Form.ProductID" id="ProductID" name="ProductID">
<option value="1">Option A</option>
<option value="2">Option B</option>
<option value="3">Option C</option>
</select>
现在 value="2"
的选项在渲染组件时默认为 selected,但是 Form.ProductID
的实际值不会更新并且 vue devtools 继续显示 ProductID: "[object HTMLOptionElement]"
作为数据。
如何使用 v-model
和组件加载时的默认选项 select 让 <select>
元素正常工作?
回答关于如何在异步加载时 select 第一个选项的评论中更新的问题。加载数据后,将 Form
的值设置为选项数组中的第一项(克隆以避免改变它),而不是手动操作输入 DOM.
例如:
<select v-model="Form.ProductID" id="ProductID" name="ProductID" v-if="options">
<option v-for="option in options" :key="option.ProductID" :value="option.ProductID">
{{ option.ProductID }}
</option>
</select>
setup() {
const options = ref(null);
const Form = ref(null);
axios.get('...').then(response => {
options.value = response.data;
Form.value = { ...options.value[0] }; // Clone and select first option
});
return { options, Form }
}
<select>
上有一个 v-if
延迟渲染,直到数据准备好。
这是一个演示:
const { createApp, ref } = Vue;
const app = createApp({
setup() {
const options = ref(null);
const Form = ref(null);
axios.get('https://jsonplaceholder.typicode.com/posts').then(response => {
options.value = response.data;
Form.value = { ...options.value[0] }; // Clone and select first option
});
return { options, Form }
}
});
app.mount("#app");
<div id="app">
<select v-model="Form.id" id="ProductID" name="ProductID" v-if="options">
<option v-for="option in options" :key="option.id" :value="option.id">
{{ option.id }}
</option>
</select>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/axios"></script>
我有一个 <select>
HTML 元素,我想 v-model
绑定到 Vue.js 3 的 setup()
方法中的 ref
值.因此,当用户 select 选择不同的选项时,Form.ProductID
ref 会更新。
这里是 <select>
代码:
<select v-model="Form.ProductID" id="ProductID" name="ProductID">
<option value="1">Option A</option>
<option value="2">Option B</option>
<option value="3">Option C</option>
</select>
和setup()
:
export default {
name: "ComponentProductSelector",
setup() {
const Form = ref({
ProductID: '2',
Price: null,
Currency: null
})
onMounted(() => Form.value.ProductID)
document.querySelector("#ProductID option:first-of-type")
}
}
在 vue devtools 中首次加载时,它显示数据为:
Form (Object Ref)
ProductID: "[object HTMLOptionElement]"
当我 select <select>
元素中的一个选项时,Form.ProductID
按预期更新并显示我 select 编辑的选项,例如:
Form (Object Ref)
ProductID: 3
问题是在页面第一次加载时,<select>
元素没有 select 使用 value="2"
选择选项,即使我在 [=20] 中硬编码它=].它只是显示一个空白选项!但是,如果我将 <select>
元素更改为以下代码,则它会:
<select ref="Form.ProductID" id="ProductID" name="ProductID">
<option value="1">Option A</option>
<option value="2">Option B</option>
<option value="3">Option C</option>
</select>
现在 value="2"
的选项在渲染组件时默认为 selected,但是 Form.ProductID
的实际值不会更新并且 vue devtools 继续显示 ProductID: "[object HTMLOptionElement]"
作为数据。
如何使用 v-model
和组件加载时的默认选项 select 让 <select>
元素正常工作?
回答关于如何在异步加载时 select 第一个选项的评论中更新的问题。加载数据后,将 Form
的值设置为选项数组中的第一项(克隆以避免改变它),而不是手动操作输入 DOM.
例如:
<select v-model="Form.ProductID" id="ProductID" name="ProductID" v-if="options">
<option v-for="option in options" :key="option.ProductID" :value="option.ProductID">
{{ option.ProductID }}
</option>
</select>
setup() {
const options = ref(null);
const Form = ref(null);
axios.get('...').then(response => {
options.value = response.data;
Form.value = { ...options.value[0] }; // Clone and select first option
});
return { options, Form }
}
<select>
上有一个 v-if
延迟渲染,直到数据准备好。
这是一个演示:
const { createApp, ref } = Vue;
const app = createApp({
setup() {
const options = ref(null);
const Form = ref(null);
axios.get('https://jsonplaceholder.typicode.com/posts').then(response => {
options.value = response.data;
Form.value = { ...options.value[0] }; // Clone and select first option
});
return { options, Form }
}
});
app.mount("#app");
<div id="app">
<select v-model="Form.id" id="ProductID" name="ProductID" v-if="options">
<option v-for="option in options" :key="option.id" :value="option.id">
{{ option.id }}
</option>
</select>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/axios"></script>