在使用Vue组件时避免直接更改道具

时间:2019-08-21 04:28:54

标签: javascript vue.js vuejs2 vue-component

我在vue中创建一个警报组件,像这样

<template>
   <div class="alert-bg" v-if="view">
    <div class="content">
        <div class="message"> {{message}} </div>
        <div class="alert-control text-right mt-4">
            <button class="btn btn-secondary" @click="onCancel" v-html="cancel"/>
            <button :class="btnStyle" class="btn ml-2" v-html="ok" @click="onSubmit"/>
        </div>
    </div>
  </div>
</template>

<script>
    import $ from 'jquery';
    import 'imports-loader?window.jQuery=jquery,this=>window!widgster';

    export default { 
        name: 'Alert',
        props: {
            message: { default: 'Lorem ipsum dolor sit amet consectetur' },
            cancel: { default: 'Cancel' },
            ok: { default: 'Yes' },
            btnStyle: { default: 'btn btn-primary' },
            view: { default: false }
        },

        methods: {
            onCancel(){
                this.view = false;
            },

            onSubmit(){
                this.$emit('onSubmit');
            }
        },

    };
</script>

然后在主页中我像这样使用它,

// html
<button class="btn btn-secondary" @click="confirm" v-html="'Confirm'"/>
<Confirm :view="alert.view"/>

// script
import Confirm from '@/components/modals/alert/alert';

export default {
  name: "Product",
  components: { Confirm },
  data() {
    return {
      alert: { view: false },
    }
  },

  methods: {
     confirm(){
        this.alert.view = true; // show alert
     }
  }
}

当我单击“确认”按钮时,成功显示警报,当我单击“取消”按钮时,警报已关闭,但出现类似这样的错误

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "view"

然后,当我再次单击确认按钮时,没有出现警报,我该如何解决此问题?非常感谢你

2 个答案:

答案 0 :(得分:1)

您正在直接从子组件更改道具(如vue所述)。 真正的方法是:

methods: {
  onCancel(){
    // this.view = false; <--- is wrong way
    this.$emit('update:view', false)
  }
  // ...
},

然后在父级中将其传递如下:

<Confirm :view.sync="alert.view"/>

答案 1 :(得分:0)

如vue.js指南所述:

  

所有道具在子属性和子属性之间形成单向绑定   父项:父项属性更新时,它将向下流动到   这个孩子,但并非相反。这样可以防止孩子   意外地改变了父母的状态,   使您的应用程序的数据流更难理解。

因此,您必须创建组件自己的状态,然后在组件内部修改状态。像这样:

<script>
    import $ from 'jquery';
    import 'imports-loader?window.jQuery=jquery,this=>window!widgster';

    export default { 
        name: 'Alert',
        data() {
            return{
                componentView: this.view
            }
        },
        props: {
            message: { default: 'Lorem ipsum dolor sit amet consectetur' },
            cancel: { default: 'Cancel' },
            ok: { default: 'Yes' },
            btnStyle: { default: 'btn btn-primary' },
            view: { default: false }
        },

        methods: {
            onCancel(){
                this.componentView = false;
            },

            onSubmit(){
                this.$emit('onSubmit');
            }
        }

    };
</script>