我有一个非常简单的父/子组件。我想以两种方式使用子组件-首先用于操作添加一个新条目,第二个用于操作更新实体。
我已经构建了以下组件:https://codepen.io/anon/pen/bJdjyx这里不使用道具,我使用自定义事件将父级和子级的值同步。
添加模板:
<div id="app">
<v-app>
<v-content>
<v-container grid-list-xl>
<my-address
:addresscompany.sync="addressCompany"
:addressstreet.sync="addressStreet"
></my-address>
<v-btn @click="submit">Submit</v-btn>
</v-container>
</v-content>
</v-app>
</div>
<script type="text/x-template" id="address-template">
<div>
<v-text-field
name="company"
v-model="addressCompany"
@change="updateCompany()">
</v-text-field>
<v-text-field
name="street"
v-model="addressStreet"
@change="updateStreet()">
</v-text-field>
</div>
</script>
添加-脚本:
let addressComponent = {
template: '#address-template',
data() {
return {
addressCompany: '',
addressStreet: '',
}
},
methods: {
updateCompany () {
this.$emit('update:addresscompany', this.addressCompany);
},
updateStreet () {
this.$emit('update:addressstreet', this.addressStreet);
}
}
};
new Vue({
el: '#app',
components: {'my-address' : addressComponent},
data() {
return {
addressCompany: '',
addressStreet: '',
}
},
methods: {
submit () {
console.log('Company ' + this.addressCompany);
console.log('Street ' + this.addressStreet);
}
}
})
但是这个模板不适用于编辑用例,因为我需要道具将值传递给子实例。所以我想出了这个:https://codepen.io/anon/pen/zXGLQG
更新-模板:
<div id="app">
<v-app>
<v-content>
<v-container grid-list-xl>
<my-address
:addresscompany.sync="addressCompany"
:addressstreet.sync="addressStreet"
></my-address>
<v-btn @click="submit">Submit</v-btn>
</v-container>
</v-content>
</v-app>
</div>
<script type="text/x-template" id="address-template">
<div>
<v-text-field
name="company"
:value="addressCompany"
@change="updateCompany()">
</v-text-field>
<v-text-field
name="street"
:value="addressStreet"
@change="updateStreet()">
</v-text-field>
</div>
</script>
更新-脚本:
let addressComponent = {
template: '#address-template',
props: ['addressCompany', 'addressStreet'],
data() {
return {
}
},
methods: {
updateCompany () {
this.$emit('update:addresscompany', this.addressCompany);
},
updateStreet () {
this.$emit('update:addressstreet', this.addressStreet);
}
}
};
new Vue({
el: '#app',
components: {'my-address' : addressComponent},
data() {
return {
addressCompany: 'Company',
addressStreet: 'Street',
}
},
methods: {
submit () {
console.log('Company ' + this.addressCompany);
console.log('Street ' + this.addressStreet);
}
}
})
主要的区别是,对于更新情况,我不对子元素使用v-model,因为我不能直接更改道具。但是使用:value时,更新事件不会被触发。
那么,使用该子组件进行添加和更新的正确方法是什么?在使用Vuex之前必须有一个标准的Vue方法,有吗?
谢谢!
发布于 2019-04-02 12:44:45
我经常使用以下模式:
创建一个实体的抽象组件,在下面的示例中,我使用了Person.vue
和firstName
和lastName
道具。
Vue.component('Person' , {
template: `
<div>
<input type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"/>
<input type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"/>
</div>
`,
props: {
firstName: String,
lastName: String
}
});
此组件的作用域严格限制为绑定到
Person
对象,响应其更改并更新父对象抛出sync
事件修饰符。
接下来,创建一个包装组件,该组件将处理实际对象(即Person.js
)的状态。它的子组件Person.vue
不关心您是在添加模式还是编辑“模式”。这个组件只负责对模型的变化作出反应。
这个组件应该从API调用或数据存储(更新模式)中加载Person
对象,或者创建一个新的空对象,即new Person()
(Add )。
下面是一个简单的示例,理想情况下,父组件(在本例中为app)将被拆分,从而减少了helper属性的使用。
function Person (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Vue.component('Person' , {
template: `
<div>
<input type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"/>
<input type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"/>
</div>
`,
props: {
firstName: String,
lastName: String
}
});
new Vue({
el: '#app',
template: `
<div>
<!-- Add mode, should be its own component -->
<section v-if="promptAdd">
<Person v-bind.sync="newPerson"/>
<button type="button" @click="onAdded">Add</button>
</section>
<!-- Update mode, should be its own component -->
<section v-else>
<p>Users:</p>
<div v-for="(person, index) in arr" :key="index">
<Person v-bind.sync="person"/>
</div>
<button type="button"
@click="addNew">Add New User</button>
</section>
</div>
`,
data: () => ({
promptAdd: false,
newPerson: undefined,
arr: [
new Person('Bob', 'Smith')
]
}),
methods: {
addNew() {
this.newPerson = new Person();
this.promptAdd = true;
},
onAdded () {
this.arr.push({ ...this.newPerson });
this.promptAdd = false;
this.newPerson = undefined;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
https://stackoverflow.com/questions/55481632
复制