Vue 2 - 关于改变 props 的警告
P粉818306280
P粉818306280 2023-10-13 10:49:44
0
2
600

我开始了 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粉818306280
P粉818306280

全部回复(2)
P粉715274052

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 调用其他子组件(例如表单元素)。

P粉268654873

这与以下事实有关:在本地改变 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 存在一些混乱,我建议您看看 线程

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!