vue-property-decorator icon indicating copy to clipboard operation
vue-property-decorator copied to clipboard

@Data decorator

Open BehindTheMath opened this issue 7 years ago • 12 comments

#36 requests a new @Data decorator to set properties as reactive. It is resolved there as unneeded, since you can just initialize the value as null.

However, there is another situation for which a @Data decorator would be useful: if you want to initialize the value of the data member to the value of a prop. ( A reason to do this would be so you can have a variable that initially mirrors the prop, but you can change the value later).

For example:

<template>
    <input v-model="localData"></input>
</template>

<script="ts">
    import {Vue, Prop} from "vue-property-decorator";

    @Component({})
    export default MyComponent extends Vue {
        @Prop(String) data!: string;

        localData: string = data;
    }
</script>

Currently, since local class member declarations and initializations are done in the class constructor, at that point the value of the props are still undefined, so that's what this component would display.

The current workaround for this is to use a data method in the Component options, since when Vue calls data(), the props are already initialized:

@Component({
    data() {
        return {
            localData: this.data,
        }
    },
})

If there was a @Data decorator that would convert something like this:

@Data() localData: string = data;

to a data method as above, that would make the code cleaner.

BehindTheMath avatar Aug 16 '18 13:08 BehindTheMath

Isn't it enough to initialize localData, in your example, at created lifecycle hook?

@Component
class YourComponent extends Vue {
    @Prop(String) data!: string

    localData = ''

    created() {
        this.localData = this.data
    }
}

kaorun343 avatar Aug 16 '18 16:08 kaorun343

@kaorun343 In that example, would localData be reactive?

BehindTheMath avatar Aug 20 '18 03:08 BehindTheMath

@BehindTheMath

I'm sorry for the late reply.

localData doesn't follow the change of data, in my example, because data is a primitive value.

kaorun343 avatar Sep 14 '18 08:09 kaorun343

localData doesn't follow the change of data, in my example, because data is a primitive value.

I understand. My question was if localData would be reactive, and would the template update if localData was assigned a new value. I see now that it is, so never mind that.

Regardless, I still think that

@Data() localData = this.data;

is simpler and nicer than

    localData = ''

    created() {
        this.localData = this.data
    }

but that's just my opinion.

BehindTheMath avatar Sep 17 '18 15:09 BehindTheMath

for reactive:

@Component
class Some extends Vue {
@Prop value;
@Watch('value')
onChangeValue(newValue) { this.data = newValue;}

data;
created(){ this.data = this.value}
@Emit('data')
onChangeData(d) {
   ...
   return this.data}
}
<template><Some @data="onChangeData" v-model="data"/></template>
<script>
@Component 
class App extends Vue {
  data='asdfs';
  onChangeData(d){ this.data = d }
}

cybermerlin avatar Sep 21 '18 15:09 cybermerlin

Bump, this solution it's not adequate in my opinion.

This library is meant to be a little bit of sugar syntax on top of the very simple Vue interface, it should not overcomplicate basic things, and data is the simplest Vue Component part.

Please reconsider

colthreepv avatar Oct 30 '18 11:10 colthreepv

@kaorun343 Why did you close it without a comment?

This seems like a common use case, that is overly complex with this library...

douglasg14b avatar Mar 03 '19 01:03 douglasg14b

@kaorun343 Out of curiosity is there a way to do this currently?

douglasg14b avatar Mar 08 '19 02:03 douglasg14b

@Component<MyComponent>({
  data() {
    return { dataValue: this.propValue }
  }
})
class MyComponent extends Vue {
  @Prop() propValue!: any

  dataValue!: any
}

kaorun343 avatar Mar 08 '19 17:03 kaorun343

@kaorun343 Is it necessary to have the propValue property ?

If I just need a data property myData to bind an input to what is the minimum working example of that?

douglasg14b avatar Mar 16 '19 03:03 douglasg14b

@douglasg14b This issue is about initializing a data member with the value of a prop. If you don't need that, you can use the syntax inherited from vue-class-component:

@Component({})
class MyComponent extends Vue {
  myData = 1;
}

BehindTheMath avatar Mar 17 '19 18:03 BehindTheMath

I still have this issue. Where I would expect myData to be defined.

@Component({})
class MyComponent extends Vue {
  @Prop({default: 'nice'}) aProp;
  myData = this.aProp

  created() {
    console.log(this.myData) // Shows undefined
   console.log(this.aProp)  // Shows 'nice'
  }
}

jellehak avatar Mar 16 '23 14:03 jellehak