为什么在计算 属性 中引用 v-model 时 vuejs 会复制其 v-model 数据?
Why does vuejs replicates its v-model data when the v-model is referenced within a computed property?
在下面的代码中:
JS
const App = {
template: '#app-template',
data: () => ({
selected: [],
items: Array.from({length: 50}, (x, i) => i+1).map(i => ({
id: i ,
name: `Item ${i}`,
subtitle: `Subtitle ${i}`
}))
}),
computed: {
parsedItems() {
this.selected;
return this.items.map(item => ({
someValue: 3,
...item
}));
}
}
}
new Vue({
vuetify: new Vuetify(),
render: h => h(App)
}).$mount('#app')
HTML
<script type="text/x-template" id="app-template">
<v-app>
{{selected}}
<v-container>
<v-virtual-scroll
:items="parsedItems"
:item-height="65"
height="500"
>
<template v-slot="{ item, index }">
<v-list-item-group
v-model="selected"
multiple
>
<v-list-item :key="item.id" :value="item">
<v-list-item-action>
<v-checkbox
:input-value="selected.includes(item.id)"
color="primary"
/>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
Index: {{ index }} {{ item.name }}
</v-list-item-title>
<v-list-item-subtitle>
{{ item.subtitle }}
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</template>
</v-virtual-scroll>
</v-container>
</v-app>
</script>
<div id="app"></div>
当我选中或取消选中其中一个复选框时 - selected
v 模型总是添加另一个实例,尽管它之前已经包含一个实例。
删除 this.selected;
(下面代码笔中的第 16 行)解决了这个问题。
我怀疑 this.selected
以某种方式取消引用它自己的值,然后无法验证之前选择的项目的外观。
这里有一个关于手头问题的 Codepen:https://codepen.io/MichaelKatz/pen/vYXXdgb
在我的真实场景中,我需要根据之前所做的选择(即删除/重新添加项目)过滤和操作列表中的项目。
我通过使用计算 item
属性 来实现它,它从先前选择的项目、selected
v 模型中派生其内容,而我当前的解决方案将要求我 JSON.stringify
我所有的对象,本质上是使它们成为基于值的字符串以保持检查状态。
在我看来,问题是您使用了 multiple
道具,这将允许多项选择。
<template v-slot="{ item, index }">
<v-list-item-group
v-model="selected"
multiple
>
只需将其删除即可解决您的问题。
v-model
似乎不适用于对象
<v-list-item :key="item.id" :value="item"> <!-- change this -->
<v-list-item :key="item.id" :value="item.id"> <!-- into this -->
并创建一个新的计算 属性 来“混合”这些 ID:
selectedItems() {
return this.selected.map(id => this.parsedItems.find(x => x.id === id))
}
似乎在过滤它引用的项目时访问 v 模型,创建了其中对象的取消引用。
我能想到的最佳解决方案是添加一个额外的计算 属性,它将包含涉及 this.selected
.
的逻辑
确实解决了我的问题
computed: {
parsedItems() {
return this.items.map(item => ({
someValue: 3,
...item
}));
},
filteredItems() { // adding another computed property while using this.selected
this.selected;
return this.parsedItems;
}
}
}
在下面的代码中:
JS
const App = {
template: '#app-template',
data: () => ({
selected: [],
items: Array.from({length: 50}, (x, i) => i+1).map(i => ({
id: i ,
name: `Item ${i}`,
subtitle: `Subtitle ${i}`
}))
}),
computed: {
parsedItems() {
this.selected;
return this.items.map(item => ({
someValue: 3,
...item
}));
}
}
}
new Vue({
vuetify: new Vuetify(),
render: h => h(App)
}).$mount('#app')
HTML
<script type="text/x-template" id="app-template">
<v-app>
{{selected}}
<v-container>
<v-virtual-scroll
:items="parsedItems"
:item-height="65"
height="500"
>
<template v-slot="{ item, index }">
<v-list-item-group
v-model="selected"
multiple
>
<v-list-item :key="item.id" :value="item">
<v-list-item-action>
<v-checkbox
:input-value="selected.includes(item.id)"
color="primary"
/>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
Index: {{ index }} {{ item.name }}
</v-list-item-title>
<v-list-item-subtitle>
{{ item.subtitle }}
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</template>
</v-virtual-scroll>
</v-container>
</v-app>
</script>
<div id="app"></div>
当我选中或取消选中其中一个复选框时 - selected
v 模型总是添加另一个实例,尽管它之前已经包含一个实例。
删除 this.selected;
(下面代码笔中的第 16 行)解决了这个问题。
我怀疑 this.selected
以某种方式取消引用它自己的值,然后无法验证之前选择的项目的外观。
这里有一个关于手头问题的 Codepen:https://codepen.io/MichaelKatz/pen/vYXXdgb
在我的真实场景中,我需要根据之前所做的选择(即删除/重新添加项目)过滤和操作列表中的项目。
我通过使用计算 item
属性 来实现它,它从先前选择的项目、selected
v 模型中派生其内容,而我当前的解决方案将要求我 JSON.stringify
我所有的对象,本质上是使它们成为基于值的字符串以保持检查状态。
在我看来,问题是您使用了 multiple
道具,这将允许多项选择。
<template v-slot="{ item, index }">
<v-list-item-group
v-model="selected"
multiple
>
只需将其删除即可解决您的问题。
v-model
似乎不适用于对象
<v-list-item :key="item.id" :value="item"> <!-- change this -->
<v-list-item :key="item.id" :value="item.id"> <!-- into this -->
并创建一个新的计算 属性 来“混合”这些 ID:
selectedItems() {
return this.selected.map(id => this.parsedItems.find(x => x.id === id))
}
似乎在过滤它引用的项目时访问 v 模型,创建了其中对象的取消引用。
我能想到的最佳解决方案是添加一个额外的计算 属性,它将包含涉及 this.selected
.
确实解决了我的问题
computed: {
parsedItems() {
return this.items.map(item => ({
someValue: 3,
...item
}));
},
filteredItems() { // adding another computed property while using this.selected
this.selected;
return this.parsedItems;
}
}
}