Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm a bit confused about how to change properties inside components, let's say I have the following component:

{
    props: {
        visible: {
            type: Boolean,
            default: true
        }
    },
    methods: {
         hide() {
              this.visible = false;
         }
    }
} 

Although it works, it would give the following warning:

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: "visible" (found in component )

Now I'm wondering what the best way to handle this is, obviously the visible property is passed in when created the component in the DOM: <Foo :visible="false"></Foo>

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
198 views
Welcome To Ask or Share your Answers For Others

1 Answer

Referencing the code in your fiddle

Somehow, you should decide on one place for the state to live, not two. I don't know whether it's more appropriate to have it just in the Alert or just in it's parent for your use case, but you should pick one.

How to decide where state lives

Does the parent or any sibling component depend on the state?

  • Yes: Then it should be in the parent (or in some external state management)
  • No: Then it's easier to have it in the state of the component itself
  • Kinda both: See below

In some rare cases, you may want a combination. Perhaps you want to give both parent and child the ability to hide the child. Then you should have state in both parent and child (so you don't have to edit the child's props inside child).

For example, child can be visible if: visible && state_visible, where visible comes from props and reflects a value in the parent's state, and state_visible is from the child's state.

I'm not sure if this is the behavour that you want, but here is a snippet. I would kinda assume you actually want to just call the toggleAlert of the parent component when you click on the child.

var Alert = Vue.component('alert', {
  template: `
        <div class="alert" v-if="visible && state_visible">
        Alert<br> 
        <span v-on:click="close">Close me</span>
      </div>`,
  props: {
    visible: {
      required: true,
      type: Boolean,
      default: false
    }
  },
  data: function() {
    return {
      state_visible: true
    };
  },
  methods: {
    close() {
      console.log('Clock this');
      this.state_visible = false;
    }
  }
});

var demo = new Vue({
  el: '#demo',
  components: {
    'alert': Alert
  },
  data: {
    hasAlerts: false
  },
  methods: {
    toggleAlert() {
      this.hasAlerts = !this.hasAlerts
    }
  }
})
.alert {
  background-color: #ff0000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo" v-cloak>
  <alert :visible="hasAlerts"></alert>

  <span v-on:click="toggleAlert">Toggle alerts</span>
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...