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

Vad*_*dym 5 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>
Run Code Online (Sandbox Code Playgroud)

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

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

或者这应该以一种全球状态传递给儿童还是以事件广播的方式完成?在我纠正之前,考虑一个例子,其中有两个<player>s和两个<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>
Run Code Online (Sandbox Code Playgroud)

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

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

更新2

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

Vad*_*dym 0

该解决方案涉及采用更新 1中描述的方法。由于该<video>元素通过 API 进行了深思熟虑,因此将其转换为响应式组件相当容易(尽管很烦人)。

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

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

cache: false必须使用属性,因为该属性不绑定到反应性元素,并且每次查询该属性时都需要重新计算。

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

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

控制面板成功引用了更新 1中所述的播放器组件。收到播放器的句柄后,可以轻松订阅其事件$on,然后在状态更改事件时简单地点击其计算属性。

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