获取子组件输入数据到父组件,在 Vue.js 中收集到数组?
Getting Child Component Input Data to Parent, gathering into Array in Vue.js?
** 例如,在这里,当我点击按钮时,我将多一个组件,这意味着它将有新数据,所以我想在按下保存数据按钮时将所有信息收集到一个数组中,我希望,它很容易理解
<Child v-for="count in btnNumber" :key="count" @showData="getElements" />
<v-btn
color="primary"
elevation="10"
class="space"
large
@click="duplicateEl"
>Add Categ & Key</v-btn
>
v-btn
color="secondary"
elevation="13"
class="btnEl"
dark
large
@click="getResult"
>Save Data</v-btn
** 它正在使用 Emit 从我的子组件获取数据
methods:{
getElements(emitPayload) {
this.selectedChildCategory = emitPayload.selectedCateg;
this.selectedChildKey = emitPayload.selectedKey;
this.selectedChildLanguage = emitPayload.selectedLang;
this.selectedChildContent = emitPayload.selectedCon;
}
}
duplicateEl() {
this.btnNumber++;
}
尝试将发射事件的数据(从获取元素)保存到一个新的数据变量数组,并使用该数组
<template>
<div>
<Child
v-for="count in btnNumber"
:key="count"
@showData="getElements(count)"
/>
<!-- BUTTONS HERE -->
</div>
</template>
<script>
export default {
data() {
return {
elementsEmmitedDataArray: [], // array
};
},
methods: {
getElements(countIndex, emitPayload) {
const data = {
uniqueIndex: countIndex, //or anything unique for each Child component
selectedChildCategory: emitPayload.selectedCateg,
selectedChildKey: emitPayload.selectedKey,
selectedChildLanguage: emitPayload.selectedLang,
selectedChildContent: emitPayload.selectedCon,
};
// check if uniqindex is already exist in array then update it else push new data
const index = this.elementsEmmitedDataArray.findIndex(
(element) => element.uniqueIndex === countIndex
);
if (index !== -1) {
this.elementsEmmitedDataArray[index] = data;
} else {
this.elementsEmmitedDataArray.push(data);
}
},
duplicateEl() {
this.btnNumber++;
},
submitData(){
// use the array
console.log(this.elementsEmmitedDataArray);
}
},
};
</script>
你可以在父组件上保存数据,请看下面的代码片段:
Vue.component('Child', {
template: `
<v-form>
<v-container>
<v-row>
<v-col>
<v-select
:items="categories"
label="Category"
dense
outlined
v-model="content.cat"
@change="setD"
></v-select>
</v-col>
<v-col>
<v-select
:items="keys"
label="Key"
dense
outlined
v-model="content.key"
@change="setD"
></v-select>
</v-col>
<v-col>
<v-select
:items="langs"
label="Lang"
dense
outlined
v-model="content.lang"
@change="setD"
></v-select>
</v-col>
<v-col>
<v-select
:items="contents"
label="Cont"
dense
outlined
v-model="content.cont"
@change="setD"
></v-select>
</v-col>
</v-row>
</v-container>
</v-form>
`,
props: ['conte'],
data() {
return {
content: this.conte,
categories: ['first', 'second', 'third'],
keys: [1,2,3],
langs: ['g', 'h', 'j'],
contents: ['aaa', 'bbb', 'ccc']
}
},
methods: {
setD() {
this.$emit('show', this.content);
},
},
})
new Vue({
vuetify: new Vuetify(),
el: "#app",
data() {
return {
contentFields: [{id: 0, cat: '', key: '', lang: '', cont: ''}],
showData: false
}
},
methods: {
addInput() {
let newI = this.contentFields.length
this.contentFields.push({id: newI, cat: '', key: '', lang: '', cont: ''})
},
getElements(e){
const newData = this.contentFields.map(obj => {
if(obj.id === e.id)
return { ...obj }
return obj
});
},
getResult() {
this.showData = !this.showData
}
}
})
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<v-container>
<v-btn
color="primary"
elevation="10"
class="space"
large
@click="addInput"
>Add Categ & Key</v-btn>
<v-container v-for="(content, i) in contentFields" :key="i">
<child :conte="content" @show="getElements" />
</v-container>
<v-btn
color="secondary"
elevation="13"
class="btnEl"
dark
large
@click="getResult"
>Save Data</v-btn>
<div v-if="showData">{{ contentFields }}</div>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
** 例如,在这里,当我点击按钮时,我将多一个组件,这意味着它将有新数据,所以我想在按下保存数据按钮时将所有信息收集到一个数组中,我希望,它很容易理解
<Child v-for="count in btnNumber" :key="count" @showData="getElements" />
<v-btn
color="primary"
elevation="10"
class="space"
large
@click="duplicateEl"
>Add Categ & Key</v-btn
>
v-btn
color="secondary"
elevation="13"
class="btnEl"
dark
large
@click="getResult"
>Save Data</v-btn
** 它正在使用 Emit 从我的子组件获取数据
methods:{
getElements(emitPayload) {
this.selectedChildCategory = emitPayload.selectedCateg;
this.selectedChildKey = emitPayload.selectedKey;
this.selectedChildLanguage = emitPayload.selectedLang;
this.selectedChildContent = emitPayload.selectedCon;
}
}
duplicateEl() {
this.btnNumber++;
}
尝试将发射事件的数据(从获取元素)保存到一个新的数据变量数组,并使用该数组
<template>
<div>
<Child
v-for="count in btnNumber"
:key="count"
@showData="getElements(count)"
/>
<!-- BUTTONS HERE -->
</div>
</template>
<script>
export default {
data() {
return {
elementsEmmitedDataArray: [], // array
};
},
methods: {
getElements(countIndex, emitPayload) {
const data = {
uniqueIndex: countIndex, //or anything unique for each Child component
selectedChildCategory: emitPayload.selectedCateg,
selectedChildKey: emitPayload.selectedKey,
selectedChildLanguage: emitPayload.selectedLang,
selectedChildContent: emitPayload.selectedCon,
};
// check if uniqindex is already exist in array then update it else push new data
const index = this.elementsEmmitedDataArray.findIndex(
(element) => element.uniqueIndex === countIndex
);
if (index !== -1) {
this.elementsEmmitedDataArray[index] = data;
} else {
this.elementsEmmitedDataArray.push(data);
}
},
duplicateEl() {
this.btnNumber++;
},
submitData(){
// use the array
console.log(this.elementsEmmitedDataArray);
}
},
};
</script>
你可以在父组件上保存数据,请看下面的代码片段:
Vue.component('Child', {
template: `
<v-form>
<v-container>
<v-row>
<v-col>
<v-select
:items="categories"
label="Category"
dense
outlined
v-model="content.cat"
@change="setD"
></v-select>
</v-col>
<v-col>
<v-select
:items="keys"
label="Key"
dense
outlined
v-model="content.key"
@change="setD"
></v-select>
</v-col>
<v-col>
<v-select
:items="langs"
label="Lang"
dense
outlined
v-model="content.lang"
@change="setD"
></v-select>
</v-col>
<v-col>
<v-select
:items="contents"
label="Cont"
dense
outlined
v-model="content.cont"
@change="setD"
></v-select>
</v-col>
</v-row>
</v-container>
</v-form>
`,
props: ['conte'],
data() {
return {
content: this.conte,
categories: ['first', 'second', 'third'],
keys: [1,2,3],
langs: ['g', 'h', 'j'],
contents: ['aaa', 'bbb', 'ccc']
}
},
methods: {
setD() {
this.$emit('show', this.content);
},
},
})
new Vue({
vuetify: new Vuetify(),
el: "#app",
data() {
return {
contentFields: [{id: 0, cat: '', key: '', lang: '', cont: ''}],
showData: false
}
},
methods: {
addInput() {
let newI = this.contentFields.length
this.contentFields.push({id: newI, cat: '', key: '', lang: '', cont: ''})
},
getElements(e){
const newData = this.contentFields.map(obj => {
if(obj.id === e.id)
return { ...obj }
return obj
});
},
getResult() {
this.showData = !this.showData
}
}
})
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<v-container>
<v-btn
color="primary"
elevation="10"
class="space"
large
@click="addInput"
>Add Categ & Key</v-btn>
<v-container v-for="(content, i) in contentFields" :key="i">
<child :conte="content" @show="getElements" />
</v-container>
<v-btn
color="secondary"
elevation="13"
class="btnEl"
dark
large
@click="getResult"
>Save Data</v-btn>
<div v-if="showData">{{ contentFields }}</div>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>