我偶然发现了这种情况,我希望将prop传递给子组件,该子组件将是组件的default
值,但只有在初始值为空时才会显示。
父组件:
<multi-line-input v-model="data.something" placeholder="Enter Something" :default="data.something"/>
子组件
props: {
value: {
type: String,
default: ''
},
default: {
type: String,
default: ''
},
},
methods: {
emitBlur (e) {
if (!this.value && this.default) {
this.value = this.default
}
this.$emit('blur')
},
emitInput () {
this.$emit('input', this.$el.value)
}
}
所以我基本上想要实现的是,当组件加载时会从v-model
获取值,它也会收到一个不应更改的default
值,并且仅用作值当blur
default
的初始值为data.something
,不应更改!
我试图使用JSON.parse(JSON.stringify(this.value))
删除引用,但它似乎也不起作用!
答案 0 :(得分:2)
因此,如果我正确理解您的问题,您需要此行为:在blur
组件上的<multi-line-input>
事件上,如果输入的值为空,则将值设置为默认值由父母指定(通过道具)。
首先,在组件中执行this.value = ...
是一个错误。你不能修改道具,道具只能将数据从父传递给子,通过道具传递的数据不是你自己直接从组件内修改的。
尝试这样的事情:
Vue.component('multi-line-input', {
template: '<input @blur="onBlur" @input="onInput" :value="value">',
props: {
value: {
type: String,
default: '',
},
default: {
type: String,
default: '',
},
},
methods: {
onBlur() {
if (!this.value && this.default) {
this.$emit('input', this.default);
}
},
onInput(e) {
this.$emit('input', e.target.value);
},
},
});
new Vue({
el: '#app',
data: {
user: null,
initialUser: null,
},
created() {
// Pretend that I'm pulling this data from some API
this.user = {
name: 'Fred',
email: 'fred@email.com',
address: '123 Fake St',
};
// Make a copy of the data for the purpose of assigning the
// default prop of each input
this.initialUser = _.cloneDeep(this.user);
},
});
&#13;
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div id="app">
<template v-if="user">
<multi-line-input v-model="user.name" :default="initialUser.name"></multi-line-input>
<multi-line-input v-model="user.email" :default="initialUser.email"></multi-line-input>
<multi-line-input v-model="user.address" :default="initialUser.address"></multi-line-input>
</template>
</div>
&#13;
或者,如果您希望组件而不是父组件(通过道具)确定默认值,则可以执行以下操作:
Vue.component('multi-line-input', {
template: '<input @blur="onBlur" @input="onInput" :value="value">',
props: {
value: {
type: String,
default: '',
},
},
created() {
this.def = this.value;
},
methods: {
onBlur() {
if (!this.value && this.def) {
this.$emit('input', this.def);
}
},
onInput(e) {
this.$emit('input', e.target.value);
},
},
});
new Vue({
el: '#app',
data: {
user: null,
},
created() {
// Pretend that I'm pulling this data from some API
this.user = {
name: 'Fred',
email: 'fred@email.com',
address: '123 Fake St',
};
},
});
&#13;
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<div id="app">
<template v-if="user">
<multi-line-input v-model="user.name"></multi-line-input>
<multi-line-input v-model="user.email"></multi-line-input>
<multi-line-input v-model="user.address"></multi-line-input>
</template>
</div>
&#13;
但是我不推荐第二种方法,因为子组件实例在其整个生命周期中只有一个默认值。 Vue尽可能重用组件实例,因此如果Vue将它绑定到不同的父组件(如何/何时更新其自己的default
状态?)它将无法工作。