Vue3 v-model 对象不是反应性的
Vue3 v-model objects are not reactive
我正在尝试创建一个包含嵌套组件的表单,其中传递给子组件的数据可以是对象的嵌套值。
带字符串的输入字段按预期工作,我只是对对象值有疑问。
预先感谢您的建议!
这是我沙盒的 link:https://codesandbox.io/s/vue3-form-54xi8
我的父组件VueVModel.vue
:
<template>
<div>
<custom-text-input
v-model:firstName="firstName"
v-model:lastName="lastName"
v-model:address.street="address.street"
/>
<p>First Name: {{ firstName }}</p>
<p>Last Name: {{ lastName }}</p>
<p>Street: {{ address.street }}</p>
</div>
</template>
<script>
import { ref, reactive } from "vue";
import CustomTextInput from "./CustomTextInput.vue";
export default {
components: {
CustomTextInput,
},
setup() {
// data
const firstName = ref("Max");
const lastName = ref("Testname");
const address = reactive({
street: "Milkyway 3",
});
return {
firstName,
lastName,
address,
};
},
};
</script>
我的子组件CustomTextInput.vue
<template>
<div>
<p>
<label> First Name </label>
<input
type="text"
:value="firstName"
placeholder="First Name"
@input="$emit('update:firstName', $event.target.value)"
/>
</p>
<p>
<label> Last Name </label>
<input
type="text"
:value="lastName"
placeholder="Last Name"
@input="$emit('update:lastName', $event.target.value)"
/>
</p>
<p>
<label> Street </label>
<input
type="text"
:value="street"
placeholder="Street"
@input="$emit('update:street', $event.target.value)"
/>
</p>
</div>
</template>
<script>
export default {
props: {
firstName: String,
lastName: String,
street: String,
},
};
</script>
您传递的 address.street
无法映射到道具中的 address.street
对象。而是尝试仅通过街道。
<custom-text-input
v-model:firstName="firstName"
v-model:lastName="lastName"
v-model:street="address.street"
></custom-text-input>
const app = Vue.createApp({
setup() {
// data
const firstname = Vue.ref('Max');
const lastname = Vue.ref('Testname');
const address = Vue.reactive({
street: 'Milkyway 3',
zip: 12345,
city: 'Mars-Village',
});
return {
firstname,
lastname,
address,
};
}
})
app.component('custom-text-input', {
template: document.getElementById("CustomTextInputTemplate").innerHTML,
props: {
firstname: {
type: String,
required: true,
},
lastname: {
type: String,
required: true,
},
street: {
type: String,
required: true,
},
}
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.0.7/dist/vue.global.prod.js"></script>
<div id="app">
<div>
<h1>Form</h1>
<custom-text-input
v-model:firstname="firstname"
v-model:lastname="lastname"
v-model:street="address.street"
></custom-text-input>
<hr />
<h3> Debugging </h3>
<p>First Name: {{ firstname }}</p>
<p>Last Name: {{ lastname }}</p>
<p>Street: {{ address.street }}</p>
<div>
Address-Object:
<pre>{{ address }}</pre>
</div>
</div>
</div>
<template id="CustomTextInputTemplate">
<div>
<p>
<label> First Name </label>
<input type="text" :value="firstname" placeholder="First Name" @blur="$emit('update:firstname', $event.target.value)" />
</p>
<p>
<label> Last Name </label>
<input type="text" :value="lastname" placeholder="Last Name" @blur="$emit('update:lastname', $event.target.value)" />
</p>
<p>
<label> Street </label>
<input type="text" :value="street" placeholder="Street" @blur="$emit('update:street', $event.target.value)" />
</p>
</div>
</template>
我正在尝试创建一个包含嵌套组件的表单,其中传递给子组件的数据可以是对象的嵌套值。
带字符串的输入字段按预期工作,我只是对对象值有疑问。 预先感谢您的建议!
这是我沙盒的 link:https://codesandbox.io/s/vue3-form-54xi8
我的父组件VueVModel.vue
:
<template>
<div>
<custom-text-input
v-model:firstName="firstName"
v-model:lastName="lastName"
v-model:address.street="address.street"
/>
<p>First Name: {{ firstName }}</p>
<p>Last Name: {{ lastName }}</p>
<p>Street: {{ address.street }}</p>
</div>
</template>
<script>
import { ref, reactive } from "vue";
import CustomTextInput from "./CustomTextInput.vue";
export default {
components: {
CustomTextInput,
},
setup() {
// data
const firstName = ref("Max");
const lastName = ref("Testname");
const address = reactive({
street: "Milkyway 3",
});
return {
firstName,
lastName,
address,
};
},
};
</script>
我的子组件CustomTextInput.vue
<template>
<div>
<p>
<label> First Name </label>
<input
type="text"
:value="firstName"
placeholder="First Name"
@input="$emit('update:firstName', $event.target.value)"
/>
</p>
<p>
<label> Last Name </label>
<input
type="text"
:value="lastName"
placeholder="Last Name"
@input="$emit('update:lastName', $event.target.value)"
/>
</p>
<p>
<label> Street </label>
<input
type="text"
:value="street"
placeholder="Street"
@input="$emit('update:street', $event.target.value)"
/>
</p>
</div>
</template>
<script>
export default {
props: {
firstName: String,
lastName: String,
street: String,
},
};
</script>
您传递的 address.street
无法映射到道具中的 address.street
对象。而是尝试仅通过街道。
<custom-text-input
v-model:firstName="firstName"
v-model:lastName="lastName"
v-model:street="address.street"
></custom-text-input>
const app = Vue.createApp({
setup() {
// data
const firstname = Vue.ref('Max');
const lastname = Vue.ref('Testname');
const address = Vue.reactive({
street: 'Milkyway 3',
zip: 12345,
city: 'Mars-Village',
});
return {
firstname,
lastname,
address,
};
}
})
app.component('custom-text-input', {
template: document.getElementById("CustomTextInputTemplate").innerHTML,
props: {
firstname: {
type: String,
required: true,
},
lastname: {
type: String,
required: true,
},
street: {
type: String,
required: true,
},
}
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.0.7/dist/vue.global.prod.js"></script>
<div id="app">
<div>
<h1>Form</h1>
<custom-text-input
v-model:firstname="firstname"
v-model:lastname="lastname"
v-model:street="address.street"
></custom-text-input>
<hr />
<h3> Debugging </h3>
<p>First Name: {{ firstname }}</p>
<p>Last Name: {{ lastname }}</p>
<p>Street: {{ address.street }}</p>
<div>
Address-Object:
<pre>{{ address }}</pre>
</div>
</div>
</div>
<template id="CustomTextInputTemplate">
<div>
<p>
<label> First Name </label>
<input type="text" :value="firstname" placeholder="First Name" @blur="$emit('update:firstname', $event.target.value)" />
</p>
<p>
<label> Last Name </label>
<input type="text" :value="lastname" placeholder="Last Name" @blur="$emit('update:lastname', $event.target.value)" />
</p>
<p>
<label> Street </label>
<input type="text" :value="street" placeholder="Street" @blur="$emit('update:street', $event.target.value)" />
</p>
</div>
</template>