为了账号安全,请及时绑定邮箱和手机立即绑定

Vue 2-变异道具vue-warn

Vue 2-变异道具vue-warn

慕容3067478 2019-11-27 10:23:32
我开始了https://laracasts.com/series/learning-vue-step-by-step系列。我停在课程Vue,Laravel和AJAX时遇到了此错误:vue.js:2574 [Vue警告]:避免直接更改道具,因为每当父组件重新渲染时,该值就会被覆盖。而是使用基于属性值的数据或计算属性。变异的道具:“列表”(位于component中)我在main.js中有此代码Vue.component('task', {    template: '#task-template',    props: ['list'],    created() {        this.list = JSON.parse(this.list);    }});new Vue({    el: '.container'})我知道当我覆盖列表属性时问题出在created()中,但是我是Vue的新手,所以我完全不知道如何解决它。任何人都知道如何(并请解释为什么)修复它?
查看完整描述

3 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

这与以下事实有关:在Vue 2中将局部更改prop视为反模式


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


Vue.component('task', {

    template: '#task-template',

    props: ['list'],

    data: function () {

        return {

            mutableList: JSON.parse(this.list);

        }

    }

});

您可以在Vue.js官方指南中了解更多有关此内容的信息


注意1:请注意,您不能为prop和使用相同的名称data,即:


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

注2:由于我觉得有一些混乱关于props和反应,我建议你有一看这个线程


查看完整回答
反对 回复 2019-11-27
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

Vue只是警告您:您更改了组件中的prop,但是当父组件重新渲染时,“列表”将被覆盖,您将丢失所有更改。因此这样做很危险。


改为使用计算属性:


Vue.component('task', {

    template: '#task-template',

    props: ['list'],

    computed: {

        listJson: function(){

            return JSON.parse(this.list);

        }

    }

});


查看完整回答
反对 回复 2019-11-27
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

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


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


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)

            }

        }

    }

})  

的模型,其属性定义prop相关联v-model,并且该事件将在改变发射。然后可以从父级调用此组件,如下所示:


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

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


该模式的优点在于,您可以将传递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发出改变它会适当地调用set()上listLocal,并由此传播事件到顶层。同样,该EditTask组件也可以使用调用其他子组件(例如表单元素)v-model。


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 857 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信