首页  >  问答  >  正文

Vue 2 - 关于改变 props 的警告

我开始了 https://laracasts.com/series/learning-vue-step-by-step 系列。我因以下错误而停止了Vue、Laravel 和 AJAX 课程:

vue.js:2574 [Vue warn]:避免直接改变 prop,因为只要父组件重新渲染,该值就会被覆盖。相反,根据 prop 的值使用数据或计算属性。正在改变的道具:“list”(在组件中找到)

我在main.js中有这段代码

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    created() {
        this.list = JSON.parse(this.list);
    }
});
new Vue({
    el: '.container'
})

我知道当我覆盖 list 属性时,问题出在 created() 中,但我是 Vue 的新手,所以我完全不知道如何解决它。有谁知道如何(并请解释原因)修复它?

P粉818306280P粉818306280342 天前573

全部回复(2)我来回复

  • P粉715274052

    P粉7152740522023-10-14 09:15:14

    Vue 模式是 props 向下,events 向上。听起来很简单,但在编写自定义组件时很容易忘记。

    从 Vue 2.2.0 开始,您可以使用 v -model(带有计算属性)。我发现这种组合在组件之间创建了一个简单、干净且一致的界面:

    • 传递给组件的任何 props 都保持响应状态(即,它不会被克隆,也不需要 watch 函数在检测到更改时更新本地副本)。< /里>
    • 更改会自动发送给父级。
    • 可与多个级别的组件一起使用。

    计算属性允许单独定义 setter 和 getter。这允许 Task 组件重写如下:

    Vue.component('Task', {
        template: '#task-template',
        props: ['list'],
        model: {
            prop: 'list',
            event: 'listchange'
        },
        computed: {
            listLocal: {
                get: function() {
                    return this.list
                },
                set: function(value) {
                    this.$emit('listchange', value)
                }
            }
        }
    })

    model 属性定义关联的 propv-model,以及更改时将发出哪个事件。然后,您可以从父组件调用此组件,如下所示:

    <Task v-model="parentList"></Task>

    listLocal 计算属性在组件内提供了一个简单的 getter 和 setter 接口(将其视为私有变量)。在 #task-template 中,您可以渲染 listLocal 并且它将保持反应性(即,如果 parentList 更改,它将更新 Task< /代码> 组件)。您还可以通过调用 setter(例如 this.listLocal = newList)来更改 listLocal,它会将更改发送给父级。

    此模式的优点在于,您可以将 listLocal 传递给 Task 的子组件(使用 v-model),并进行更改来自子组件的内容将传播到顶级组件。

    例如,假设我们有一个单独的 EditTask 组件,用于对任务数据进行某种类型的修改。通过使用相同的 v-model 和计算属性模式,我们可以将 listLocal 传递给组件(使用 v-model):

    <script type="text/x-template" id="task-template">
        <div>
            <EditTask v-model="listLocal"></EditTask>
        </div>
    </script>

    如果EditTask发出更改,它将适当地调用listLocal上的set(),从而将事件传播到顶层。同样,EditTask 组件也可以使用 v-model 调用其他子组件(例如表单元素)。

    回复
    0
  • P粉268654873

    P粉2686548732023-10-14 00:33:06

    这与以下事实有关:在本地改变 prop 是被认为是 Vue 2 中的反模式

    如果您想要在本地改变 prop,您现在应该做的是在 data 中声明一个使用 props 的字段code> value 作为其初始值,然后改变副本:

    Vue.component('task', {
        template: '#task-template',
        props: ['list'],
        data: function () {
            return {
                mutableList: JSON.parse(this.list);
            }
        }
    });

    您可以在 Vue 上阅读更多相关信息.js官方指南


    注1:请注意您不应该propdata,即:

    data: function () { return { list: JSON.parse(this.list) } } // WRONG!!

    注2:我觉得关于 propsreactivity 存在一些混乱,我建议您看看 线程

    回复
    0
  • 取消回复