提问人:Merc 提问时间:11/17/2023 更新时间:11/20/2023 访问量:34
Vue 3: 从数组中删除对象(代理)
Vue 3: Remove objects (Proxies) from Array
问:
我有一个 vue3 项目,我使用组合 API。 我有一个组件,它显示一些项目(在本例中称为令牌)。
<script setup>
import { ref, onMounted, toRaw } from 'vue'
import RotaryToken from './RotaryToken.vue'
const tokens = ref([])
const addToken = () => {
const id = new Date().valueOf()
tokens.value.push({ id })
}
const removeToken = (id) => {
console.log('id: ', id)
tokens.value = tokens.value.filter((token) => {
console.log('toRaw(token): ', toRaw(token))
return token.id !== id
})
console.log('tokens.value: ', tokens.value)
}
</script>
<template>
<div class="canvas">
<div class="controls"><button @click="addToken">Add token</button></div>
<div v-if="tokens.length <= 0" class="fallback-message">Place tokens here</div>
<RotaryToken
v-for="token in tokens"
:key="token.id"
@destroy="removeToken"
:id="token.id"
/>
</div>
</template>
RotaryToken 本身可以发出 destroy 事件,因此我可以将自身从数组中删除,因此应该将其删除。(我试图自毁一个旋转令牌,但没有成功)。
不幸的是,我无法从反应式数组中删除令牌。问题出在 Vues Reactivity 的某个地方。tokens
我可以看到 id 是正确的,但就是不起作用。
我尝试过拼接而不是过滤,添加了.没有任何效果。tokens.value.filter
nextTick
也许有人知道如何从数组中删除令牌并使其重新呈现模板并删除已销毁的令牌?
答:
1赞
yoduh
11/17/2023
#1
问题出在您的过滤器测试上。
tokens.value.filter((token) => {
console.log('toRaw(token): ', toRaw(token))
return token.id !== id
})
你认为的地方是一个数字,但正如你的屏幕截图所示,它是一个名为“id”的对象,但也有一个属性。因此,筛选器测试仅返回以下标记id
id
token.id !== object
要么将实际属性传递给函数,要么访问对象上的属性,即:id
id.id
tokens.value.filter((token) => {
console.log('toRaw(token): ', toRaw(token))
return token.id !== id.id
})
评论
0赞
Merc
11/17/2023
天哪,真是个愚蠢的错误!多谢!
0赞
Laurent Schoelens
11/20/2023
#2
我建议您更改删除实现以利用数组中的 vuejs 反应性:
const removeToken = (id) => {
console.log('id: ', id)
// search index of the token to remove by its id
const index = tokens.value.findIndex(token => token.id === id)
if (index >= 0) {
// index >= 0 -> index as been found in array -> use splice method to remove item in array
tokens.value.splice(index, 1)
}
console.log('tokens.value: ', tokens.value)
}
如果此代码在数组中是唯一的,则此代码应该有效。id
tokens
如果不是这种情况,您可以将调用包装在这样的循环中:splice
while
const removeToken = (id) => {
console.log('id: ', id)
// search index of the token to remove by its id
let index = tokens.value.findIndex(token => token.id === id)
while (index >= 0) {
// index >= 0 -> index as been found in array -> use splice method to remove item in array
tokens.value.splice(index, 1)
// and update the index var to search for a new token in the tokens array
index = tokens.value.findIndex(token => token.id === id)
}
console.log('tokens.value: ', tokens.value)
}
评论
0赞
Merc
11/21/2023
实际上上面的代码有效,我已经接受了答案。无论如何,谢谢!
0赞
Laurent Schoelens
11/21/2023
没问题:)我没有抓住 is 一个对象,因为 is 在它本身上被调用。使用 vuejs 原生响应式函数可以提供更高的性能,因为你不需要每次都重新创建数组。id
@destroy="removeToken"
token
评论
console.log(tokens.value[0].id)