vuejs / vue-class-component

ES / TypeScript decorator for class-style Vue components.
MIT License
5.81k stars 429 forks source link

Props defined using Vue.with(Props) are not populated by element attributes #501

Closed bobmeyers5 closed 3 years ago

bobmeyers5 commented 3 years ago

When I use the @Options({ props: ... }) syntax currently generated by vue-cli, the component props are correctly populated by element attributes. When I use the extends Vue.with(Props) syntax, the component props are not populated.

Repro: I used vue-cli@4.5.9 with Vue3, babel, typescript, and eslint support to generate a new project.

Dependencies added include:

"vue": "^3.0.0",
"vue-class-component": "^8.0.0-0"

HelloWorld.vue (minus some fluff) looks like this:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';

@Options({
  props: {
    msg: String
  }
})
export default class HelloWorld extends Vue {
  msg!: string
}
</script>

App.vue uses the component like this:

  <HelloWorld msg="My favorite prop value"/>

This works just fine. The attribute value is correctly displayed in the <h1> element inside the component. I'm not sure why the generated class defines msg as both a prop and data, though.

If I change the component to use the new prop syntax (and comment out the data property), like this:

class Props {
  msg!: string
}

export default class HelloWorld extends Vue.with(Props) {
  //msg!: string
}

The app compiles and loads just fine, but the prop is no longer populated by the element attribute.

This test case suggests this should work, so I'm not sure what's broken: https://github.com/vuejs/vue-class-component/blob/4ccce3f42adf5c0b445e3e9935029cc7b2fc70fd/test/specs/test.spec.ts#L390

Changing the dependency version to 8.0.0-rc.1 did not affect the behavior.

ygj6 commented 3 years ago

Hi Bob, you need to add "useDefineForClassFields": true for TypeScript compiler option, or define prop like this:

import { Vue, prop } from 'vue-class-component'
class Props {
  msg = prop({
    type: String,
    required: true
  })
}

@ktsn Shall we add "useDefineForClassFields":true to vue-cli's template project ?

ktsn commented 3 years ago

As @ygj6 said.

I've made a PR in vue-cli repo. https://github.com/vuejs/vue-cli/pull/6235