【问题标题】:Opening (and Closing) vue material dialog on different components在不同组件上打开(和关闭)vue 材质对话框
【发布时间】:2020-08-19 23:59:39
【问题描述】:

我正在尝试在子组件上打开一个 vue 材质对话框。我希望触发按钮保留在父组件上,对话框模板保留在子组件上,以便维护。

对话框正确打开,但是当我单击关闭按钮时,对话框关闭,但我无法使用触发按钮再次打开它。我正在使用道具将变量从父级传递给子级。

如何关闭对话框并再次打开?

app.vue:

<template>
  <div>
    <button @click="showContextMenu = true">
      <span>Show Context Menu</span>
    </button>
    <contextMenu :showContextMenu="showContextMenu"></contextMenu>
  </div>
</template>

<script>
import contextMenu from "contextMenu.vue";

export default {
  data() {
    return {
      showContextMenu: false,
    };
  },
  components: {
    contextMenu,
  },
};
</script>

contextMenu.vue:

<template>
  <md-dialog :md-active.sync="showContextMenu">
    <md-dialog-title>Preferences</md-dialog-title>Dialog
    <md-dialog-actions>
      <md-button class="md-primary" @click="showContextMenu = false">Close</md-button>
    </md-dialog-actions>
  </md-dialog>
</template>

<script>
export default {
  data() {
    return {};
  },
  props: ["showContextMenu"],
};
</script>

【问题讨论】:

    标签: vue.js vue-material


    【解决方案1】:

    您实际上是在尝试设置app 中存在的属性,但您在contextMenu 中将其切换为false。

    不推荐使用变异道具。

    改为这样做

    App.vue

    <template>
      <div>
        <button @click="showContextMenu = true">
          <span>Show Context Menu</span>
        </button>
        <contextMenu v-if="showContextMenu" 
         :showContextMenu="showContextMenu" 
         @close-context="showContextMenu = false"> //capturing event close-context
        </contextMenu>
      </div>
    </template>
    

    然后在contextMenu 中,向父级发出一个事件。

    contextMenu.vue

    <template>
      <md-dialog :md-active.sync="showContextMenu">
        <md-dialog-title>Preferences</md-dialog-title>Dialog
        <md-dialog-actions>
          <md-button class="md-primary" @click="closeContext">Close</md-button>
        </md-dialog-actions>
      </md-dialog>
    </template>
    
    <script>
    export default {
      data() {
        return {};
      },
      methods: {
        closeContext() {
          this.$emit('close-context'); // emitting to parent
        },
      props: ["showContextMenu"],
    };
    </script>
    

    【讨论】:

    • 谢谢。您为我指出了正确的方向,尽管我更喜欢 AndrejH 的回答,因为它通过直接内联编写 $emit 方法为我节省了一些代码。非常感谢。
    • 一般建议避免内联函数调用。在这种情况下,它只是设置一个布尔值。您可能想做一些复杂的事情,然后用数据发出事件。在那种情况下,内联会非常痛苦。无论如何,很高兴我的回答对您有所帮助。
    【解决方案2】:

    将 props 传递给子组件会创建单向绑定,因此您不能使用它们将状态从子组件传递给其父组件。您可以让contextMenu 发出一个事件,在该事件上更改父级中showContextMenu 变量的值。请记住以下几点:props 用于将状态从父组件传递到子组件,事件用于执行相反的操作。

    代码如下所示:

    app.vue:

    <template>
      <div>
        <button @click="showContextMenu = true">
          <span>Show Context Menu</span>
        </button>
        <contextMenu :showContextMenu="showContextMenu" @close="showContextMenu = false"></contextMenu>
      </div>
    </template>
    
    <script>
    import contextMenu from "contextMenu.vue";
    
    export default {
      data() {
        return {
          showContextMenu: false,
        };
      },
      components: {
        contextMenu,
      },
    };
    </script>
    

    contextMenu.vue:

    <template>
      <md-dialog :md-active.sync="showContextMenu">
        <md-dialog-title>Preferences</md-dialog-title>Dialog
        <md-dialog-actions>
          <md-button class="md-primary" @click="$emit('close')">Close</md-button>
        </md-dialog-actions>
      </md-dialog>
    </template>
    
    <script>
    export default {
      data() {
        return {};
      },
      props: ["showContextMenu"],
    };
    </script>
    

    【讨论】:

    • 按esc键时,我看到这个错误[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: "active"
    • 点击对话框的外部怎么样? md-overlay 将 md-active.sync 中的任何道具设置为 false ,即使此类道具未在本地定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2020-01-09
    • 2018-06-27
    • 2019-07-24
    相关资源
    最近更新 更多