GithubHelp home page GithubHelp logo

vuejs / jsx-vue2 Goto Github PK

View Code? Open in Web Editor NEW
1.5K 1.5K 97.0 1.75 MB

monorepo for Babel / Vue JSX related packages

Home Page: https://jsx-vue2-playground.netlify.app/

JavaScript 93.22% HTML 0.28% TypeScript 5.74% CSS 0.76%

jsx-vue2's Introduction

Babel Preset JSX

Configurable Babel preset to add Vue JSX support. See the configuration options here.

Compatibility

This repo is only compatible with:

Installation

Install the preset with:

npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props

Then add the preset to babel.config.js:

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

Syntax

Content

render() {
  return <p>hello</p>
}

with dynamic content:

render() {
  return <p>hello { this.message }</p>
}

when self-closing:

render() {
  return <input />
}

with a component:

import MyComponent from './my-component'

export default {
  render() {
    return <MyComponent>hello</MyComponent>
  },
}

Attributes/Props

render() {
  return <input type="email" />
}

with a dynamic binding:

render() {
  return <input
    type="email"
    placeholder={this.placeholderText}
  />
}

with the spread operator (object needs to be compatible with Vue Data Object):

render() {
  const inputAttrs = {
    type: 'email',
    placeholder: 'Enter your email'
  }

  return <input {...{ attrs: inputAttrs }} />
}

Slots

named slots:

render() {
  return (
    <MyComponent>
      <header slot="header">header</header>
      <footer slot="footer">footer</footer>
    </MyComponent>
  )
}

scoped slots:

render() {
  const scopedSlots = {
    header: () => <header>header</header>,
    footer: () => <footer>footer</footer>
  }

  return <MyComponent scopedSlots={scopedSlots} />
}

Directives

<input vModel={this.newTodoText} />

with a modifier:

<input vModel_trim={this.newTodoText} />

with an argument:

<input vOn:click={this.newTodoText} />

with an argument and modifiers:

<input vOn:click_stop_prevent={this.newTodoText} />

v-html:

<p domPropsInnerHTML={html} />

Functional Components

Transpiles arrow functions that return JSX into functional components, when they are either default exports:

export default ({ props }) => <p>hello {props.message}</p>

or PascalCase variable declarations:

const HelloWorld = ({ props }) => <p>hello {props.message}</p>

jsx-vue2's People

Contributors

allex avatar angusfu avatar antfu avatar chenjiahan avatar chrisvfritz avatar dependabot[bot] avatar emosheeep avatar nickmessing avatar nooooooom avatar sodatea avatar sxzz avatar visualfanatic avatar znck 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

jsx-vue2's Issues

underscored props get broken

Upgrading from this package's predecessors and running into an issue where underscored props get broken ..

I have a prop on a child component called "ecs_tasks" .. but when the component receives it, its $attrs contains this prop's value in a key ecs instead.

Data spread operation mutates given object

Hey, I'm leaving this issue here, as well as vuejs/babel-helper-vue-jsx-merge-props#10, because I'm not sure which repository is where bugs will be handled going forward.

I suppose this could be intended behavior, but if it is, I'd kinda wanna know why.

I was writing some stories for my vue storybook and ran into an instance where I was iterating over different variations of a component like so:

render() {
    types = [...blah];
    types.map(t => {
        const data = { attrs: { types[t]: true } };
        <ProfilePic {...data} />
        <ProfilePic url={picUrl} {...data} />
    }
}

I was getting odd behavior on the second component, and I managed to track it down to the fact that the data object is actually mutated in the creation of the first element. All the props are removed from the data object when props are "extracted" and applied to the element.

Is this intended behavior? or a bug? It seems like the data object to be merged should be cloned instead of mutated, but let me know if there's a reason for this. I can create a repro code pen if needed.

ReferenceError: h is not defined

babel.config.js

module.exports = {
  presets: [
    '@babel/preset-env',
    '@vue/babel-preset-jsx'
  ],
  plugins: [
    '@babel/plugin-transform-modules-commonjs',
    '@babel/plugin-transform-runtime',
  ],
  comments: false,
  env: {
    test: {
      presets: ['@babel/preset-env'],
      plugins: [
        'babel-plugin-dynamic-import-node',
      ],
    },
  },
};

target property in tsconfig is esnext. I also tried es2015. Still doesn't work. The file extension is .tsx. Please let me know if you more details

how to use v-slot in jsx

return (

{item.placeholder + '1233423'}

{item.placeholder}


)
these two slots are all in default,why?if i was wrong,then how i can do to fix this?

Conversation: Support & future curators

First of all, thanks to @nickmessing for the work here on Vue JSX and this Monorepo. The following is not a compliant in any way, but with reference to #2, I'm just a little concerned around the lack of a roadmap and the development direction, and want to spark a discussion of what could be done to help take things forward.

As a little background, one of the key reasons we chose to use Vue over React in my organisation was the ability to still use JSX, and with recently having to upgrade to Node 10, NPM 6 and Babel 7 (for various maintainability & security reasons), this package is the only way I can find to restore some JSX functionality to my organisation's work, using these dependencies.

I know that this package is 0.1.0, and hasn't yet matured. Is there a way that we, as a community can help to get this package to where it needs to be? Obviously we can report issues and submit PR's for how we believe things should be fixed, but with no understanding of design decisions, or the intended direction of development, it's a little difficult to do things in accordance with the wishes of the maintainer.

Importantly, there is a big reliance here on @nickmessing to do all the merging and upversioning. Would it be possible to get more people from the Vue team, or even more people with an interest in JSX, as curators for this repository in the future, to help accelerate the development and maturation of this repo?

Again, this isn't a complaint or a criticism, I really appreciate @nickmessing's work here; I just want to spark conversations to help move this forward.

HOCs not working correctly

There are a few things that right now do not work

function Component(WrappedComponent) {
  return function(h, {props, listeners}) {
    return h(<div>whatever</div>)
}
}
export default Component(Select);

Expected output <div>whatever</div>, does not print anything.

function Component(WrappedComponent) {
  return function(h, {props, listeners}) {
    return h(<div class="whatever"><WrappedComponent/></div>)
}
}
export default Component(Select);

Expected output <div class="whatever">{WrappedComponent contents}</div>, does not print the enclosing div (<div class="whatever">), but only the contents of WrappedComponent.

function Component(WrappedComponent) {
  return function(h, {props, listeners}) {
    return h(<WrappedComponent class="whatever"/>)
}
}
export default Component(Select);

Does not augment the component with class whatever. I tried also with className and

return h(<WrappedComponent/>, {class: "whatever"})

it seems that 「slots」 don't work

the following is the code which with the problem.

the child component :

export default {
    mounted(){
    },
    render() {
        return <div>
                    Hello,<slot name="default"></slot>
                </div>
    }
}

the parent component:

<template>
       <JsxComp>Slot Word</JsxComp>
</template>
<script>
export default {
  components: { JsxComp }
};
</script>

the render result:

Hello,

the slots doesn't render anything

here is a repo to reproduce it.

https://github.com/light0x00/vue-jsx-issue.git

Duplicate declaration "h" (This is an error on an internal node. Probably an internal error.)

TableCoumn.vue

<script lang="tsx">
  import { State, Getter, Action } from 'vuex-class';
  import { Component, Vue, Prop, Watch, Model } from 'vue-property-decorator';

  const isNotIn: any = (obj: any, v: any, key: any) => v && (obj[key] = v);

  import pluginHelper from './TablePlugin';

  @Component({
    components: {},
  })
  export default class TableColumn extends Vue {

    @Prop({
      type: Object, default: () => {
      }
    })
    private column: any;

    @Prop({ type: String, default: '' })
    private pk: string;

    private render(h: any) {
      const me = this;

      function renderChild(column: any) {
        const ps: any = { attrs: {} };
        const { header, dataIndex, width, formatter, children, type, pk, slot } = pluginHelper(column, h);
        ps.attrs.key = dataIndex || (pk + type);
        isNotIn(ps.attrs, header, 'label');
        isNotIn(ps.attrs, dataIndex, 'prop');
        isNotIn(ps.attrs, width, 'width');
        isNotIn(ps.attrs, formatter, 'formatter');

        if (slot) {
          //搞定
          ps.scopedSlots = { default: ({ row }:{ row: any }) => slot({ row, column }) };
        }

        if (column.children) {
          ps.attrs.headerAlign = 'center';
          return <el-table-column { ...ps }>
            {
              column.children.map((child: any) => {
                return renderChild(child);
              })
            }
          </el-table-column>;
        }
        else {
          return <el-table-column
            { ...ps }>
          </el-table-column>;
        }
      }

      if (this.column) {
        return renderChild(this.column);
      }
    }
  }
</script>

TablePlugin.ts


export default (column: any, h: any) => {
  column = customs(column, h);
  return column;
}


const customs = (column: any, h: any) => {
  if ('render' in column) {
    const slot = column.render(h);

    const { render, ...left } = column;
    return {
      ...left,
      slot
    };
  }
  return column;
};

view.vue

<template>
    <el-table
      :data="list"
      v-loading="loadings"
    >
      <table-col
        v-for="(column,$index) in tableConfig.columns"
        :column="column"
        :key="$index"
      >
      </table-col>
    </el-table>
</template>

<script lang="tsx">
  import { Component, Vue, Prop, Watch, Model } from 'vue-property-decorator';
  @Component({
    components: {
      TableCol,
    },
  })
  export default class GroupDoor extends ListBase {
      protected tableConfig: any = {
      defaultSort: {},
      data: [],
      columns: [
        {
          label: '售价',
          prop: 'sale_price',
          sortable: 'custom',
          width: 130,
          _checked: true,
          _disabled: true,
          render: () => (data:any) => {
            return <div>
            </div>;
          },
        },
      ],
    };
  }
</script>

Question/Feature Request: How to use prop.sync or update:prop?

Is there currently a way to use prop.sync or even its longhand form in v-on:update:prop? I've tried a few different syntax variations and haven't found anything that works. Currently, the only way I can do prop syncing is like this:

<MyComponent
    myprop={this.myprop}
    {...{
        on: {
            "update:myprop": val => this.myprop = val
        }
    }}
></MyComponent>

Functional components type error ts2322

<VIf condition={true}>

不能将类型“{ condition: boolean | undefined; }”分配给类型“{ props: any; }”。
类型“{ props: any; }”上不存在属性“condition”。ts(2322)

如果改成 (ctx)=><div>ctx.props.condition</div> 没问题
这种写法在非jsx中 注册到components中的时候控制台也会报类型错误,但不影响编译

ReferenceError: h is not defined

This code works:

<script>
export default {
  name: 'DmFoo',
  functional: true,
  render() {
    return <p>hello</p>;
  }
};
</script>

However this does not:

<script>
export default {
  name: 'DmFoo',
  functional: true,
  render: () => <p>hello</p>
};
</script>

auto inject h error with tsx vue-class-component

like this #34

when you auto inject h with vue-class-component and tsx will get some thing wrong

build just fine ,no error,but there will actually be problems

there is my example repo

components/test.vue look like is:

  
<template>
  <div></div>
</template>
<script lang="tsx">
import { Component, Vue } from "vue-property-decorator";
@Component
export default class App extends Vue {
  test = (h: any) => <div>123</div>;
}
</script>

then, the test.vue will be built into this :

/*#__PURE__*/
function (_Vue) {
  Object(inherits["a" /* default */])(App, _Vue);

  function App() {
    var _this;

    Object(classCallCheck["a" /* default */])(this, App);

    // the  _this variable is undefined,I think this is the problem !
    var h = _this.$createElement;
    _this = Object(possibleConstructorReturn["a" /* default */])(this, Object(getPrototypeOf["a" /* default */])(App).apply(this, arguments));

    _this.test = function (h) {
      return h("div", ["123"]);
    };

    return _this;
  }

  return App;
}(vue_property_decorator["c" /* Vue */]);

as you can see the h variable is inject before _this definition, then an error occurred

v-model[type=] is not supported

It looks like components with v-model are not being correctly flagged as a component. This means the isComponent check is failing and falling through to the error.

For example:

render() {
    return (
        <div>
            <vue-multiselect v-model={this.model} />
            <b-form-checkbox v-model={this.status} />
        </div>
    );
}

is not being treated as a component.

Adding to babel.config.js

New to JS && Vue. Trying to add @vue/babel-preset-jsx to the default babel.config.js generated by webpacker gem for Ruby on Rails, but I get the following error:

Error: .presets[0][1] must be an object, false, or undefined

babel.config.js:

module.exports = function(api) {
  var validEnv = ['development', 'test', 'production']
  var currentEnv = api.env()
  var isDevelopmentEnv = api.env('development')
  var isProductionEnv = api.env('production')
  var isTestEnv = api.env('test')

  if (!validEnv.includes(currentEnv)) {
    throw new Error(
      'Please specify a valid `NODE_ENV` or ' +
        '`BABEL_ENV` environment variables. Valid values are "development", ' +
        '"test", and "production". Instead, received: ' +
        JSON.stringify(currentEnv) +
        '.'
    )
  }
  console.log('babel.config.js',require("@vue/babel-preset-jsx")())
  return {
    presets: [
      isTestEnv && [
        require("@vue/babel-preset-jsx").default,
        require('@babel/preset-env').default,
        {
          targets: {
            node: 'current'
          }
        }
      ],
      (isProductionEnv || isDevelopmentEnv) && [
        require("@vue/babel-preset-jsx").default,
        require('@babel/preset-env').default,
        {
          forceAllTransforms: true,
          useBuiltIns: 'entry',
          modules: false,
          exclude: ['transform-typeof-symbol']
        }
      ]
    ].filter(Boolean),
    plugins: [
      require('babel-plugin-macros'),
      require('@babel/plugin-syntax-dynamic-import').default,
      isTestEnv && require('babel-plugin-dynamic-import-node'),
      require('@babel/plugin-transform-destructuring').default,
      [
        require('@babel/plugin-proposal-class-properties').default,
        {
          loose: true
        }
      ],
      [
        require('@babel/plugin-proposal-object-rest-spread').default,
        {
          useBuiltIns: true
        }
      ],
      [
        require('@babel/plugin-transform-runtime').default,
        {
          helpers: false,
          regenerator: true
        }
      ],
      [
        require('@babel/plugin-transform-regenerator').default,
        {
          async: false
        }
      ]
    ].filter(Boolean)
  }
}

Is this possible?

update:prop doesn't seem to work

I've tried both suggestions from issue #40
Unfortunately, neither has worked.

<v-data-table onUpdated:pagination={this.updatePagination} />
<v-data-table on-updated:pagination={this.updatePagination} />

If i call this.$listeners in the v-data-table the only registered listener is update. It looks like the colon and the attribute are truncated.

Error trying to install

When I try to run the following:

npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props

I got the following error:

npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@vue%2fbabel-helper-vue-jsx-merge-props - User not found
npm ERR! 404 
npm ERR! 404  '@vue/babel-helper-vue-jsx-merge-props@latest' is not in the npm registry.
npm ERR! 404 Your package name is not valid, because 
npm ERR! 404  1. name can only contain URL-friendly characters
npm ERR! 404 
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/lucas/.npm/_logs/2019-03-25T17_00_17_050Z-debug.log

The URL exists.

My setup:

node --version
v11.12.0

vue --version 
3.0.5

npm --version  
6.9.1-next.0

When I was trying to solve this issue, I added this lines to my .npmrc:

@vue:registry=https://registry.npmjs.org
@babel:registry=https://registry.npmjs.org

But still the same error...

error with input type="range" and v-model

The following code:

	render(h) {
		return <input type="range" v-model={this.opacity}/>;
	},

fails with:

Module build failed (from ../node_modules/babel-loader/lib/index.js):
Cannot read property 'toLowerCase' of undefined

whereas replacing type="range" with type="number" works fine.

Transparent wrapper component pattern with JSX

I'm trying to recreate something like this https://zendev.com/2018/05/31/transparent-wrapper-components-in-vue.html with JSX.

// This does not work:
// `[Vue warn]: Failed to resolve directive: on`
export const MyComponent = {
  render() {
    return <div vOn={this.$listeners}>{this.$slots.default}</div>
  }
};

This results in [Vue warn]: Failed to resolve directive: on.

For now I use render functions instead, but I'd love to use JSX to create transparent wrapper components. Is this already possible and I do something wrong or is this just not supported?

// This works but I'd love to use JSX.
export const MyComponent = {
  render() {
    return h(
      'div',
      { on: this.$listeners },
      this.$slots.default,
    );
  }
};

Thanks!

Cannot process jsx comments

Version

3.4.0

Reproduction link

https://github.com/JackFGreen/vue-demo-jsx

Environment info


Environment Info:

  System:
    OS: macOS 10.14.2
    CPU: (8) x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
  Binaries:
    Node: 8.11.1 - ~/.nvm/versions/node/v8.11.1/bin/node
    Yarn: 1.3.2 - /usr/local/bin/yarn
    npm: 5.6.0 - ~/.nvm/versions/node/v8.11.1/bin/npm
  Browsers:
    Chrome: 71.0.3578.98
    Firefox: 64.0
    Safari: 12.0.2
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0-beta.2
    @vue/babel-plugin-transform-vue-jsx:  1.0.0-beta.2
    @vue/babel-preset-app:  3.4.0
    @vue/babel-preset-jsx:  1.0.0-beta.2
    @vue/babel-sugar-functional-vue:  1.0.0-beta.2
    @vue/babel-sugar-inject-h:  1.0.0-beta.2
    @vue/babel-sugar-v-model:  1.0.0-beta.2
    @vue/babel-sugar-v-on:  1.0.0-beta.2
    @vue/cli-overlay:  3.4.0
    @vue/cli-plugin-babel: ^3.4.0 => 3.4.0
    @vue/cli-plugin-eslint: ^3.4.0 => 3.4.0
    @vue/cli-service: ^3.4.0 => 3.4.0
    @vue/cli-shared-utils:  3.4.0
    @vue/component-compiler-utils:  2.5.2
    @vue/preload-webpack-plugin:  1.1.0
    @vue/web-component-wrapper:  1.2.0
    eslint-plugin-vue: ^5.0.0 => 5.1.0
    vue: ^2.5.22 => 2.5.22
    vue-eslint-parser:  4.0.3
    vue-hot-reload-api:  2.3.1
    vue-loader:  15.6.2
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.5.21 => 2.5.22
    vue-template-es2015-compiler:  1.8.2
  npmGlobalPackages:
    @vue/cli: Not Found

Steps to reproduce

yarn serve

What is expected?

处理 jsx 注释

What is actually happening?

  1. yarn serve 不能处理 jsx 注释
  2. cd src && vue serve App.vue 能处理

v-model binding incorrect order

The v-model directive adds an on-input event.

Consider the following:

render() {
    return (
        <div>
            <input v-model={this.model}  on-input={this.someMethod} />
        </div>
    );
}

This generates the following output:

"on": {
    "input": [this.someMethod, function ($$v) {
        _this1.model = $$v;
    }]
}

The problem here is the order of the generated event handler function to update the model. It's added after the manual on-input method.

This can cause issues when this.someMethod is expecting the value to have been set, but because state is synchronous, it hasn't actually been updated yet as the v-model event handler has not been executed yet.

I believe that the v-model event bindings should always be added to the start of the event handler array, to ensure that it is executed first.

I tested this on the vue-template compiler, which does handle inserting the v-model binding at the start of the event array:

https://template-explorer.vuejs.org/#%3Cinput%0A%20%20v-model%3D%22this.model%22%0A%20%20%40input%3D%22this.someMethod%22%0A%2F%3E

For the time being, the workaround is to manually set this.model in this.someMethod.

Should move attributes not reserved or prefixed to attrs property in JSXSpreadAttribute

Currently, I wrote a vue-cli-plugin vue-cli-plugin-tsx to help writing TSX, but jsx spread attributes not work as expectation (At present, I write a babel plugin to transform JSXSpreadAttributes before vue's jsx to transform). For example, the expression <Element { ...{ a, b, c, on, slot } } /> will transform to something like h(Element, { a, b, c, on, slot }), so should we move attributes not reserved or prefixed to attrs property in JSXSpreadAttribute?

Component with model props throws error

When component has a prop named model, throws an error.

Code like this:

public render() {
    return (
      <el-form model={this.model} nativeOnSubmit={this.submit}>
        <el-form-item prop='name' label='姓名'>
          <el-input vModel={this.model.name} />
        </el-form-item>
        <el-form-item>
          <el-button type='primary' nativeType='submit'>
            提交
          </el-button>
        </el-form-item>
      </el-form>
    )
  }
vue.runtime.esm.js?2b0e:619 [Vue warn]: Invalid handler for event "input": got undefined

found in

---> <ElForm> at packages/form/src/form.vue
       <Home>
         <App>
           <Root>

Another code removed prop model is correct:

public render() {
    return (
      <el-form nativeOnSubmit={this.submit}>
        <el-form-item prop='name' label='姓名'>
          <el-input vModel={this.model.name} />
        </el-form-item>
        <el-form-item>
          <el-button type='primary' nativeType='submit'>
            提交
          </el-button>
        </el-form-item>
      </el-form>
    )
  }

Here is a repo.

Report BUG of vModel

<input vModel={data.value} />

is working ↑↑

but:

<input vModel={data['value']} />

error!!!!

Props key support 'model'

code:

<div
        class="foo"
        style="bar"
        key="key"
        ref="ref"
        refInFor
        slot="slot"
        props-model={{"a":1}}
        model={{
          value: this.txt,
          callback: $$v => {
            this.txt = $$v
          }
        }}>
      </div>

transform :

h("div", {
  "class": "foo",
  "style": "bar",
  "key": "key",
  "ref": "ref",
  "refInFor": true,
  "slot": "slot",
  "props": {
    "model": {
      "a": 1
    }
  },
  "model": {
    value: this.txt,
    callback: $$v => {
      this.txt = $$v;
    }
  }
})

repository with feige05@f1e2042

请教如何解决这个问题。expected "</>/<=/>="

注释掉下面的 jsx 语法可以正常工作。
image

babel.config.js

module.exports = {
    presets: [
        '@vue/app',
        "@babel/preset-typescript",
        "@vue/babel-preset-jsx",
    ],
    plugins: [
        "@babel/plugin-transform-typescript"
    ] 
}

在另一个文件中也使用到了 jsx ,但是没有任何影响。

代码如下:

const createWaringDialog = function(options: {
    title?: string,
    type?: 'danger' | 'primary',
    message?: string,
    render?: (h: CreateElement) => JSX.Element,
    confirmBtnText?: string,
    cancelBtnText?: string
}) {
    options = Object.assign({
        type: 'primary',
        title: '提示',
        confirmBtnText: '确认',
        cancelBtnText: '取消'
    }, options)
    return new Vue<{
        dialogVisible: boolean
    }, {
        open: () => void
        close: () => void
        cancel: () => void
        confirm: () => void
    }>({
        setup: function(props, ctx) {
            const dialogVisible = ref(false)

            function open() {
                dialogVisible.value = true
            }

            function close() {
                ctx.emit('cancel')
                dialogVisible.value = false
            }

            function cancel() {
                ctx.emit('cancel')
                dialogVisible.value = false
            }

            function confirm() {
                ctx.emit('confirm')
                dialogVisible.value = false
            }

            return {
                cancel,
                confirm,
                open,
                close,
                dialogVisible
            }
        },

        render(h) {
            return <dialog-template
                    title={options.title}
                    visible={this.dialogVisible}
                    onClose={this.close}
                    append-to-body={true}
                    destroy-on-close={true}
                    width={"400px"}
                >
                {options.message && <div>{options.message}</div>}
                {options.render && options.render(h)}
                <div slot="footer" style="text-align: center">
                    <el-button size="medium" onClick={this.confirm} type={options.type}>
                        {options.confirmBtnText}
                    </el-button>
                    <el-button size="medium" onClick={this.cancel} plain>{options.cancelBtnText}</el-button>
                </div>
            </dialog-template>
        }
    })
}

Feature Request: support `.passive` modifier

Description

Seems that the modifier .passive is not yet supported?

<div vOn:scroll_passive={this.handleScroll}></div

Solution

The equivalent template

<div v-on:scroll.passive="handleScroll"></div>

will compiles to the following in template-explorer.vuejs.org:

function render() {
  with(this) {
    return _c('div', {
      on: {
        "&scroll": function ($event) {
          return handleScroll($event)
        }
      }
    })
  }
}

We can see the only difference is the prefix & (&scroll).

Error: Cannot find module '@vue/babel-preset-jsx' from <Project Path>

Issue
Hi there, it seems the '@vue/babel-preset-jsx' doesn't ship the built code on npm/yarn install. I started up a fresh default config project with the latest Vue CLI and followed the instructions on this projects read me and was met with the titles error.

Repro steps Assuming latest vue-cli 3 is installed as global package

  1. cd ~/
  2. vue create jsx && cd jsx
  3. Select default config.
  4. yarn add @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props --dev
  5. Add '@vue/babel-preset-jsx' to babel.config.js.
  6. yarn serve

You will see failure.

How I got it working locally

  1. yarn add @babel/core.
  2. yarn add babel-loader.
  3. cd node_modules/@vue-babel-preset-jsx,
  4. yarn && yarn build in @vue/babel-preset-jsx.
  5. cd ../../../ && yarn serve

Thanks so much for the project, I've been trying to figure out how to get React like functional components in Vue because it's something I really miss using in my day job. So thank you so much!

Remove whitespace between HTML tags

Currently the preset will preserve whitespaces between HTML tags by default, can you provide a option like preserveWhitespace in vue-loader, or just remove whitespace between HTML tags like JSX in React?

input:

<div>
  <span>{this.text}</span>
  <span>{this.text}</span>
</div>

output:

h('div', [
  h('span', [this.text]),
  '\n        ',
  h('span', [this.text])
]);

expected:

h('div', [
  h('span', [this.text]),
  h('span', [this.text])
]);

Consider adding vue-jsx-hot-loader

Hi there!

A log time ago I developed a Webpack loader to enable HMR for Vue components that use JSX (render functions):

// component.jsx
export default {
    render(h) {
        return (
            <div>
                <p>Hello</p>
            </div>
        );
    },
};

The package is located here: https://github.com/skyrpex/vue-jsx-hot-loader It's been working great so far, so I think it would be nice to officially add it here.

Is staticClass no longer supported ?

Now, staticClass does not work.

Reproduction

Input code:

<div staticClass="foo" />;

Transpiled by babel-plugin-transform-vue-jsx (works):

h("div", { staticClass: "foo" });

Transpiled by @vue/babel-plugin-transform-vue-jsx (does not work):

h("div", {
  "attrs": {
    "staticClass": "foo"
  }
});

Doesn't work in Vue files templates

I'm using rollup with babel plugin.
My setup is simple but the preset doesn't seem to work.

Already tried to move babel plugin above vue plugin but still doesn't work.

// rollup.config.js

import vue from 'rollup-plugin-vue2';
import css from 'rollup-plugin-css-only';
import babel from 'rollup-plugin-babel';
import replace from 'rollup-plugin-replace';

export default {
  input: 'src/index.js',
  output: {
    format: 'iife',
    file: 'dist/index.js'
  },
  plugins: [
    vue(),
    css({
      output: 'dist/bundle.css'
    }),
    babel({
      exclude: 'node_modules/**'
    }),
    replace({
      'process.env.NODE_ENV': JSON.stringify('production')
    })
  ]
}
// component.vue

<script>
  export default {
      render() {
        return <h1>Hello World !</h1>
      }
  }
</script>

<style>
   * {
     box-sizing: border-box;
   }
</style>
// Error: Unexpected token.
return <h1>Hello World !</h1>
           ^

Directives don't work when v-model is used

Consider the following component:

const Cwd6 = new Vue({
    el: '#cwd6',

    data: function () {
        return {
            textExample: ''
        };
    },

    render(h) {
        console.log(this.textExample);
        return (
            <div>
                <b-col cols="12">
                    <b-form-group
                        id="form-group-text"
                        description="Enter some text"
                        label="Text"
                        label-for="text-field">
                        <input
                            type="text"
                            name="textField"
                            v-model={this.textExample}
                            v-validate="required"
                        />
                        <div>exampletext: {this.textExample}</div>
                        <CwdValidationError
                            errors={this.errors}
                            fieldName="textField" />
                    </b-form-group>
                </b-col>
            </div>
        );
    }
});

In the monorepo plugin, it is transpiled to:

var Cwd6 = new Vue({
el: '#cwd6',
data: function data() {
    return {
        textExample: ''
    };
},
render: function render(h) {
    var _this = this;

    console.log(this.textExample);
    return h("div", [h(
        "b-col", {
            "attrs": {
                "cols": "12"
            }
        },
        [h(
            "b-form-group", {
                "attrs": {
                    "id": "form-group-text",
                    "description": "Enter some text",
                    "label": "Text",
                    "label-for": "text-field"
                }
            },
            [h("input", (0, _babelHelperVueJsxMergeProps.default)([{
                "attrs": {
                    "type": "text",
                    "name": "textField"
                },
                "directives": [{
                    name: "validate",
                    value: "required"
                }],
                "domProps": {
                    "value": _this.textExample
                },
                "on": {
                    "input": function input($event) {
                        if ($event.target.composing) return;
                        _this.textExample = $event.target.value;
                    }
                }
            }, {
                directives: [{
                    name: "model",
                    value: _this.textExample,
                    modifiers: {}
                }]
            }])), h("div", ["exampletext: ", this.textExample]), h(CwdValidationError, {
                "attrs": {
                    "errors": this.errors,
                    "fieldName": "textField"
                }
            })]
        )]
    )]);
}
});

Unfortunately, the v-validate directive is not working. This appears to be caused by the way that non v-model directives are transpiled.

In https://github.com/vuejs/babel-helper-vue-jsx-merge-props, this works, and is transpiled as:

render: function render(h) {
    var _this = this;

    console.log(this.textExample);
    return h('div', [h(
        'b-col', {
            attrs: {
                cols: '12'
            }
        },
        [h(
            'b-form-group', {
                attrs: {
                    id: 'form-group-text',
                    description: 'Enter some text',
                    label: 'Text',
                    'label-for': 'text-field'
                }
            },
            [h('input', (0, _babelHelperVueJsxMergeProps2.default)([{
                attrs: {
                    type: 'text',
                    name: 'textField'
                },
                domProps: {
                    'value': _this.textExample
                },
                on: {
                    'input': function input($event) {
                        if ($event.target.composing) return;
                        _this.textExample = $event.target.value;
                    }
                }
            }, {
                directives: [{
                    name: 'model',
                    value: _this.textExample
                }]
            }, {
                directives: [{
                    name: 'validate',
                    value: 'required'
                }]
            }])), h('div', ['exampletext: ', this.textExample]), h(CwdValidationError, {
                attrs: {
                    errors: this.errors,
                    fieldName: 'textField'
                }
            })]
        )]
    )]);
}

I've tested this for other directives and the result is always the same. It seems that directives are being added at the wrong place. This actually only happens with v-validate.

The `scopedSlots` can't work properly

hey..
我在用vue和elementui,尝试包装一个PopConfirm组件,类似antd的PopConfirm, 这是我的demo
https://github.com/jdz321/vue-jsx-demo

components/A.vue 使用render函数和jsx
components/B.vue 使用普通的template

B可以正常工作,但是A点击没有反应。 这是我的render函数

{
  render() {
    const scopedSlots = {
      reference: () => this.$slots.default,
    }
    return (
      <ElPopover placement="top" width="160" vModel={this.visible} scopedSlots={scopedSlots}>
        {this.$slots.content ? this.$slots.content : (
          <p>{this.content}</p>
        )}
        <div style="text-align: right; margin: 0">
          <ElButton size="mini" type="text" vOn:click={this.onCancelClick}>{this.cancelText}</ElButton>
          <ElButton type="primary" size="mini" vOn:click={this.onOkClick}>{this.okText}</ElButton>
        </div>
      </ElPopover>
    )
  }
}

我参考了 这个PR里的写法, 这不一定是一个issue,很可能是我的写法不对。

感谢。

Is it safe to use the `hook` property of the vNode interface?

After poking around the source code a bit, I noticed the hook property that can be set on the data object of a vnode, and It actually helped me solve one of the problems I was dealing with in a pretty elegant manner, but, since it's not documented anywhere, I wanted to make sure that that API is stable and ok to use in userland. Is that the case? My assumption is that it mirrors the hooks present on a directive.

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.