使用 v-model 更新 axios 响应的子组件值
Update child component value on axios response using v-model
Vue 3
我正在尝试从 Axios 响应中更新数据变量的值。如果我在父组件中打印值,它会被打印并更新响应,但变量的值不会在子组件中更新。
我能弄清楚的是我的子组件没有收到更新的值。但是我不知道为什么会这样。
输入字段是全局组件。
Vue 3
父组件
<template>
<input-field title="First Name" :validation="true" v-model="firstName.value" :validationMessage="firstName.validationMessage"></input-field>
</template>
<script>
export default {
data() {
return {
id: 0,
firstName: {
value: '',
validationMessage: '',
},
}
},
created() {
this.id = this.$route.params.id;
this.$http.get('/users/' + this.id).then(response => {
this.firstName.value = response.data.data.firstName;
}).catch(error => {
console.log(error);
});
},
}
</script>
子组件
<template>
<div class="form-group">
<label :for="identifier">{{ title }}
<span class="text-danger" v-if="validation">*</span>
</label>
<input :id="identifier" :type="type" class="form-control" :class="validationMessageClass" :placeholder="title" v-model="inputValue">
<div class="invalid-feedback" v-if="validationMessage">{{ validationMessage }}</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true,
},
validation: {
type: Boolean,
required: false,
default: false,
},
type: {
type: String,
required: false,
default: 'text',
},
validationMessage: {
type: String,
required: false,
default: '',
},
modelValue: {
required: false,
default: '',
}
},
emits: [
'update:modelValue'
],
data() {
return {
inputValue: this.modelValue,
}
},
computed: {
identifier() {
return this.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
},
validationMessageClass() {
if (this.validationMessage) {
return 'is-invalid';
}
return false;
}
},
watch: {
inputValue() {
this.$emit('update:modelValue', this.inputValue);
},
},
}
</script>
您的 child 永远不会从您的 parent 收到更新的原因是,即使您更改 firstName.value
,您的 child-component 也不会 re-mount并意识到这种变化。
它绑定到它内部创建的 属性 (inputValue
) 并一直监视它,而不是从 parent 传递的 modelValue
。
这是一个使用您的代码的 example,它完全按照预期的方式工作,并按照您的预期工作。
它接收一次值 (firstName.value
),创建另一个 属性 (inputValue
) 并在发生变化时发出该值。
不管parent改变firstName.value
属性多少次,child都不在乎,输入[=31=的不是属性 ]的child看。
你可以这样做
<template>
<div class="form-group">
<label :for="identifier"
>{{ title }}
<span class="text-danger" v-if="validation">*</span>
</label>
<input
:id="identifier"
:type="type"
class="form-control"
:class="validationMessageClass"
:placeholder="title"
v-model="localValue" // here we bind localValue as v-model to the input
/>
<div class="invalid-feedback" v-if="validationMessage">
{{ validationMessage }}
</div>
</div>
</template>
<script>
export default {
... // your code
computed: {
localValue: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
},
},
},
};
</script>
我们删除了观察者,而是使用一个计算的 属性,它将 return 中的模型值 getter(所以每当 parent 传递一个新值时,我们实际上使用 that 而不是 localValue) 和 setter 将更新事件发送到 parent.
这是另一个 codesandbox 示例来说明上述解决方案。
Vue 3
我正在尝试从 Axios 响应中更新数据变量的值。如果我在父组件中打印值,它会被打印并更新响应,但变量的值不会在子组件中更新。
我能弄清楚的是我的子组件没有收到更新的值。但是我不知道为什么会这样。
输入字段是全局组件。
Vue 3
父组件
<template>
<input-field title="First Name" :validation="true" v-model="firstName.value" :validationMessage="firstName.validationMessage"></input-field>
</template>
<script>
export default {
data() {
return {
id: 0,
firstName: {
value: '',
validationMessage: '',
},
}
},
created() {
this.id = this.$route.params.id;
this.$http.get('/users/' + this.id).then(response => {
this.firstName.value = response.data.data.firstName;
}).catch(error => {
console.log(error);
});
},
}
</script>
子组件
<template>
<div class="form-group">
<label :for="identifier">{{ title }}
<span class="text-danger" v-if="validation">*</span>
</label>
<input :id="identifier" :type="type" class="form-control" :class="validationMessageClass" :placeholder="title" v-model="inputValue">
<div class="invalid-feedback" v-if="validationMessage">{{ validationMessage }}</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true,
},
validation: {
type: Boolean,
required: false,
default: false,
},
type: {
type: String,
required: false,
default: 'text',
},
validationMessage: {
type: String,
required: false,
default: '',
},
modelValue: {
required: false,
default: '',
}
},
emits: [
'update:modelValue'
],
data() {
return {
inputValue: this.modelValue,
}
},
computed: {
identifier() {
return this.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
},
validationMessageClass() {
if (this.validationMessage) {
return 'is-invalid';
}
return false;
}
},
watch: {
inputValue() {
this.$emit('update:modelValue', this.inputValue);
},
},
}
</script>
您的 child 永远不会从您的 parent 收到更新的原因是,即使您更改 firstName.value
,您的 child-component 也不会 re-mount并意识到这种变化。
它绑定到它内部创建的 属性 (inputValue
) 并一直监视它,而不是从 parent 传递的 modelValue
。
这是一个使用您的代码的 example,它完全按照预期的方式工作,并按照您的预期工作。
它接收一次值 (firstName.value
),创建另一个 属性 (inputValue
) 并在发生变化时发出该值。
不管parent改变firstName.value
属性多少次,child都不在乎,输入[=31=的不是属性 ]的child看。
你可以这样做
<template>
<div class="form-group">
<label :for="identifier"
>{{ title }}
<span class="text-danger" v-if="validation">*</span>
</label>
<input
:id="identifier"
:type="type"
class="form-control"
:class="validationMessageClass"
:placeholder="title"
v-model="localValue" // here we bind localValue as v-model to the input
/>
<div class="invalid-feedback" v-if="validationMessage">
{{ validationMessage }}
</div>
</div>
</template>
<script>
export default {
... // your code
computed: {
localValue: {
get() {
return this.modelValue;
},
set(value) {
this.$emit("update:modelValue", value);
},
},
},
};
</script>
我们删除了观察者,而是使用一个计算的 属性,它将 return 中的模型值 getter(所以每当 parent 传递一个新值时,我们实际上使用 that 而不是 localValue) 和 setter 将更新事件发送到 parent.
这是另一个 codesandbox 示例来说明上述解决方案。