[英]How to access Vue component element property from sibling component
Problem问题
I'm working with a Vue CLI application.我正在使用Vue CLI应用程序。 There is a grandchild component that needs access to another component's element's properties.
有一个孙子组件需要访问另一个组件的元素属性。 It really only needs the
clientHeight
property.它实际上只需要
clientHeight
属性。
So Content2.vue component needs access to the clientHeight
property of this element: <div id="header"></div>
(in Header.vue ).所以Content2.vue组件需要访问这个元素的
clientHeight
属性: <div id="header"></div>
(在Header.vue中)。
Attempted Solutions尝试的解决方案
I've tried using $refs
.我试过使用
$refs
。 And according to this stackoverflow answer $refs
are only available to components directly related as parent/child.并且根据this stackoverflow answer
$refs
仅适用于与父/子直接相关的组件。
I've also considered adding the $refs
or clientHeight
to the store ( vuex ), but its seems like overkill.我还考虑将
$refs
或clientHeight
添加到商店( vuex ),但这似乎有点过分了。
I could always go vanilla and use querySelector or getElementById .我总是可以 go vanilla 并使用querySelector或getElementById 。 But thought there may be something better.
但认为可能有更好的东西。
Thanks for your help!谢谢你的帮助!
Possible solutions as of today:截至今天的可能解决方案:
$refs
are set on the component where they are declared. $refs
在声明它们的组件上设置。 If you want to access it, you can do it via $parent
, like this.$parent.$parent.$children[0].$refs.name
.$parent
来实现,比如this.$parent.$parent.$children[0].$refs.name
。 Vuex Vuex
clientHeight
and add it to the store.clientHeight
并将其添加到商店。 (Don't add the $refs
, they are not data objects) $refs
,它们不是数据对象)clientHeight
.clientHeight
之类的全局信息的“自然”位置之一。 Hardly any new developer to your project will be surprised to know that clientHeight
, which is shared by components far in the tree, is in the store.clientHeight
被树中远处的组件共享,在 store 中。 Vanilla香草
this.$root
: The root instance this.$root
: 根实例
data()
in the root component and have a clientHeight
property there.data()
并在那里有一个clientHeight
属性。 You can now set it from any component using this.$root.clientHeight = newValue
or read it using this.$root.clientHeight
.this.$root.clientHeight = newValue
从任何组件设置它或使用this.$root.clientHeight
读取它。data()
in the root component.data()
。 Requires care as someone may begin to add properties there, which can quickly become a bad situation (having the downsides of Vuex without the upsides).$root
solution, the difference being that instead of setting the data directly, you emit and receive events.$root
解决方案,不同之处在于您不是直接设置数据,而是发出和接收事件。data()
in the root.data()
。$root
for that).$root
)。 The bad part here is that this solution is not natural to your case.clientHeight
is not an event in any way (or is it?), so this could be unnatural. clientHeight
的设置无论如何都不是事件(或者是?),所以这可能是不自然的。 Passing around props传递道具
Header.vue
passes clientHeight
(via event) to App.vue
, that passes down to Content.vue
(via props) that passes further down to Content2.vue
(via props).Header.vue
将clientHeight
(通过事件)传递给App.vue
,然后传递给Content.vue
(通过道具), Content2.vue
(通过道具)。$root
/hub/bus instances.$root
/hub/bus 实例。 Every data passing (in our out) is clear in the signature (events or props) of each component. Dependency injection via provide
/ inject
aka "long-range-props" 通过
provide
/ inject
又名“远程道具”进行依赖注入
clientHeight
from Header.vue
to the App.vue
and App.vue
would declare a provide
function.clientHeight
从Header.vue
传递给App.vue
,而App.vue
将声明provide
function。 Then the Content2.vue
would use inject
in it.Content2.vue
将在其中使用inject
。 For more, see docs or demo .clientHeight
from Header.vue
to App.vue
via event, although that's just one hop.clientHeight
从Header.vue
传递给App.vue
,尽管这只是一跳。App.vue
to Content2.vue
is quite clean, after all, that's what provide
was designed for.App.vue
到Content2.vue
的数据传递非常干净,毕竟,这就是provide
的目的。 Personally, I'd go for Vuex, specially if you already have it configured.就个人而言,我会为 Vuex 使用 go,特别是如果您已经配置了它。 If not, I'd use
$root
, but with the promise of using Vuex the first moment any other prop becomes necessary globally.如果不是,我会使用
$root
,但是在使用 Vuex 的 promise 的第一刻,任何其他道具在全球范围内都是必要的。
If you are absolutely sure this can't be solved with CSS and you really do need the element's clientHeight
, you are left choosing the least-bad solution from the following:如果您绝对确定 CSS 无法解决此问题,并且您确实需要元素的
clientHeight
,那么您只能从以下选择最不坏的解决方案:
id
of the Header
instance from App
to Content
to Content2
.Header
实例的id
从App
传递到Content
到Content2
。 Then have Content2
use a query selector to get the height.Content2
使用查询选择器来获取高度。 This seems slightly less brittle than having Content2
have a hard-coded id
.Content2
有一个硬编码的id
更脆弱。Header
compute its own height and emit an event to App
, which then passes the height to Content
and then to Content2
. Header
计算自己的高度并向App
发出事件,然后将高度传递给Content
,然后传递给Content2
。 Note that you may need to listen for resize events if the height is not fixed. Which one you choose depends on more than what's presented in the question.您选择哪一个不仅取决于问题中提出的内容。
I'd choose (1) if no other components need to know the height of the Header
.如果没有其他组件需要知道
Header
的高度,我会选择 (1)。
I'd choose (2) if other components need to know the height of the Header
or if the Header
instance is in the best position to determine its own dynamic height.如果其他组件需要知道
Header
的高度,或者Header
实例是否在最佳 position 中以确定其自己的动态高度,我会选择 (2)。
I'd choose (3) if I was already using some sort of global state manager.如果我已经在使用某种全局 state 管理器,我会选择 (3)。
Well you can try to use something called "event bus".好吧,您可以尝试使用称为“事件总线”的东西。 You can emit an event from any content over the global event bus to another content, and the other content listen to this event.
您可以通过全局事件总线从任何内容向另一个内容发出事件,而其他内容会监听此事件。 Then you execute an function that emits over the event bus the height and u listen again with "on" on this event and execute an function
然后你执行一个 function,它在事件总线上发出高度,你再次用“on”监听这个事件并执行一个 function
This might help you: https://alligator.io/vuejs/global-event-bus/这可能会对您有所帮助: https://alligator.io/vuejs/global-event-bus/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.