繁体   English   中英

如何从兄弟组件访问 Vue 组件元素属性

[英]How to access Vue component element property from sibling component

问题
我正在使用Vue CLI应用程序。 有一个孙子组件需要访问另一个组件的元素属性。 它实际上只需要clientHeight属性。

组件结构

所以Content2.vue组件需要访问这个元素的clientHeight属性: <div id="header"></div> (在Header.vue中)。

尝试的解决方案

  • 我试过使用$refs 并且根据this stackoverflow answer $refs仅适用于与父/子直接相关的组件。

  • 我还考虑将$refsclientHeight添加到商店( vuex ),但这似乎有点过分了。

  • 我总是可以 go vanilla 并使用querySelectorgetElementById 但认为可能有更好的东西。

谢谢你的帮助!

截至今天的可能解决方案:

  • $refs

    • $refs在声明它们的组件上设置。 如果你想访问它,你可以通过$parent来实现,比如this.$parent.$parent.$children[0].$refs.name
    • 优点:又快又脏。 作品。
    • 缺点:非常脆弱的耦合。 你可以从火车残骸中看到,没有多少程序员会发现它是一个好的解决方案。
  • Vuex

    • 获取clientHeight并将其添加到商店。 (不要添加$refs ,它们不是数据对象)
    • 优点/缺点:似乎矫枉过正。 如果你还没有 Vuex 并且只会为此目的添加它。 如果不是这种情况,Vuex 存储是存储诸如clientHeight之类的全局信息的“自然”位置之一。 几乎没有任何新的项目开发人员会惊讶地发现clientHeight被树中远处的组件共享,在 store 中。
  • 香草

    • 使用querySelectorgetElementById
    • 优点/缺点:这里的问题是耦合。 并且是一个隐藏的,更糟糕的一种。 这是一个快速而肮脏的解决方案,这将是原型设计和所有其他方面的一个很好的首选替代方案。 但是当应用程序 go 成熟时,这种隐藏的依赖是非常危险的。
  • this.$root : 根实例

    • 在根组件中创建一个data()并在那里有一个clientHeight属性。 您现在可以使用this.$root.clientHeight = newValue从任何组件设置它或使用this.$root.clientHeight读取它。
    • 优点:如果您不想/不需要为此拥有完整的 Vuex 商店,那就太好了。 从树中的任何组件都可以轻松访问。 反应性。
    • 缺点:您必须在根组件中声明data() 需要小心,因为有人可能会开始在那里添加属性,这很快就会变成一个糟糕的情况(有 Vuex 的缺点而没有优点)。 如果发生这种情况,您应该开始使用 Vuex。
  • 事件中心/总线

    • 创建一个 Vue 实例并将其用作事件中心/总线。 这类似于$root解决方案,不同之处在于您不是直接设置数据,而是发出和接收事件。
    • 优点:解耦,根目录中不需要data()
    • 缺点:仍然需要创建将充当集线器/总线的实例(尽管您也可以为此使用$root )。 这里的坏处是这种解决方案对您的情况不自然。 clientHeight的设置无论如何都不是事件(或者是?),所以这可能是不自然的。
  • 传递道具

    • 组件通过事件向上传递属性并通过道具向下传递,一次一跳。 换句话说, Header.vueclientHeight (通过事件)传递给App.vue ,然后传递给Content.vue (通过道具), Content2.vue (通过道具)。
    • 优点:不需要任何全局存储或$root /hub/bus 实例。 每个传递的数据(在我们的输出中)在每个组件的签名(事件或道具)中都是明确的。
    • 缺点:四处耦合; 仅用于传递的样板; 可以说是使用 Vuex 等商店的主要原因之一。
  • 通过provide / inject又名“远程道具”进行依赖注入

    • 与 props 不同的是,您可以(例如通过事件)将clientHeightHeader.vue传递给App.vue ,而App.vue将声明provide function。 然后Content2.vue将在其中使用inject 有关更多信息,请参阅文档演示
    • 缺点:在 Vue 应用中不太常见,一些新手开发者可能不知道。 仍然必须通过事件将clientHeightHeader.vue传递给App.vue ,尽管这只是一跳。
    • 优点:从App.vueContent2.vue的数据传递非常干净,毕竟,这就是provide的目的。

就个人而言,我会为 Vuex 使用 go,特别是如果您已经配置了它。 如果不是,我会使用$root ,但是在使用 Vuex 的 promise 的第一刻,任何其他道具在全球范围内都是必要的。

如果您绝对确定 CSS 无法解决此问题,并且您确实需要元素的clientHeight ,那么您只能从以下选择最不坏的解决方案:

  1. Header实例的idApp传递到ContentContent2 然后让Content2使用查询选择器来获取高度。 这似乎比Content2有一个硬编码的id更脆弱。
  2. Header计算自己的高度并向App发出事件,然后将高度传递给Content ,然后传递给Content2 请注意,如果高度不固定,您可能需要监听调整大小事件。
  3. 执行 (1) 或 (2) 但将其存储在 Vuex 中或使用事件总线而不是传递参数。

您选择哪一个不仅取决于问题中提出的内容。

如果没有其他组件需要知道Header的高度,我会选择 (1)。

如果其他组件需要知道Header的高度,或者Header实例是否在最佳 position 中以确定其自己的动态高度,我会选择 (2)。

如果我已经在使用某种全局 state 管理器,我会选择 (3)。

好吧,您可以尝试使用称为“事件总线”的东西。 您可以通过全局事件总线从任何内容向另一个内容发出事件,而其他内容会监听此事件。 然后你执行一个 function,它在事件总线上发出高度,你再次用“on”监听这个事件并执行一个 function

这可能会对您有所帮助: https://alligator.io/vuejs/global-event-bus/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM