forum icon indicating copy to clipboard operation
forum copied to clipboard

ScopeSlots no JSX do Vue

Open IgorHalfeld opened this issue 6 years ago • 4 comments

Recentemente twittei sobre o ScopedSlots no JSX do Vue, falando como achava nojento a sintaxe que ficava, mas que era melhor escrever assim do que colocar uma string do componente, já que eu estava usando o Storybook

const expandableStory = () => ({
  render (h) { // eslint-disable-line
    const isDebug = boolean('Debug', false);

    const header = ({ toggle }) => (
      <div class="d-flex justify-content-between align-items-center">
        <div class="d-flex align-items-center">
          <h4 class="m-0">Expandable! :)</h4>
        </div>
        <div
          class="d-flex"
          on-click={toggle.trigger}
        >
          <Icon
            name={toggle.isOpen ? 'chevron-up' : 'chevron-down'}
            clickable={true}
            size="25px"
            type="solid"
          />
        </div>
      </div>
    );

    return (
      <Wrapper isDebug={isDebug}>
        <Expandable { ...{
          scopedSlots: {
            header,
          },
        }}>
          <template slot="header"/>
          <template slot="content">
            Content here
          </template>
        </Expandable>
      </Wrapper>
    );
  },
});

IgorHalfeld avatar Jan 12 '19 16:01 IgorHalfeld

Eu vi no Twitter e a primeira coisa que eu pensei foi usar um componente lógico para montar o slotScoped de uma maneira mais fácil. Eu respondi que ele era solução, mas fiquei te devendo um exemplo.

Eu copiei seu exemplo num CodeSandbox e consegui montar o componente lógico sem problemas e usar ele. Basicamente ele recebe o componente e os slots e monta eles sem muita mágica.

export default {
  name: 'SlotScoped',
  functional: true,
  props: {
    component: Object
  },
  render (h, context) {
    const scopedSlots = context.data.attrs || {};
    const Component = context.props.component;

    return (
      <Component {...{ scopedSlots }} />
    );
  }
};

Esse seria o uso dele no seu exemplo.

<SlotScoped component={Expandable} header={header} />

Eu testei bastante o JSX do Vue e li alguns artigos à respeito, para tentar me convencer do contrário. Mas o fato é que Vue não foi desenhado para ser usado com JSX e com os comportamentos sobre funções (HOCs, render props etc) que o React e outras frameworks tem.

Eu sei que o Storybook acaba te prendendo ao JSX, mas no mundo ideal é interessante passar as stories por alguma engine de bundle e usar SFC ou outra maneira de renderizar o template (HTML, Tagged Template etc) para montá-las. Não tenho exemplos disso e imagino que falte conteúdo de Vue com Storybook.

VitorLuizC avatar Jan 12 '19 17:01 VitorLuizC

@VitorLuizC

image

IgorHalfeld avatar Jan 12 '19 20:01 IgorHalfeld

Nice!

rof20004 avatar Jan 14 '19 12:01 rof20004

AWESOME!

nelsonseccofilho avatar Jan 15 '19 01:01 nelsonseccofilho