Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@model decorator from vue-property-decorator generates vue-warn: Avoid mutating

I use typescript with this lib. And I have following code in file HomePage.vue :

<template>
    <div>Write something x: <input v-model="someName" type="text"></div>
</template>

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

@Component
export default class HomePage extends Vue {
    @Model() someName: string;
}
</script>

After compilation, run in browser and type something on input box i get in chrome console following vue warrning:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "someName"

Any idea how to fix this problem?

like image 421
Kamil Kiełczewski Avatar asked Dec 18 '22 02:12

Kamil Kiełczewski


2 Answers

TL:DR

I'm new in Vue (coming from React) but from what I understand the answer above is not wrong but it doesn't answer the question of how to use @Model decorator. Provide and Inject is an overkill for passing props from parent to child. The documentation is not clear, so I scratched my head a lot on this one. But remember that the package is referring to props. Hence @Prop, @PropSync and @Model should be at the child component. Here is what I did and it didn't throw out that horrible console error. Parent component:

<template>
  <div>
     <input type="text" v-model="modelText" />
    <Child 
      :modelText="modelText"
    />
  </div>
</template>

<script lang="ts">
import Component from 'vue-class-component';
import Vue from 'vue';
import Child from './Child.vue';

@Component({
  components: {
    Child,
  }
})
export default class Parent extends Vue {
  private modelText: string = 'model-text';
}
</script>

And for the child component:

<template>
    <div>
      @Model: {{modelText}}
    </div>
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import { Prop, PropSync, Model } from 'vue-property-decorator';

@Component({

})
export default class Child extends Vue {
  @Model('input', { type: String }) modelText!: string;
}
</script>
like image 187
Kleo Avatar answered Dec 20 '22 14:12

Kleo


Since v. 9.1.2 view-property-decorator now supports the @VModel decorator.

Where

import { Vue, Component, VModel } from 'vue-property-decorator'

@Component
export default class CustomComponent extends Vue {
  @VModel() name!: string
}

will make it possible to use two-way-databinding with name inside the component and v-model="..." from the outside. Without the annoying warnings!

https://github.com/kaorun343/vue-property-decorator#-vmodelpropsargs-propoptions-decorator

like image 34
Lovis Avatar answered Dec 20 '22 15:12

Lovis