最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to foward $refs in Vue - Stack Overflow

programmeradmin0浏览0评论

I have a component which should pass everything on to the child. I'm successfully passing $attrs and $listeners already:

<template>
  <el-form v-on="$listeners" v-bind="$attrs" :label-position="labelPosition">
    <slot />
  </el-form>
</template>

But I'm unsure how to also forward $refs like we can do in React, so that when using my component like this:

<el-form-responsive
  class="form"
  :model="formValues"
  status-icon
  :rules="rules"
  ref="form"
  label-width="auto"
  @submit.native.prevent="submitForm"
>

Then this.$refs.form is actually a reference to the child <el-form>.

I would rather do this transparently, as in you pass exactly the same props to el-form-responsive as you would to a el-form without needing to know that refs has to be passed in a special way.

I have a component which should pass everything on to the child. I'm successfully passing $attrs and $listeners already:

<template>
  <el-form v-on="$listeners" v-bind="$attrs" :label-position="labelPosition">
    <slot />
  </el-form>
</template>

But I'm unsure how to also forward $refs like we can do in React, so that when using my component like this:

<el-form-responsive
  class="form"
  :model="formValues"
  status-icon
  :rules="rules"
  ref="form"
  label-width="auto"
  @submit.native.prevent="submitForm"
>

Then this.$refs.form is actually a reference to the child <el-form>.

I would rather do this transparently, as in you pass exactly the same props to el-form-responsive as you would to a el-form without needing to know that refs has to be passed in a special way.

Share Improve this question edited Oct 12, 2019 at 16:33 nanobar asked Oct 12, 2019 at 16:01 nanobarnanobar 66.4k25 gold badges151 silver badges174 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 6

I don't think it is possible to directly mimic React's ref. A ref attribute in Vue is just a string which is used to register a child component reference to the parent's $refs object during the render function.

Here are the links to documentations doc & doc

So basically it's a kind of inverted logic.. instead of passing a ref to a child in Vue we get it from the child into the parent. So it's not really possible at this point to create a grandchild reference, which is what you need.

There are some workarounds though.

1. Quick dirty and not transparent but technically it would work: In the parent component, which uses your el-form-responsive, on mounted hook we could replace the original child reference with the grandchild ref.

Your el-form-responsive component. Template:

<el-form ref="elform">

A parent which uses your el-form-responsive. Template:

<el-form-responsive ref="form">

Script:

...
mounted () {
  this.$refs.form = this.$refs.form.$refs.elform
}

And after this this.$refs.form is actually a reference to the granchild <el-form>

2. This one would be more elaborate, but probably mach better then the first method:

In order to make the el-form-responsive component really transparent you could expose some of the methods and properties from the child el-form component to any potential parent. Something like this:

el-form-responsive. Template:

<el-form ref="elform">

Script:

export default {
  data: () => ({
    whatever: null
  }),
  mounted () {
    this.whatever = this.$refs.elform.whatever
  },
  methods: {
    submit () {
      this.$refs.elform.submit()
    }
  }
}

So then inside some parent el-form-responsive could be used like this:

<el-form-responsive ref="form">
...
mounted () {
  const formWhatever = this.$refs.form.whatever // actually `whatever` from `el-form`
  this.$refs.form.submit() // eventually calls submit on `el-form`  
},

If you are working with a custom component with the script setup in Vue 3, it's worth nothing that template refs work like this.

Essentially, you will have to use defineExpose to "expose" your child component data to the parent component

Try this to replace parent's ref with child's , In el-form-responsive

<template>
  <el-form v-on="$listeners" v-bind="$attrs" :label-position="labelPosition" ref='ref'>
    <slot />
  </el-form>
</template>

mounted () {
  Object.entries(this.$parent.$refs).forEach(([key, value]) => {
    if (value === this) {
      this.$parent.$refs[key] = this.$refs.ref
    }
  })
...

It is work for me:

mounted() {
   Object.assign(Object.getPrototypeOf(this), this.$refs.formRef)
}

warning: insert to __proto__,maybe is bad way

发布评论

评论列表(0)

  1. 暂无评论