Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when using vModel in Composition API component #169

Open
TheoBP opened this issue Oct 30, 2020 · 17 comments
Open

Error when using vModel in Composition API component #169

TheoBP opened this issue Oct 30, 2020 · 17 comments

Comments

@TheoBP
Copy link

TheoBP commented Oct 30, 2020

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
Copy link

CharlieLau commented Nov 12, 2020

has same error : vuejs/composition-api#589

@LancerComet
Copy link

LancerComet commented Feb 3, 2021

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

This comment was marked as off-topic.

@hisuwh

This comment was marked as duplicate.

@leecervan904

This comment was marked as duplicate.

@LancerComet
Copy link

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

This comment was marked as duplicate.

@FuDesign2008
Copy link

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
Copy link

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

This comment was marked as duplicate.

@agileago

This comment was marked as duplicate.

@chengfengfengwang

This comment was marked as duplicate.

@AugustToko

This comment was marked as duplicate.

2 similar comments
@guohuihot
Copy link

any progress?

@guohuihot
Copy link

any progress?

@djkloop
Copy link

djkloop commented Dec 25, 2023

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

@guohuihot
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests