jsx-vue2 icon indicating copy to clipboard operation
jsx-vue2 copied to clipboard

Error when using vModel in Composition API component

Open TheoBP opened this issue 5 years ago • 17 comments

I'm getting the following error when using vModel in a JSX/TSX file with the latest version:

Cannot read property 'body' of undefined (babel-sugar-composition-api-render-instance\dist\plugin.js:1:1179)

Packages:

{
  "name": "vmodel",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
    "@vue/babel-preset-jsx": "^1.2.4",
    "@vue/composition-api": "^1.0.0-beta.18",
    "core-js": "^3.6.5",
    "register-service-worker": "^1.7.1",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^2.33.0",
    "@typescript-eslint/parser": "^2.33.0",
    "@vue/cli-plugin-babel": "^4.5.8",
    "@vue/cli-plugin-eslint": "^4.5.8",
    "@vue/cli-plugin-pwa": "^4.5.8",
    "@vue/cli-plugin-router": "^4.5.8",
    "@vue/cli-plugin-typescript": "^4.5.8",
    "@vue/cli-plugin-vuex": "^4.5.8",
    "@vue/cli-service": "^4.5.8",
    "@vue/eslint-config-typescript": "^5.0.2",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "typescript": "^4.0.3",
    "vue-template-compiler": "^2.6.11"
  }
}

Component (TSX):

import { defineComponent, reactive } from '@vue/composition-api'

export default defineComponent({
  setup() {

    const state = reactive<{ search: string | null }>({
      search: null
    })

    return () =>
      <div>
        <h1>This is a page.</h1>

        <input type="text" placeholder="Search:" vModel={state.search} />
      </div>
  }
})

Babel config:

module.exports = {
  presets: [
    [
      "@vue/cli-plugin-babel/preset", {
        jsx: {
          compositionAPI: true
        }
      }
    ]
  ]
}

TheoBP avatar Oct 30 '20 10:10 TheoBP

has same error : https://github.com/vuejs/composition-api/issues/589

CharlieLau avatar Nov 12 '20 08:11 CharlieLau

Same here, cannot make vModel working in TSX environment.

"@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
"@vue/babel-preset-jsx": "^1.2.4",
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^2.6.12",

(BTW Vue 3 works fine)

TypeError: tiny-form.tsx: Cannot read property 'body' of undefined at MemberExpression (node_modules\@vue\babel-sugar-composition-api-render-instance\dist\plugin.js:1:1241)

babel.config.js:

module.exports = {
  presets: [
    [
      '@vue/babel-preset-jsx', {
        compositionAPI: true
      }
    ],
    [
      '@babel/preset-env', {
        useBuiltIns: 'entry',
        modules: 'auto',
        loose: false,
        corejs: {
          version: 3,
          proposals: true
        }
      }
    ]
  ]
}

Update:

I think it's something to do with the @vue/composition-api, check this:

This thing just doesn't work:

import { defineComponent, ref } from '@vue/composition-api'

const TinyForm = defineComponent({
  setup () {
    const name = ref<string | null>(null)
    const age = ref<number | null>(null)

    return () => (
      <div>
        <div>
          <label>
            <span>Username:</span>
            <input vModel={name.value} placeholder='Your name.' />
          </label>
        </div>

        <div>
          <label>
            <span>Age:</span>
            <input vModel_number={age.value} placeholder='Your age.' type='number' />
          </label>
        </div>

        <div>
          <button>Submit</button>
        </div>
      </div>
    )
  }
})

export {
  TinyForm
}

This thing works:

import { defineComponent } from '@vue/composition-api'

const TinyForm = defineComponent({
  data: () => ({
    name: '',
    age: 0
  }),

  render (h) {
    return (
      <div>
        <div>
          <label>
            <span>Username:</span>
            <input vModel={this.name} placeholder='Your name.' />
          </label>
        </div>

        <div>
          <label>
            <span>Age:</span>
            <input vModel_number={this.age} placeholder='Your age.' type='number' />
          </label>
        </div>

        <div>
          <button>Submit</button>
        </div>
      </div>
    )
  }
})

LancerComet avatar Feb 03 '21 08:02 LancerComet

Is there any progress?

galenjiang avatar Oct 19 '21 01:10 galenjiang

Getting the same problem? Any ideas?

hisuwh avatar Mar 14 '22 17:03 hisuwh

Same Error...

leecervan904 avatar Apr 10 '22 08:04 leecervan904

well since the official Vue 2 JSX support seems to be deprecated, I have made a Vue 2 JSX runtime to support Vue 2 JSX, and it works with TSC/SWC directly, no Babel is needed, and using v-model in setup function no longer throws exceptions.

https://github.com/LancerComet/vue2-jsx-runtime

@galenjiang @hisuwh @leecervan904 give it a shot

LancerComet avatar May 23 '22 07:05 LancerComet

any progress?

dyf19118 avatar Jul 07 '22 08:07 dyf19118

In my project, @vue/babel-preset-jsx is using, and vModel should be config as true (see https://www.npmjs.com/package/@vue/babel-preset-jsx for details).

 [
          '@vue/babel-preset-jsx',
          {
            vModel: true,
            functional: true,
            injectH: true,
            vOn: true,
            compositionAPI: true,
          },
        ],

v-model and vModel are ok in .tsx file.

<GroupRadio v-model={this.currentBookId}  />
<el-input type="textarea" vModel={this.inputText}  />

FuDesign2008 avatar Jul 07 '22 10:07 FuDesign2008

In my project, @vue/babel-preset-jsx is using, and vModel should be config as true (see https://www.npmjs.com/package/@vue/babel-preset-jsx for details).

 [
          '@vue/babel-preset-jsx',
          {
            vModel: true,
            functional: true,
            injectH: true,
            vOn: true,
            compositionAPI: true,
          },
        ],

v-model and vModel are ok in .tsx file.

<GroupRadio v-model={this.currentBookId}  />
<el-input type="textarea" vModel={this.inputText}  />

This exception only appears when returning JSX which contains v-model from setup() directly Using render() is fine

LancerComet avatar Jul 07 '22 10:07 LancerComet

any progress?

seanrosenberg avatar Aug 04 '22 04:08 seanrosenberg

@sodatea any progress?

agileago avatar Aug 13 '22 03:08 agileago

expect update

chengfengfengwang avatar Sep 28 '22 08:09 chengfengfengwang

any progress?

AugustToko avatar Dec 13 '22 07:12 AugustToko

any progress?

guohuihot avatar Jun 09 '23 08:06 guohuihot

any progress?

guohuihot avatar Jun 09 '23 09:06 guohuihot

vue2 要结束更新了,这个bug能修复一下吗?100%复现的bug...

djkloop avatar Dec 25 '23 09:12 djkloop

肯定不好修,不然早修了,直接用value+onInput

guohuihot avatar Jan 09 '24 08:01 guohuihot