【问题标题】:Why is v-model inside a component inside a v-for (using a computed list) changing weirdly when the list changes?为什么当列表更改时,v-for(使用计算列表)内的组件内的 v-model 会发生奇怪的变化?
【发布时间】:2019-10-22 01:04:53
【问题描述】:

我正在使用计算列表来显示用于更改数据库中的 cmets 的几种表格。 (后端 Symfony / api 通过 axios 请求,但不相关)

cmets 本身的表单位于 Vue 组件中。 计算列表基于在加载页面时加载(并设置为数据属性)的列表,然后由计算属性中的输入搜索框过滤。

现在,当我在输入框中输入不同的内容并且评论组件得到更新时,v-model 和标签就会变得混乱。

我在几个浏览器中测试过,在主要浏览器中的行为都是一样的。

我也搜索了文档,但没有找到解决方案。

重现行为的示例:

<!DOCTYPE html>
<html>
<div id="app"></app>
</html>
const ChangeCommentForm = {
    name: 'ChangeCommentForm',
    props: ['comment', 'id'],
    data() {
        return {
            c: this.comment,
            disabled: false
        };
    },
    template: `
<form>
  <div>{{ comment }}</div>
  <input :disabled="disabled" type="text" v-model="c">
  <button type="submit" @click.prevent="changeComment">
    Change my comment
  </button>
</form>
`,
    methods: {
        changeComment() {
            this.disabled = true;
            // do the actual api request (should be unrelated)
            // await api.changeCommentOfFruit(this.id, this.c),
            // replacing this with a timeout for this example
            window.setTimeout(() => this.disabled = false, 1000);
        }
    }
};

const App = {
    components: {ChangeCommentForm},
    data() {
        return {
            fruits: [
                {id: 1, text: "apple"},
                {id: 2, text: "banana"},
                {id: 3, text: "peach"},
                {id: 4, text: "blueberry"},
                {id: 5, text: "blackberry"},
                {id: 6, text: "mango"},
                {id: 7, text: "watermelon"},
            ],
            search: ''
        }
    },
    computed: {
        fruitsFiltered() {

            if (!this.search || this.search === "")
                return this.fruits;

            const r = [];
            for (const v of this.fruits)
                if (v.text.includes(this.search))
                    r.push(v);
            return r;
        }
    },
    template: `
<div>
  <form><input type="search" v-model="search"></form>
  <div v-for="s in fruitsFiltered">
    <ChangeCommentForm :id="s.id" :comment="s.text"/>
  </div>
</div>
`
};

const vue = new Vue({
    el: '#app',
    components: {App},
    template: '<app/>'
});

只需在搜索框中输入一些字母 Codepen 示例:https://codepen.io/anon/pen/KLLYmq

现在如示例所示,CommentChangeForm 中的 div 已正确更新,但 v-model 已损坏。

我想知道我是否遗漏了什么或者这是 Vue 中的错误?

【问题讨论】:

  • 能否更具体一些。您在哪个字段中输入什么数据?观察到的行为是什么,预期的行为是什么?
  • 哎,问题出在哪里;非常感谢。

标签: javascript vue.js


【解决方案1】:

为了在渲染之间保留 DOM 元素的状态,v-for 元素也有一个 key 属性很重要。此键应在渲染之间保持一致。

这里看起来像下面这样可以解决问题:

<div v-for="s in fruitsFiltered" :key="s.id">
  <ChangeCommentForm :id="s.id" :comment="s.text"/>
</div>

见:

https://vuejs.org/v2/guide/list.html#Maintaining-State

https://vuejs.org/v2/api/#key

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 2021-02-15
    • 2019-02-14
    • 2018-01-02
    • 2020-06-07
    • 2021-11-30
    • 2018-04-21
    • 1970-01-01
    相关资源
    最近更新 更多