Vue.js 更改道具

新手上路,请多包涵

我对如何更改组件内部的属性有点困惑,假设我有以下组件:

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

虽然它有效,但它会给出以下警告:

避免直接改变 prop,因为只要父组件重新渲染,该值就会被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“可见”(在组件中找到)

现在我想知道处理这个问题的最佳方法是什么,显然 visible 属性是在 DOM 中创建组件时传入的: <Foo :visible="false"></Foo>

原文由 woutr_be 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 348
2 个回答

引用 小提琴 中的代码

不知何故,你应该决定 一个 国家居住的地方,而不是两个。我不知道将它放在 Alert 中还是放在它的父级中是否更适合您的用例,但您应该选择一个。

如何决定国家在哪里

父组件或任何兄弟组件是否依赖于状态?

  • 是:那么它应该在父级(或在某些外部状态管理中)
  • 否:那么更容易让它处于组件本身的状态
  • 两者兼而有之:见下文

在极少数情况下,您可能需要组合。也许你想让父母和孩子都能够隐藏孩子。然后你应该在父母和孩子中都有状态(所以你不必在孩子里面编辑孩子的道具)。

例如,孩子可以在以下情况下可见: visible && state_visible ,其中 visible 来自道具并反映父母状态中的值,而 state_visible 来自孩子状态.

我不确定这是否是您想要的行为,但这里有一个片段。我有点假设您实际上只想在单击子组件时调用父组件的 toggleAlert

 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>

原文由 ArneHugo 发布,翻译遵循 CC BY-SA 4.0 许可协议

根据 Vue.js 组件文档

当父属性更新时,它会向下流向子属性,但不会反过来。那么,当事情发生时,我们如何与父母沟通呢?这就是 Vue 的自定义事件系统的用武之地。

使用 $emit('my-event) 从子级向父级发送事件。使用 v-on:my-event (或 @my-event )接收父级内部子级声明的事件。

工作示例:

 // child

Vue.component('child', {
  template: '<div><p>Child</p> <button @click="hide">Hide</button></div>',
  methods: {
    hide () {
      this.$emit('child-hide-event')
    }
  },
})

// parent

new Vue({
  el: '#app',
  data: {
    childVisible: true
  },
  methods: {
    childHide () {
      this.childVisible = false
    },
    childShow () {
      this.childVisible = true
    }
  }
})
 .box {
  border: solid 1px grey;
  padding: 16px;
}
 <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app" class="box">
  <p>Parent | childVisible: {{ childVisible }}</p>
  <button @click="childHide">Hide</button>
  <button @click="childShow">Show</button>
  <p> </p>
  <child @child-hide-event="childHide" v-if="childVisible" class="box"></child>
</div>

原文由 François Romain 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题