Vue.js改变道具

wou*_*_be 23 javascript vue.js vue-component

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

{
    props: {
        visible: {
            type: Boolean,
            default: true
        }
    },
    methods: {
         hide() {
              this.visible = false;
         }
    }
} 
Run Code Online (Sandbox Code Playgroud)

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

避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖.而是根据prop的值使用数据或计算属性.Prop变异:"可见"(在组件中找到)

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

Arn*_*ugo 14

引用你小提琴中的代码

不知何故,你应该决定一个地方让国家生活,而不是两个.我不知道是否更适合将它放在用例中Alert或仅用于它的用例中,但是你应该选择一个.

如何决定国家的生活方式

父母或任何兄弟组成部分是否依赖于州?

  • 是的:然后它应该在父母(或在一些外部国家管理)
  • 否:然后在组件本身的状态下更容易
  • 有点:见下文

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

例如,如果出现以下情况visible && state_visible,则可以看到子项:,其中visible来自props并反映父项状态中的值,并且state_visible来自子项的状态.

我不确定这是否是你想要的行为,但这里有一个小提琴.我会假设您实际上只想toggleAlert在单击子项时调用父组件.

  • 对于表单子组件呢?也许您想将数据从父级传递给子级,能够对其进行编辑,然后如果发布成功,则将更新的数据传递回父级? (2认同)

Pan*_*潘俊杰 6

如果 prop 只对这个子组件有用,给子组件一个proplikeinitialVisible和一个datalike mutableVisible,并在created钩子(组件的数据结构组装时调用)中,简单地this.mutableVisible = this.initialVisible.

如果 prop 由父组件的其他子组件共享,您需要将其设为父组件data以使其可用于所有子组件。然后在 child 中,this.$emit('visibleChanged', currentVisible)通知 parent 进行更改visible。在父模板中,使用<ThatChild ... :visibleChanged="setVisible" ...>. 看看指南:http : //vuejs.org/v2/guide/components.html


Guy*_*uyC 5

阅读您的最新评论后,您似乎担心是否有逻辑来显示/隐藏父级的警报。因此我建议如下:

家长

# template
<alert :alert-visible="alertVisible"></alert>

# script
data () {
  alertVisible: false,
  ...
},
...
Run Code Online (Sandbox Code Playgroud)

然后在子警报中,您将 $watch 属性的值并将所有逻辑移至警报中:

孩子(警报)

# script
data: {
  visible: false,
  ...
},
methods: {
  hide () {
    this.visible = false
  },
  show () {
    this.visible = true
  },
  ...
},
props: [
  'alertVisible',
],
watch: {
  alertVisible () {
    if (this.alertVisible && !this.visible) this.show()
    else if (!this.alertVisible && this.visible) this.hide()
  },
  ...
},
...
Run Code Online (Sandbox Code Playgroud)


Fra*_*ain 5

根据Vue.js 组件文档

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

使用$emit('my-event)from child 向父级发送事件。使用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
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
.box {
  border: solid 1px grey;
  padding: 16px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)