Code Monkey home page Code Monkey logo

babel-plugin-jsx's Introduction

Babel Plugin JSX for Vue 3

npm package issues-helper

To add Vue JSX support.

English | 简体中文

Installation

Install the plugin with:

npm install @vue/babel-plugin-jsx -D

Then add the plugin to your babel config:

{
  "plugins": ["@vue/babel-plugin-jsx"]
}

Usage

options

transformOn

Type: boolean

Default: false

transform on: { click: xx } to onClick: xxx

optimize

Type: boolean

Default: false

enable optimization or not. It's not recommended to enable it If you are not familiar with Vue 3.

isCustomElement

Type: (tag: string) => boolean

Default: undefined

configuring custom elements

mergeProps

Type: boolean

Default: true

merge static and dynamic class / style attributes / onXXX handlers

enableObjectSlots

Type: boolean

Default: true

Whether to enable object slots (mentioned below the document) syntax". It might be useful in JSX, but it will add a lot of _isSlot condition expressions which increase your bundle size. And v-slots is still available even if enableObjectSlots is turned off.

pragma

Type: string

Default: createVNode

Replace the function used when compiling JSX expressions.

resolveType

Type: boolean

Default: false

(Experimental) Infer component metadata from types (e.g. props, emits, name). This is an experimental feature and may not work in all cases.

Syntax

Content

functional component

const App = () => <div>Vue 3.0</div>;

with render

const App = {
  render() {
    return <div>Vue 3.0</div>;
  },
};
import { withModifiers, defineComponent } from 'vue';

const App = defineComponent({
  setup() {
    const count = ref(0);

    const inc = () => {
      count.value++;
    };

    return () => (
      <div onClick={withModifiers(inc, ['self'])}>{count.value}</div>
    );
  },
});

Fragment

const App = () => (
  <>
    <span>I'm</span>
    <span>Fragment</span>
  </>
);

Attributes / Props

const App = () => <input type="email" />;

with a dynamic binding:

const placeholderText = 'email';
const App = () => <input type="email" placeholder={placeholderText} />;

Directives

v-show

const App = {
  data() {
    return { visible: true };
  },
  render() {
    return <input v-show={this.visible} />;
  },
};

v-model

Note: You should pass the second param as string for using arg.

<input v-model={val} />
<input v-model:argument={val} />
<input v-model={[val, ['modifier']]} />
// Or
<input v-model_modifier={val} />
<A v-model={[val, 'argument', ['modifier']]} />
// Or
<input v-model:argument_modifier={val} />

Will compile to:

h(A, {
  argument: val,
  argumentModifiers: {
    modifier: true,
  },
  'onUpdate:argument': ($event) => (val = $event),
});

v-models (Not recommended since v1.1.0)

Note: You should pass a Two-dimensional Arrays to v-models.

<A v-models={[[foo], [bar, 'bar']]} />
<A
  v-models={[
    [foo, 'foo'],
    [bar, 'bar'],
  ]}
/>
<A
  v-models={[
    [foo, ['modifier']],
    [bar, 'bar', ['modifier']],
  ]}
/>

Will compile to:

h(A, {
  modelValue: foo,
  modelModifiers: {
    modifier: true,
  },
  'onUpdate:modelValue': ($event) => (foo = $event),
  bar: bar,
  barModifiers: {
    modifier: true,
  },
  'onUpdate:bar': ($event) => (bar = $event),
});

custom directive

Recommended when using string arguments

const App = {
  directives: { custom: customDirective },
  setup() {
    return () => <a v-custom:arg={val} />;
  },
};
const App = {
  directives: { custom: customDirective },
  setup() {
    return () => <a v-custom={[val, 'arg', ['a', 'b']]} />;
  },
};

Slot

Note: In jsx, v-slot should be replaced 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>
    );
  },
};

// or

const App = {
  setup() {
    const slots = {
      default: () => <div>A</div>,
      bar: () => <span>B</span>,
    };
    return () => <A v-slots={slots} />;
  },
};

// or you can use object slots when `enableObjectSlots` is not false.
const App = {
  setup() {
    return () => (
      <>
        <A>
          {{
            default: () => <div>A</div>,
            bar: () => <span>B</span>,
          }}
        </A>
        <B>{() => 'foo'}</B>
      </>
    );
  },
};

In TypeScript

tsconfig.json:

{
  "compilerOptions": {
    "jsx": "preserve"
  }
}

Who is using


Ant Design Vue

Vant

Element Plus

Vue Json Pretty

Compatibility

This repo is only compatible with:

  • Babel 7+
  • Vue 3+

babel-plugin-jsx's People

Contributors

140948940 avatar amour1688 avatar beicause avatar caozhong1996 avatar choysen avatar dependabot-preview[bot] avatar dependabot[bot] avatar fxy060608 avatar g-plane avatar jawn-ha avatar john60676 avatar jokcy avatar kaelwd avatar leezng avatar martinoooo avatar maxim-mazurok avatar renovate[bot] avatar selicens avatar sodatea avatar sxzz avatar tangjinzhou avatar various-hooks avatar xrkffgg avatar yyx990803 avatar zhiyuanzmj avatar zhoudewei2526 avatar zkwolf avatar zouhangwithsweet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

babel-plugin-jsx's Issues

Should support passing object slots via JSX children

I may have missed the reasoning but I just noticed the usage of v-slots which is quite odd.

A more straightforward syntax should be:

const slots = {
  default: () => <div>default</div>,
  foo: () => <div>bar</div>
}
<Comp>{slots}</Comp>

Or inline:

<Comp>{{
  default: () => <div>default</div>,
  foo: () => <div>bar</div>
}}</Comp>

how to bind event?

I tried v-on, on, vOn, none worked. What is the correct way to bind an event?

provide used in function

import { provide } from 'vue';

cosnt Component =(props,{slots})=>{
provide('a',233);
return <div>slots.default()</div>
}

it produces [Vue warn]: provide() can only be used inside setup(). so it's my problem?

How to disable imports or specify a custom file?

I'm using the compiled file in the browser (Chromium only), and I need to specify the path like this (otherwise it throws an error):

import { createApp, createVNode, createTextVNode } from "./vue-files/vue.esm-browser.js";

Even if I add this line manually, the plugin still adds

import { createVNode, createTextVNode } from "vue";

which causes an error.

P.S. I've found https://github.com/FollowmeTech/babel-plugin-replace-import-path which replaces the path automatically. Leaving it here in case someone finds it helpful, or if someone knows a better solution.

Directives is not working properly

Vite jsx Directives is not working properly

const App = {
  data() {
    return { visible:false};
  },
  render() {
    return <input v-show={this.visible} />;
  },
};

Browser display:

<input v-show="false">

Directives did not parse properly
custom directive did not parse properly

antd vue

import { SearchOutlined } from '@ant-design/icons-vue';
vite 
runtime-dom.esm-bundler-4d575bf8.js:1180 [Vue warn]: SyntaxError: The requested module '/@modules/tinycolor2/tinycolor.js' does not provide an export named 'default'

[docs] 文档可以补充具体一点

  • 建议使用vModel
  • 自定义组件建议使用vCustom
  • directives: { custom: customDirective }中customDirective 该怎么用
  • slots子组件该怎么写
  • emit怎么写

function children should not be parsed

<Comp>
{() => <span></span>}
</Comp>

By default slot will be parsed to function to be performent, but if we write it to a function, it should stay that instead of wrap it to another function.

I think () => <span></span> is just what we called scopedSlot in vue.

Feature Request: $attrs type enhancement

const Child = defineComponent({
  props: {
    label: String
  },
  setup(_, ctx) {
    return () => [
      <div>{_.label}</div>,
      <input {...ctx.attrs}/>
    ];
  }
});

const Parent = defineComponent(() => {
  return () => <Child label="test" placeholder="please input"/>;
});

This code will show a error as following.

Type '{ label: string; placeholder: string; }' is not assignable to type 'IntrinsicAttributes & Partial<{}> & Pick<Readonly<{} & { label?: string | undefined; }> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "label" | ... 9 more ... | "class">'.
Property 'placeholder' does not exist on type 'IntrinsicAttributes & Partial<{}> & Pick<Readonly<{} & { label?: string | undefined; }> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "label" | ... 9 more ... | "class">'

Issue with using className instead of just class

Hello team,

I am currently developing new library that would output JSX template, so this output could be used in Vue and React projects.

Unfortunately, I found this library does not adhere DOM API same way as React do. My issue is caused by using className instead of just class, because I am using object destructing I cannot use class keyword. Same situation would happen by using htmlFor instead of just for. Both class and for are reserved keywords and cannot be used in object destructing.

So I want to ask, if there is possibility to introduce new option to convert those two attributes.

Thanks

Transitions not working (insert transition node)

I'm actually working on a Vue3 project with rollup and babel (ES6).
The transition is inserted as a dom node and is not recognized by VueJS.

That's my code.

export default {
    // ...
 
    render() {
        return (
            <transition name="fade" mode="out-in">
                {this.title && <Title title={this.title} />}
            </transition>
        );
    }
};

Turn into this.

e.createVNode(
    e.resolveComponent("transition"),
    { name: "fade", mode:"out-in" },
    { default: () => [ this.game && e.createVNode(p, null, null) ] }
);

And looks like this in the DOM Tree.

<transition name="fade" mode="out-in"> <!-- Why this div exist ? -->
    <div id="title">
         You are <span class="secondary">Innocent</span>
    </div>
</transition>

I don't understand where the issue could come from, maybe a JSX translation error or an issue relative to Vue3 ?

JSX element type 'List' does not have any construct or call signatures.

上级组件:
import { defineComponent, ref, reactive } from "vue";
import List from "@/components/List";
const Home = defineComponent(() => {

const list = ref([
5
]);
const flag = ref(
false
);

const list2 = reactive([
2, 3, 4, 5, 6
])
console.log(list);
const handleClick = () => {
list2[2] = 1003;
}
const handleClick2 = () => {
list2[2] = -10000;
}
return () => (
<>
// 使用list组件

{
list.value.map((item) =>

{item}


)
}
{
flag.value ?

true

:

false


}

  {
    list2.map((item) =>
      <h1>{item}</h1>
    )
  }
</>

);
})
export default Home;

// list 组件
import { onMounted, ref } from "vue";
const List = {
setup() {
const num = ref(0);
onMounted(() => {
console.log('aaa')
});
return () =>

{num.value}

}
}

export default List;

开启optimize的影响具体是什么?

开启optimize的影响会有什么,看起来诱惑很大,但是又不知道具体影响会是什么。跟vue3的什么有关系。

开启和关闭具体的优化提升又是多少

如何同时使用 RouterView / KeepAlive / Transition ?

目前的写法是

return (
        <div>
          <RouterView>
            {{
              default: ({ Component, route }: { Component: any; route: RouteLocation }) => {
                const name = route.meta.inTab ? 'fade' : null;

                const Content = (
                  <KeepAlive max={max} include={cacheTabs}>
                    <Component />
                  </KeepAlive>);

                return (
                  <Transition
                    name={name}
                    mode="out-in"
                    appear={true}
                  >
                    {Content}
                  </Transition>
                );
              },
            }}
          </RouterView>
        </div>

异常:

Uncaught (in promise) TypeError: Cannot read property '_' of null
    at initSlots (runtime-core.esm-bundler.js?5c40:2731)
    at setupComponent (runtime-core.esm-bundler.js?5c40:6183)
    at mountComponent (runtime-core.esm-bundler.js?5c40:3960)
    at processComponent (runtime-core.esm-bundler.js?5c40:3936)
    at patch (runtime-core.esm-bundler.js?5c40:3547)
    at componentEffect (runtime-core.esm-bundler.js?5c40:4053)
    at reactiveEffect (reactivity.esm-bundler.js?a1e9:42)
    at effect (reactivity.esm-bundler.js?a1e9:17)
    at setupRenderEffect (runtime-core.esm-bundler.js?5c40:4018)
    at mountComponent (runtime-core.esm-bundler.js?5c40:3976)

单独使用 RouteView + KeepAliveRouteView + Transition 都没有任何问题,就是 KeepAlive + Transition 一起就会出问题。

另外也尝试过使用 slots / defineAsyncComponent 等方式

<KeepAlive max={max} include={cacheTabs} v-slots={{default: ()=> <Component />}} />
// or
<KeepAlive max={max} include={cacheTabs} >
   {defineAsyncComponent(Component)}
</KeepAlive>

... Transition 一致
const Content = (
                  <Transition
                    name={name}
                    mode="out-in"
                    appear={true}
                  >
                    <Component />
                  </Transition>
                );
return (
                  <KeepAlive max={max} include={cacheTabs}>
                    <Content />
                  </KeepAlive>);

均只能 KeepAliveTransition 不在一起使用时正常。

在 vite 中测试了一下是可以一起使用的。 似乎 children 在 vite 是个array,在这边是个 object ? 不太清楚。。。

edit:

在KeepAlive外层加入 <div></div> 就不会报错,但Transition失效,估计要调整一下。

Feature Request: Support local relative img source in JSX

current

must declarative import from JS

import Logo from '@/assets/logo.png'

const App = defineComponent({
  setup() {
    return () => (<img alt="Vue logo" src={Logo} />)
  },
})

wanted

directly import local img by absolute path string

const App = defineComponent({
  setup() {
    return () => (<img alt="Vue logo" src="./assets/logo.png" />)
  },
})

Migrate jsx compoents

Some of my components are written in jsx (vue@2)
For example:

<script>
  import isArray from 'lodash/isArray'
  import isFunction from 'lodash/isFunction'
  import map from 'lodash/map'
  import { NewBsBox } from '@myComp'

  export default {
    name: 'Paragraph',
    functional: true,
    props: {
      content: {
        type: [String, Function, Array],
      },
      bs: {
        type: Object,
        default: () => ({}),
      },
    },
    render(h, { props }) {
      const { content, bs } = props
      let lst = content
      if (!isArray(lst)) {
        lst = [lst]
      }
      return (
        <NewBsBox bs={bs}>
          {
            map(lst, txt => {
              let text = txt
              if (isFunction(text)) {
                text = text(h)
              }
              return <NewBsBox>{text}</NewBsBox>
            })
          }
        </NewBsBox>
      )
    },
  }
</script>

If migrate to vue@3. Do i have to rewrite all my jsx components?

Dynamic Components support

  1. What is the recommended way to use dynamic component in JSX? In my case it is reading component names from configuration and use it in JSX.
  2. Do you plan to add/replicate previous functionality

In vue2 with composition-api: I have the following (simplified) code:

export default defineComponent({
  name:  "c-item-description",
  props: {
    item:                  {
      type:    Object,
      default: () => ({}) 
    },
    presentationComponent: String,
  },
  setup(props, context) {
    const { dynamicComponentRef} = useItemDescriptionConfiguration(props);
    return () => {
      const DynamicComponent: any = dynamicComponentRef.value || "t-item-description";
      return (
        <keep-alive>
          <DynamicComponent
            item={props.item}
          />
        </keep-alive>
      );
    };
  }
});

I found a workaround. Is it supposed to be so?

import { defineComponent, computed, ref,getCurrentInstance } from 'vue';
export default defineComponent({
  name:  "tsx-world",
  props: {
    msg: String
  },
  setup(props, context) {
    const dynamicComponent = ref("local-title"); // read from configuration
    const myTitleRef = computed(()=>getCurrentInstance()?.appContext?.components[dynamicComponent.value]);
    return () => {
      const myTitle = myTitleRef.value;
      return (
        <myTitle
          msg="dynamic component"
        />
    );}
  }
});

Bind multiple V- model.sync

template

<div  
    v-model:expandedKeys="expandedKeys"
    v-model:selectedKeys="selectedKeys"
    v-model:checkedKeys="checkedKeys">
</div>

How to use it in JSX?

<div 
v-model={[expandedKeys,'expandedKeys']}>
v-model={[selectedKeys,'selectedKeys']}>
</div>
JSX elements cannot have more than one attribute with the same name

Update not triggering with event listener on hoc

jsx: 1.0.0-beta.3
vue: 3.0.0-beta.23

import { h, Transition } from 'vue';

function MyTransition(props, ctx) {
  return h(Transition, ctx.slots.default);
}

setup() {
  const isOpen = ref(false);
  setInterval(() => { isOpen.value = !isOpen.value }, 1000);

  return () => <MyTransition>{isOpen.value && <h1>Visible</h1>}</MyTransition>;
}

does not seem to trigger an update on isOpen change. Converting it to an h function:

return () => h(MyTransition, isOpen.value ? <h1>Visible</h1> : null);
// or recommended
return () => h(MyTransition, () => isOpen.value ? <h1>Visible</h1> : null);

works fine though. I tried converting functional component to a normal component but the problem persists.

Component "default" in record with path "/book" is a function that does not return a Promise.

Hi, there is a problom when I use jsx-next。I try [email protected] with jsx-next. here.

.babel

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    "@vue/babel-plugin-jsx",
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": false,
        "helpers": true,
        "regenerator": true,
        "useESModules": false,
        "version": "7.0.0-beta.0"
      }
    ]
  ]
}

.package.json

{
// ...
"dependencies": {
    "axios": "^0.20.0",
    "classnames": "^2.2.6",
    "lodash": "^4.17.20",
    "vue": "^3.0.0-rc.10",
    "vue-cookies": "^1.7.4",
    "vue-i18n": "^8.21.0",
    "vue-router": "^4.0.0-beta.9",
    "vuex": "^4.0.0-beta.4"
  }
// ...
}

royter.js

import Layout from 'layout/Layout';

import Hello from 'views/Hello';
import Book from 'views/Book';

const routes = [
  {
    path: '/',
    component: Layout,
    children: [
      {
        path: '/',
        redirect: '/home',
      },
      {
        path: '/home',
        component: Hello,
      },
      {
        path: '/book',
        component: Book,
      },
    ],
  },
];

export default routes;

Business component

const Book = () => <div>this is Book component!</div>;

export default Book;

but, I got a error info.

runtime-core.esm-bundler.js:153 [Vue warn]: Component "default" in record with path "/book" is a function that does not return a Promise. If you were passing a functional component, make sure to add a "displayName" to the component. This will break in production if not fixed.

help me, thanks

does not support slot、v-slot、 vSlot

<compoentA>
  <template slot="name"></template>
or
  <template vSlot="name"></template>
or
  <template v-slot="name"></template>
</componentA>

I can not get $slots.name

Fragment with condition fails with undefined vnode

jsx: 1.0.0-beta.1
vue: 3.0.0-beta.20

return (
  <>
    <h1>test</h1>
    {false && (
      <h1>test</h1>
    )}
  </>
);

return (
  <>
    {false && (
      <h1>test</h1>
    )}
    <h1>test</h1>
  </>
);

Keeps failing with Invalid VNode type: undefined (undefined) error.

return (
  <>
    {false && (
      <h1>test</h1>
    )}
  </>
);

If you leave only the conditional, it works fine.

Webpack HMR not working

I am using vue js, without cli, since I need to configure webpack myself. I couldn't make jsx (vuejs 3) hot update by webpack HMR, and documentation about it is really poor and I spent several hours searching and trying to make it work.

Is there any package, which provides need loader?

How to use v-model in component?

// index.tsx
image

// Modal.tsx
image

I refer <A v-model={[val, 'argument', ['modifier']]} />, but got typescript error.

Version:
vue: 3.0.2
@vue/babel-plugin-jsx: 1.0.0-rc.3
typescript: 3.9.7

.vue 文件中使用 jsx, style 的 scoped 不起作用

style 的 scoped 生成的 data-v-xxxx, jsx 生成的为 data-v-xxxx-s

image

image

===

自己尝试看了一下源码, 没有解决的, 目前猜想是, jsx 的 vnode 丢失了 scopeId 属性, 导致 vue3 的 runtime 把 jsx 的 dom 当做了 slot.

因为 template 中执行了这个方法, 使得 vnode 获取了 scopeId

image

image

stable release date

when this plugin stable version will be released?
is there any thing not finished in the RC to consider it not stable ?

Extending the catalog of recognized built-in elements

Since Vue 3 allows for custom renderers as an alternative to @vue/runtime-dom, A custom runtime might have it's own collection of 'native' elements. See Vugel for a good example. It supports built-in tags like <shader> and <container>.

At the moment @vue/babel-plugin-jsx will flag unknown native elements as a callExpression (https://github.com/vuejs/jsx-next/blob/dev/packages/babel-plugin-jsx/src/utils.ts#L111) if they are not matched in the catalog of known svg or html tags. How can we allow new native elements to be compatible JSX in Vue?

能否使用slots和KeepAlive缓存

vue template

<router-view v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" />
  </keep-alive>
</router-view>

How to use it in JSX?

Develop VUE components using rollup,But the vue. CreateTextVNode unsuccessful

  • version
    vue: 3.0.0
    rollup:2.28.2
    @vue/babel-plugin-jsx: 1.0.0-rc.3

  • babel.config

{
  "plugins": ["@vue/babel-plugin-jsx"]
}
  • conponent detail
const bar: any = {
  name: "BBar",
  render() {
    return (
      <div class="bar">
        <div class="bar_text">aaa</div>
      </div>
    );
  },
};

bar.install = (app) => {
  app.component(bar.name, bar);
};

export default bar;
  • build file
var bar = {
      name: "BBar",
      render: function () {
        return vue.createVNode("div", {
          "class": "bar"
        }, [vue.createVNode("div", {
          "class": "bar_text"
        }, [vue.createTextVNode("aaa")])]);
      }
    };

    bar.install = function (app) {
      app.component(bar.name, bar);
    };
  • use component

When the page is displayed, the 'AAA' is not displayed, but the class name exists.

import bar from "../../lib/bar";
import App from "./App.vue";

const app = createApp(App);

app.use(bar );

app.mount("#app");
  • demo img
    image

  • supplement

  • brower console
    image

error when use this package with vue 3 and vue router next

there is error when setup with vue 3 , vue router next . and this plugin

  • Vue : 3.0.0-beta.14
  • Vue Router : 4.0.0-alpha.12
  • @ant-design-vue/babel-plugin-jsx : 1.0.0-alpha.4

Home.jsx

export default {
  name: "Home",
  setup() {
    return () => (
      <div class="home">
        <img alte="Vue Logo" src="../assets/logo.png" />
      </div>
    );
  }
};

router/index.js

import { createRouter, createWebHashHistory } from "vue-router";
import Home from "../views/Home.jsx";

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home
  }
];

const router = createRouter({
  history: createWebHashHistory(),
  routes
});

export default router;

babel.config.js

module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"],
  plugins: ["@ant-design-vue/babel-plugin-jsx"]
};

The Error when open home route in the console

TypeError: Cannot read property '$createElement' of undefined
    at setup (Home.jsx?6389:3)

[TSX]:怎样解决组件props为required时,使用v-model类型提示错误问题

组件定义Tag.tsx

import { defineComponent, PropType } from 'vue'

export default defineComponent({
  name: 'Tag',
  props: {
    value: {
      type: String as PropType<string>,
     // !!! 下一行代码是导致出错的地方
      required: true,
    },
  },
  emits: ['update:value'],
  setup(props, { emit }) {
    // 这里用InputEvent 会出错
    const handleInput = (e: any) => {
      emit('update:value', e.target.value)
    }

    return () => {
      const { value } = props

      return <input type="text" value={value} onInput={handleInput} />
    }
  },
})

组件使用demo.tsx

import { defineComponent, ref } from 'vue'
import Tag from './Tag'

export default defineComponent({
  setup() {
    const modelValue = ref('')

    return () => {
      return (
        <>
          <h1>{modelValue.value}</h1>
          {/* 这样写不出错,但太麻烦了 */}
          <Tag
            value={modelValue.value}
            {...{
              'onUpdate:value': ($event: string) => (modelValue.value = $event),
            }}
          />
          {/* !!!!! 下一行代码ts会出错 */}
          <Tag v-model={[modelValue.value, 'value']} />
        </>
      )
    }
  },
})

How does it work with vue-class-component?

When creating a project with the latest version of the vue cli (4.5.7), you can select jsx, typescript, or vue-class-component to create the project together, but errors are generated in the project.

<script lang="ts">
import { Options, Vue } from "vue-class-component";

@Options({})
export default class Home extends Vue {
  render(){
    return (
        <div>456</div>
    )
  }
}
</script>

slot中支持template标签么?

在slot中使用template标签不显示

const slots = { default: () => { <template> <NavMenuItem /> <NavMenuItem /> </template> } }

KeepAlive combined with RouterView

const Slots = {
    default: (router) => (
        <KeepAlive>
            <component is={router.Component}></component>
        </KeepAlive>
    )
}
return () => (
   <KeepAlive>
       <router-view v-slots={Slots}></router-view>
   </KeepAlive>
)
[Vue warn]: Component is missing template or render function. 
  at <Anonymous is= {__v_isVNode: true, __v_skip: true, type: {…}, props: {…}, key: null, …}anchor: nullappContext: nullchildren: nullcomponent: nulldirs: nulldynamicChildren: nulldynamicProps: nullel: nullkey: nullpatchFlag: 0props: {ref: RefImpl, onVnodeUnmounted: ƒ}ref: {i: {…}, r: RefImpl}scopeId: nullshapeFlag: 4ssContent: nullssFallback: nullstaticCount: 0suspense: nulltarget: nulltargetAnchor: nulltransition: nulltype: {name: "XXXXXX", render: ƒ}__v_isVNode: true__v_skip: true__proto__: Object > 
  at <KeepAlive> 
  at <RouterView> 

use via cdn

Is there any way to use this jsx plugin via cdn? Just like babel.min.js do with react.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.