繁体   English   中英

为什么 vuejs 在计算属性中引用 v-model 时会复制其 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-model 总是添加另一个实例,尽管它以前已经包含一个实例。

删除this.selected; (下面 Codepen 中的第 16 行)解决了这个问题。

我怀疑this.selected以某种方式取消引用它自己的值,然后无法验证先前选择的项目的外观。

这是手头有问题的 Codepen: https://codepen.io/MichaelKatz/pen/vYXXdgb

在我的真实场景中,我需要根据之前所做的选择(即删除/重新添加项目)过滤和操作列表中的项目。 我通过使用计算item属性来执行此操作,该属性从先前选择的项目、 selected的 v 模型中派生其内容,而我当前的解决方案将要求我JSON.stringify我的所有对象,基本上使它们成为基于值的字符串以保留检查的事情。

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))
}

更新了 Codepen

似乎在过滤它引用的项目时访问 v-model 会创建其中对象的取消引用。

我能想到的最佳解决方案是添加一个额外的计算属性,该属性将包含涉及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;
    }
  }
}

从我的角度来看,问题在于您使用了multiple道具,这将允许多个选择。

      <template v-slot="{ item, index }">
       <v-list-item-group
         v-model="selected"
         multiple
       >

只需将其删除即可解决您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM