'Why is there an "unexpected mutation of prop" when this is not a prop?
This code below triggers an error for the <q-input> component
ESLint: Unexpected mutation of "serviceName" prop. (vue/no-mutating-props)
The thing I do not understand is why serviceName is seen as a prop when I explicitly crated the reference from the prop.
Does this mean that changes in serviceName will bubble to props? If so does this mean that I have to copy the contents of props into a new reactive variable, breaking the relationship with the prop?
<template>
<div class="q-pa-md">
<q-form
@submit="true"
>
<div class="row q-gutter-md">
<q-input v-model="serviceName" label="service" class="" filled></q-input>
</div>
<div class="row q-gutter-md">
<q-input v-model="serviceConf.image" label="image"></q-input>
<q-input v-model="serviceConf.container_name" label="container_name"></q-input>
</div>
</q-form>
</div>
</template>
<script lang="ts">
export default {
name: 'EditService'
}
</script>
<script lang="ts" setup>
import { toRef, PropType } from 'vue'
import { ServiceFull } from 'components/defs'
const props = defineProps({
serviceName: {
type: String
},
serviceConf: {
type: Object as PropType<ServiceFull>
}
})
const serviceName = toRef(props, 'serviceName')
const serviceConf = toRef(props, 'serviceConf') as unknown as ServiceFull
</script>
For reference, ServiceFull is defined as
// name of the service
export type ServiceName = string
// description of the service below the name
export interface ServiceConfig {
container_name: string
image: string
environment: string[]
restart: string
volumes: string[]
ports: string[]
depends_on: string[]
cap_add: string[]
}
// complete service, name + config → used to transfer between components
export interface ServiceFull {
name: ServiceName
conf: ServiceConfig
}
Solution 1:[1]
The docs explain that toRef keeps a reactive connection to the source property, so modifying the resulting ref would update the original property. In addition to the linter warning, you'd see a browser console warning when trying to use this ref in a v-model:
Set operation on key "serviceName" failed: target is readonly.
To be able to modify serviceName independently from the prop, you could use a ref of the prop value (i.e., a copy):
import { ref } from 'vue'
const serviceName = ref(props.serviceName)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | tony19 |
