Search code examples
vue.jsvuejs2jsxvue-componentvue-loader

vue babel-loader SyntaxError: Unexpected token on ":click" syntax


I use render function like this:

.script.js:

methods: {
    handleClick(data){
        console.log(data)
    },
    render(h, { node, data, store }) {
            return (
                <span>
                    <span>
                        <span>{node.label}</span>
                    </span>
                    <span style="float: right; margin-right: 20px">
                        <a href="javascript:;" 
                            :attr="data.id" @click="handleClick">Edit{data.id}
                        </a>
                    </span>
                </span>
            );
        }
}

But babel encoutners error saying the :click has Unexpected token.

.vue:

<template src="./template.html"></template>
<script src="./script.js"></script>

package.json:

"vue": "^2.2.6"
"vue-router": "^2.4.0"
"element-ui": "^1.2.8",
"babel-core": "^6.24.0",
"babel-loader": "^6.4.1",
"babel-plugin-transform-vue-jsx": "^3.4.2",
"vue-loader": "^11.3.4",
"webpack": "^2.3.1",

webpack:

{
    test: /\.vue$/,
    loader: `vue-loader`,
    options: {
        loaders: {
            js: 'babel-loader'
        }
    }
},
{
    test: /\.js$/,
    loader: `babel-loader`,
    exclude: /(node_modules)/
}

.babelrc:

{
    "presets": [
        ["es2015", { "modules": false }], "stage-1", "stage-2", "stage-3"
    ],
    "plugins": [
        ["transform-vue-jsx"],
        ["transform-object-assign"],
        ["component", [{
            "libraryName": "element-ui",
            "styleLibraryName": "theme-default"
        }]]
    ]
}

When i run gulp dist, babel throws an error like follows:

Namespaced tags/attributes are not supported. JSX is not XML.\nFor attributes like xlink:href, use xlinkHref instead.


Solution

  • As @Bert Evans suggested, after re-reading the reademe docs of https://github.com/vuejs/babel-plugin-transform-vue-jsx, I figured out that i just wrote the code without understanding the syntax of vue-specific jsx syntax.

    As the docs says:

    Note that almost all built-in Vue directives are not supported when using JSX, the sole exception being v-show, which can be used with the v-show={value} syntax. In most cases there are obvious programmatic equivalents, for example v-if is just a ternary expression, and v-for is just an array.map() expression, etc.

    The equivalent of the above in Vue 2.0 JSX is:

    render (h) {
          return (
            <div
              // normal attributes or component props.
              id="foo"
              // DOM properties are prefixed with `domProps`
              domPropsInnerHTML="bar"
              // event listeners are prefixed with `on` or `nativeOn`
              onClick={this.clickHandler}
              nativeOnClick={this.nativeClickHandler}
              // other special top-level properties
              class={{ foo: true, bar: false }}
              style={{ color: 'red', fontSize: '14px' }}
              key="key"
              ref="ref"
              // assign the `ref` is used on elements/components with v-for
              refInFor
              slot="slot">
            </div>
          )
        }
    

    So, i changed my code to

    render(h, {node,data,store}) {
        const link = {
            href: `/#/schema-type/${data.id}`
        };
        return (
            <span>
                <span>
                    <span>{node.label}</span>
                </span>
                <span>
                    <a href={link.href} target="_blank">edit</a>
                </span>
            </span>
        );
    }
    

    And it works!