在 Vue 3 中加载异步选项时自动选择第一个 <select> 选项
Posted
技术标签:
【中文标题】在 Vue 3 中加载异步选项时自动选择第一个 <select> 选项【英文标题】:Auto-select first <select> option when loading async options in Vue 3 【发布时间】:2021-06-04 15:09:25 【问题描述】:我有一个 <select>
html 元素,我想将它 v-model
绑定到 Vue.js 3 的 setup()
方法中的 ref
值。因此,当用户选择不同的选项时,Form.ProductID
引用会更新。
这里是<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>
元素中选择一个选项时,Form.ProductID
会按预期更新并显示我选择了哪个选项,例如:
Form (Object Ref)
ProductID: 3
问题是在第一次加载页面时,<select>
元素没有选择带有value="2"
的选项,即使我在setup()
中对其进行了硬编码。它只是显示一个空白选项!但是,如果我将 <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"
的选项,但是Form.ProductID
的实际值不会更新,vue devtools继续将ProductID: "[object HTMLOptionElement]"
显示为数据。
如何让<select>
元素使用v-model
工作,并在组件加载时选择默认选项?
【问题讨论】:
肯定有不同的问题,应该可以工作jsfiddle.net/sh0ber/zrj18f69 @shob 你是对的,这是一段代码:onMounted(() => Form.value.ProductID = document.querySelector("#ProductID option:first-of-type")
默认选择第一个选项。是否可以让Form.value.ProductID
等于第一个选项onMounted的值?
为什么不将Form.ProductID
设置为 1?
@shob 因为我不能总是知道 ID 是什么。它们最终将来自数据库作为 json
【参考方案1】:
回答 cmets 中关于异步加载时如何选择第一个选项的更新问题。加载数据后,将 Form
的值设置为 options 数组中的第一项(克隆以避免变异),而不是手动操作输入 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>
【讨论】:
不客气!我做了一个小更新。首先克隆选项很重要,或者为Form
创建一个新对象并一个一个添加属性,克隆任何引用类型。否则更改表单输入会更改选项 #1 的选项数据以上是关于在 Vue 3 中加载异步选项时自动选择第一个 <select> 选项的主要内容,如果未能解决你的问题,请参考以下文章