【问题标题】:VueJS 2.0 - Communication Between Sibling Components - $emit and $onVueJS 2.0 - 兄弟组件之间的通信 - $emit 和 $on
【发布时间】:2016-11-01 01:56:54
【问题描述】:

我正在构建一个应用程序,如下所示..让我们看看我正在使用的一个模型..(我在后台安装了 Laravel 5.3,只是提供基本视图并提供 API。

例如:客户。
在 example.com/admin/clients 我加载了两个组件 <admin-clients-moderator><admin-clients-navigator>。主持人是修改当前选择的客户端的表单。 Navigator 用于导航并选择您要操作的客户端。

这些都作为全局组件加载到根 Vue 中,#admin-app

在 Vue.js 1.0 中,我让根实例使用 :selected-client.sync="selectedClient" 加载两个组件,该组件与根数据变量 "selectedClient" 相关联,并且当导航器选择新客户端时,这些组件接受 "selectedClient" 作为道具,导航器将更新selectedClient,并且由于它是通过引用传递的,因此这将更新根实例,因此也会更新同步的主持人,然后表单将填充该客户端的详细信息。

当表单被取消/保存时,我 $broadcast 来自组件 $parent 的一个事件,以便兄弟姐妹能够在“事件”中对其进行操作...

我正在尝试在 Vue.js 2.0 中复制此功能,但未能成功。

我已经阅读了关于从 1.0 更新到 2.0 的文档,但是他们警告我一直在使用的道具的突变,我一直无法弄清楚他们是如何设置 $emit 和 @ 987654331@ 函数使用eventHub 概述。

我不介意使用 eventHub 示例,但需要更多关于如何实现它的指导...

  • 我可以在同级组件中使用$on 吗?
  • 我需要在每个根实例中单独定义吗?
  • 是否应该为我正在处理的每个模型设置不同的根实例?
  • 是否有适合此的 vue 扩展/插件?
  • 我的方法是否正确?

下面的代码sn-ps

我的 app.js

Vue.component(
    'admin-clients-moderator',
    require('./components/admin/clients/Moderator.vue')
);

Vue.component(
    'admin-clients-navigator',
    require('./components/admin/clients/Navigator.vue')
);

var mainApp = new Vue({
    el: '#app',
    data: {
        selectedClient: {}, // I don't think i need this anymore
    }
});

我的 Navigator.vue(简化版)

.... Template ....
        <tr v-for="client in collection">
            <td>{{ client.name }}</td>
            <td>{{ client.status }}</td>
            <td>
                <button class="btn btn-primary btn-xs"
                        @click="select(client)"
                >
                    <i class="fa-search fa"></i>
                </button>

                <button class="btn btn-danger btn-xs"
                        @click="remove(client)"
                >
                    <i class="fa-trash fa"></i>
                </button>
            </td>
        </tr>

.... Javascript ....

<script>
export default {
    props: [],
    data() {
        return {
            selectedClient: {},
            collection: [],
            // TRAIT
            resource: null,
            resourceUri: "",
            modelName: ""
        };
    },
    methods: {
        select(client) {
            this.$emit('client-selected', {client});
            this.selectedClient = client;
        },
        remove(client) {
            this.deleteModel(client)
        },

Moderator.vue

.... JaveScript


<script>
export default {
    props: [],
    data() {
        return {
            selectedClient: {},
            // TRAIT
            resource: null,
            resourceUri: "",
            modelName: ""
        };
    },
    computed: {
        newClient() {
            return (this.selectedClient.id == null
            || this.selectedClient.id == 0);
        }
    },
    created() {
        this.$on('client-selected', this.setSelectedClient);
    },
    methods: {
        setSelectedClient(client) {
            this.selectedClient = client;
        },

【问题讨论】:

    标签: javascript vue.js dom-events


    【解决方案1】:

    我可以在我的兄弟组件中使用 $on 吗?

    是的。您可以在父组件和兄弟组件中使用 $on$emit

    我需要在每个根实例中单独定义吗?

    您可以添加一个全局变量。但我通常这样做 this.$root.$emit(my-event)

    我应该为我正在处理的每个模型设置不同的根实例吗?

    见#2

    有适合​​这个的 vue 扩展/插件吗?

    取决于您正在构建的应用程序,您可能需要检查Vuex

    我的方法是否正确?

    到目前为止看起来合法。

    【讨论】:

    • 谢谢。但是,我发现使用 this.$root.$emit() 只会触发 root 实例的 this.$on() 。我通过重用我之前的内容来解决这个问题......在我的 html 中使用 :model.sync="model" 在我的父组件和子组件之间同步 selectedClient 。但是,我希望能够将更多数据传递给 Navigator 孩子。当主持人创建一个新客户端时,它应该将该数据推送到导航器以将其附加到集合对象......除了使用道具之外,我如何向孩子发送数据?或者我可以使用道具作为一种数据传输对象...?
    • 仅对根实例意味着什么? .sync2.x 中已弃用。您可以传递一个包含事件中所有需要的数据的数组。如果是组件之间复杂的数据传输,我建议你看看 Vuex。不过我还没有完全使用它。
    【解决方案2】:

    每个 Vue 实例(根、子、兄弟)都是一个独立的事件中心。

    您在一个实例上 $emit 事件,您可以在同一实例上使用 $on 订阅事件通知。

    您可以使用this.$root.$on()this.$root.$emit() 将根实例用作事件总线并达到您的目的。

    您可以使用任何实例作为事件总线:$root 非常方便,因为可以使用 this.$root 从任何组件访问它。诀窍是所有的 $emit() 和 $on() 都应该应用于同一个 vue 实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-08
      • 2017-05-04
      • 2017-10-30
      • 1970-01-01
      • 2017-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      相关资源
      最近更新 更多