具有功能模板引用的动态 v-for 中的空值
null value in dynamic v-for with functional template refs
情况
我正在构建自定义过滤组件。这允许用户应用在模板中显示为 v-for
的 n
过滤器。用户可以更新输入字段中的任何值或之后删除任何过滤器。
问题
删除其中一个过滤器后,我的数组 itemRefs
得到一个 null
值作为最后一项。
代码(简体)
<script setup>
const filtersScope = $ref([])
const itemRefs = $ref([])
function addFilter () {
filtersScope.push({ value: '' })
}
function removeFilter (idx) {
filtersScope.splice(idx, 1)
itemRefs.pop() // <- necessary? has no effect
// validate and emit stuff
console.log(itemRefs)
// itemRefs got at least one null item
// itemRefs = [null]
}
// assign the values from the input fields to work with it later on
function updateValue() {
itemRefs.forEach((input, idx) => filtersScope[idx].value = input.value)
}
</script>
<template>
<div v-for="(filter, idx) in filtersScope" :key="filter.id">
<input
type="text"
@keyup="updateValue"
:ref="(input) => { itemRefs[idx] = input }"
:value="filter.value"
>
<button @click="removeFilter(idx)" v-text="'x'" />
</div>
<button @click="addFilter()" v-text="'add filter +'" />
</template>
>>> Working demo
重现:
- 添加两个过滤器
itemRefs
现在将模板引用作为参考,例如:[input, input]
- 删除一个过滤器,
itemRefs
现在看起来:[input, null]
- 删除最后一个过滤器,
itemRefs
现在看起来像:[null]
问题
在没有 itemRefs.pop()
的情况下,删除并应用新过滤器后出现以下错误:
Uncaught TypeError: input is null
使用 pop()
方法我防止了控制台错误,但 itemRefs
中的 null
值仍然存在。
如何彻底清理模板引用?
我不知道在 $refs
中使用 $refs
是怎么回事,但它显然没有像人们预期的那样工作。
但是,您永远不需要嵌套 $refs
。改变数据时,改变外部 $refs
。使用 $computed
获取该数据的 simplified/focused angle/slice。
<script setup>
const filtersScope = $ref([])
const values = $computed(() => filtersScope.map(e => e.value))
function addFilter() {
filtersScope.push({ value: '' })
}
function removeFilter(idx) {
filtersScope.splice(idx, 1);
console.log(values)
}
</script>
<template>
<div v-for="(filter, idx) in filtersScope" :key="idx">
<input type="text"
v-model="filtersScope[idx].value">
<button @click="removeFilter(idx)" v-text="'x'" />
</div>
<button @click="addFilter()" v-text="'add filter +'" />
</template>
情况
我正在构建自定义过滤组件。这允许用户应用在模板中显示为 v-for
的 n
过滤器。用户可以更新输入字段中的任何值或之后删除任何过滤器。
问题
删除其中一个过滤器后,我的数组 itemRefs
得到一个 null
值作为最后一项。
代码(简体)
<script setup>
const filtersScope = $ref([])
const itemRefs = $ref([])
function addFilter () {
filtersScope.push({ value: '' })
}
function removeFilter (idx) {
filtersScope.splice(idx, 1)
itemRefs.pop() // <- necessary? has no effect
// validate and emit stuff
console.log(itemRefs)
// itemRefs got at least one null item
// itemRefs = [null]
}
// assign the values from the input fields to work with it later on
function updateValue() {
itemRefs.forEach((input, idx) => filtersScope[idx].value = input.value)
}
</script>
<template>
<div v-for="(filter, idx) in filtersScope" :key="filter.id">
<input
type="text"
@keyup="updateValue"
:ref="(input) => { itemRefs[idx] = input }"
:value="filter.value"
>
<button @click="removeFilter(idx)" v-text="'x'" />
</div>
<button @click="addFilter()" v-text="'add filter +'" />
</template>
>>> Working demo
重现:
- 添加两个过滤器
itemRefs
现在将模板引用作为参考,例如:[input, input]
- 删除一个过滤器,
itemRefs
现在看起来:[input, null]
- 删除最后一个过滤器,
itemRefs
现在看起来像:[null]
问题
在没有 itemRefs.pop()
的情况下,删除并应用新过滤器后出现以下错误:
Uncaught TypeError: input is null
使用 pop()
方法我防止了控制台错误,但 itemRefs
中的 null
值仍然存在。
如何彻底清理模板引用?
我不知道在 $refs
中使用 $refs
是怎么回事,但它显然没有像人们预期的那样工作。
但是,您永远不需要嵌套 $refs
。改变数据时,改变外部 $refs
。使用 $computed
获取该数据的 simplified/focused angle/slice。
<script setup>
const filtersScope = $ref([])
const values = $computed(() => filtersScope.map(e => e.value))
function addFilter() {
filtersScope.push({ value: '' })
}
function removeFilter(idx) {
filtersScope.splice(idx, 1);
console.log(values)
}
</script>
<template>
<div v-for="(filter, idx) in filtersScope" :key="idx">
<input type="text"
v-model="filtersScope[idx].value">
<button @click="removeFilter(idx)" v-text="'x'" />
</div>
<button @click="addFilter()" v-text="'add filter +'" />
</template>