New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add component instances to slots on mount #41

Closed
alexjoverm opened this Issue Sep 5, 2017 · 9 comments

Comments

Projects
None yet
6 participants
@alexjoverm
Copy link

alexjoverm commented Sep 5, 2017

Is there a way to somehow pass component instances to the slots property of mount? The use case is, say I have a component that has a required property:

export default {
    name: 'Message',
    props: {
      message: {
        type: String,
        required: true,
        validator: value => value.length > 1
      }
  }

Then if in a test I wanna add a list of Message as the default slots, I cannot do it like it's documented: I'll get a "message" property is required error:

mount(MessageList, {
  slots: {
    default: messages
  }
})

I tried using mount and getting the vm out of it, or also extending the component and using new Vue(...) but I get the error [Vue warn]: Failed to mount component: template or render function not defined.:

beforeEach(() => {
  const indexes = [0, 1, 2]
  const messages = indexes.map(i => mount(Message, {
    propsData: { message: `Message ${i}` }
  }).vm)

  cmp = mount(MessageList, {
    slots: {
      default: messages
    }
  })
})

So, how's it possible to accomplish that?

@eddyerburgh

This comment has been minimized.

Copy link
Member

eddyerburgh commented Sep 5, 2017

There isn't currently a way to pass mounted components to slots.

There's some work being done in avoriaz to add the option to pass Wrappers as slots. But right now there's an unsolved bug - eddyerburgh/avoriaz#113.

I'd like to add this functionality, but don't have time to work on this feature right now. I'd welcome a PR and could give you some guidance if you were willing to make one.

@alexjoverm

This comment has been minimized.

Copy link

alexjoverm commented Sep 5, 2017

Thanks, right now I also don't have the time, but probably in the coming days I can get some and lend a hand in there. I'll contact you for that guidance in that case ;).

@alexjoverm

This comment has been minimized.

Copy link

alexjoverm commented Sep 5, 2017

FYI, as a workaround, this seems to work:

mount(MessageList, {
  slots: {
    default: {
      render(h) {
        return h(Message, { props: { message: 'hey' }  })
      }
    }
  }
})
@sebastiandedeyne

This comment has been minimized.

Copy link

sebastiandedeyne commented Nov 13, 2017

Hmm this doesn't seen to work for me. The component is created, but the props are undefined when I try to access them...

const table = mount(TableComponent, {
    propsData: {
        data: [
            { firstName: 'John', lastName: 'Lennon' },
            { firstName: 'Paul', lastName: 'McCartney' },
            { firstName: 'George', lastName: 'Harrison' },
            { firstName: 'Ringo', lastName: 'Starr' },
        ],
    },
    slots: {
        default: {
            render(h) {
                return h(TableColumn, {
                    props: {
                        show: 'firstName',
                        label: 'First name',
                    },
                });
            },
        },
    },
});

console.log(table.vm.$slots.default[0].componentInstance.show);
@mouafa

This comment has been minimized.

Copy link

mouafa commented Dec 8, 2017

try this:

const tableCol = table.find(TableColumn)
expect(tableCol.vm.show).toBe('firstName')
expect(tableCol.vm.label).toBe('First name')
@eddyerburgh

This comment has been minimized.

Copy link
Member

eddyerburgh commented Jan 27, 2018

We aren't going to implement this at the moment. You can pass a component, but not an instance.

@phobetron

This comment has been minimized.

Copy link

phobetron commented Apr 5, 2018

@eddyerburgh Is this functionality anywhere on the roadmap? I have some functionality that can't really be tested without access to instance properties, and workarounds don't always work well.

@eddyerburgh

This comment has been minimized.

Copy link
Member

eddyerburgh commented Apr 5, 2018

It's not on the roadmap. I would review a PR if somebody wants to add it.

@hiendv

This comment has been minimized.

Copy link

hiendv commented Jul 5, 2018

If anyone is looking for a workaround, try testing with another Component

let App = Vue.extend({
  render (h) {
    return h(Parent, {
      props: {
        // parent props
      }
    }, [
      // slots
      h(Child, {
        props: {
          // child props
        }
      })
    ])
  }
})

it('has a button', () => {
  let wrapper = mount(App)
  console.log(wrapper.find(Parent).vm.$slots.default)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment