VueJS连接不相关(如父/子)组件

时间:2015-11-20 23:06:31

标签: javascript mvvm vue.js

我正在探索vue.js,并对如何解决某个问题提出疑问。

我的根组件有以下模板:

<div class="container">
    <div class="stage">
        <map :current-time="currentTime" :recording="recording"></map>
        <player :track="track" :current-time="currentTime"></player>
    </div>
    <control-panel :current-time="currentTime"></control-panel>
</div>

基本上,<player>组件里面有<video>元素,它将加载指定的轨道(隐藏本机控件)。因此,它实际上将在视频播放时(当前时间,播放状态等)驱动应用程序的状态。但是,<control-panel>有一个清理栏和按钮,用于指示视频状态(播放/暂停,搜索)。显然,在其中一个组件中更改此一般状态将影响其他两个组件(映射也将根据当前时间进行)。

但是,我想知道它是否更有意义,以及Vue是否支持提供对组件的引用,以便我可以为<control-panel>提供<player>的引用,以便它可以直接从状态更改它

或者这应该以一种全球状态传递给儿童还是以事件广播的方式完成?在我纠正之前,请考虑一个示例,其中有两个<player>和两个<control-panel> s不是分层相关的,但一个panelA与playerA和panelB与playerB一起使用。在这种情况下,我认为广播选项不在桌面上,对吗?

特别欢迎任何建议,因为我只是在学习Vue。

更新1

因此,在对Vue稍微熟悉并从社区回复之后,我想我已经想出了一个聪明的解决方案,可以将<player><control-panel>同步到一起。我的标记更改为以下内容:

<div class="container">
    <div class="stage">
        <map :current-time="currentTime" :recording="recording"></map>
        <player :track="track" :current-time="currentTime" v-ref:player></player>
    </div>
    <control-panel :current-time="currentTime" v-ref:player-controls :player="$refs.player"></control-panel>
</div>

请注意,v-ref<player>以及<control-panel>属性添加了:player="$refs.player"属性。这允许我将逻辑关联在一起。在我的脑海中,控制面板知道它控制的是谁或者是什么是有意义的。我将进一步测试它,但是现在,这似乎有效。

至于将<map>捆绑在一起,我最终会使用广播或仅由currentTime更新的双向<control-panel>。我将在我发布时更新这篇文章,如果与任何答案不同,将标记正确答案或发布我自己的答案。

更新2

请阅读下面的答案。我已经能够使用以下方法成功解决我的问题。

2 个答案:

答案 0 :(得分:0)

我认为将它们作为独立组件保留是个好主意;

然后,您可以在使用相同界面

的其他人时切换控制面板组件

(就像在电子商务应用中使用其他支付处理器切换Stripe一样)

$broadcasting$dispatching即使在每个广播/发送传递标识符密钥时,即使存在多个参与者也能正常工作,这样每个接收该消息的组件都可以立即确定是否已发送对他们来说。

答案 1 :(得分:0)

解决方案涉及采用 Update 1 中描述的方法。因为<video>元素在API中经过深思熟虑,所以将其转换为反应组件相当容易(虽然很烦人)。

视频元素的包装器最终以下列方式创建了几个computed属性:

'currentTime': {
    cache: false,
    get: function () {
        return this.$els.player.currentTime;
    },
    set: function (value) {
        this.$els.player.currentTime = value;
    }
}

必须使用属性cache: false,因为该属性不依赖于被动元素,每次查询属性时都需要重新计算。

不使组件完全反应是故意的。也就是说,我可以将所需的属性定义为props,并假设它们可以由父级提供并与之同步。只要<video>元素触发状态更改事件,就会在内部更新这些属性。

我还最终使用<video>方法将$emit元素的事件传播到组件的父级。这样做是因为组件简单地引入了HLS并充当了状态驱动程序。因此,它是完全被动的并且模仿普通的<video>元素是可以接受的。

控制面板成功引用了 Update 1 中的播放器组件。收到播放器的句柄后,很容易用$on订阅它的事件,然后在状态改变事件时简单地点击它的计算属性。

最后,map更容易实现,因为它遵循所有其他Vue示例中描述的或多或少的简单流程。实际上,地图的父母会记录当前时间。控制面板使用:currentTime.sync="currentTime"属性实际更新了此变量。然而,对于地图来说,感觉就像父母本身正在更新时间一样。