vuejs / jsx-vue2

monorepo for Babel / Vue JSX related packages
https://jsx-vue2-playground.netlify.app/
1.47k stars 96 forks source link

Error when using vModel in Composition API component #169

Open TheoBP opened 3 years ago

TheoBP commented 3 years ago

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
        }
      }
    ]
  ]
}
CharlieLau commented 3 years ago

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

LancerComet commented 3 years ago

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>
    )
  }
})
galenjiang commented 2 years ago

Is there any progress?

hisuwh commented 2 years ago

Getting the same problem? Any ideas?

leecervan904 commented 2 years ago

Same Error...

LancerComet commented 2 years ago

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

dyf19118 commented 2 years ago

any progress?

FuDesign2008 commented 2 years ago

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}  />
LancerComet commented 2 years ago

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

seanrosenberg commented 1 year ago

any progress?

agileago commented 1 year ago

@sodatea any progress?

chengfengfengwang commented 1 year ago

expect update

AugustToko commented 1 year ago

any progress?

guohuihot commented 1 year ago

any progress?

guohuihot commented 1 year ago

any progress?

djkloop commented 7 months ago

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

guohuihot commented 6 months ago

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