vuejs / babel-plugin-jsx

JSX for Vue 3
https://vue-jsx-explorer.netlify.app
MIT License
1.72k stars 141 forks source link

v-slots can not work. #441

Closed jackchoumine closed 2 years ago

jackchoumine commented 3 years ago

🧐 Problem Description

💻 Sample code

export default {
  name: 'RenderSlots',
  setup(props, { slots }) {
    const ButtonSlots = {
      left: () => <span>左边插槽</span>,
      default: ({ person }) => <span>默认插槽{person.age}</span>,
      right: ({ age }) => <span>右边插槽{age}</span>,
    }
    return () => <MyButton v-slots={ButtonSlots} />
  },
}

这样写 插槽渲染。

渲染结果为 :

<div v-slots="[object Object]"><button><span>按钮</span></button></div>

babel:

module.exports = {
  plugins: ['@vue/babel-plugin-jsx'],
}

🚑 Other information

希望文档再详细一些。

arronKler commented 3 years ago

Note: In jsx, v-slot should be replace with v-slots

const A = (props, { slots }) => (
  <>
    <h1>{ slots.default ? slots.default() : 'foo' }</h1>
    <h2>{ slots.bar?.() }</h2>
  </>
);

const App = {
  setup() {
    const slots = {
      bar: () => <span>B</span>,
    };
    return () => (
      <A v-slots={slots}>
        <div>A</div>
      </A>
    );
  },
};
itskaiway commented 2 years ago

I had the same problem.

index.tsx

export default defineComponent({
  name: 'CustomTable',
  setup() {
    const elDropDownSlots = {
      default: () => <span>Test</span>,
      dropdown: () => {
        return (
          <Fragment>
            <ElDropdownMenu>
              <ElDropdownItem icon="Plus">Action 1</ElDropdownItem>
              <ElDropdownItem icon="CirclePlus">Action 2</ElDropdownItem>
            </ElDropdownMenu>
          </Fragment>
        );
      },
    };
    return () => (
      <div>
        <ElDropdown trigger="click" v-slots={elDropDownSlots}>
          <ElTooltip content="Custom Columns" placement="top" effect="light">
            <ElButton circle>
              <SvgIcon name="fa fa-solid fa-arrow-up-a-z" />
            </ElButton>
          </ElTooltip>
        </ElDropdown>
      </div>
    );
  },
});

babel.config.js

const presets = [
  [
    "@babel/preset-env",
    {
      useBuiltIns: false, 
      modules: false, 
    },
  ],
  [
    "@babel/preset-typescript",
    {
      isTSX: true,
      allowNamespaces: true,
      allExtensions: true, 
    },
  ],
];

const plugins = [
  "@vue/babel-plugin-jsx",
  [
    "@babel/plugin-transform-runtime",
    {
      corejs: 3, 
    },
  ],
];

module.exports = { presets, plugins };

Then I got this result.

<div>
   <div class="el-dropdown" v-slots="[object Object]"> 
    <div class="el-dropdown--small el-tooltip__trigger el-tooltip__trigger"> 
     <button class="el-button el-button--small is-circle el-tooltip__trigger" type="button"> 
      <!--v-if-->
      <span class="">
        <i class="fa fa-solid fa-arrow-up-a-z svg-icon" style=""></i>
      </span> 
      </button> 
     <!--teleport start--> 
     <!--teleport end--> 
    </div> 
    <!--teleport start--> 
    <!--teleport end--> 
    <!--v-if--> 
   </div> 
</div> 

I'm baffled, it seems that my code is not wrong, maybe it is a problem with elementPlus or something wrong with the configuration of the project? I don't know how to proceed and look forward to your help @Amour1688 thanks.