Child 从 object 传播到 parent,共 object 秒
Child propagation to parent from object of objects
我有一个带有列下拉列表的 table,而不是为每个列创建 objects(即数据:{col1:{},..}),我有一个 object 的 object 个,在 "created".
上初始化和填充
因此,我遇到的问题是,当 object 传递给 child 时,child 组件没有正确地将更改传播到 parent 组件] 道具是 object 来自 object 的 object。
仅供参考,table数据是通过 axios 检索的。
我正在使用 quasar 和 vue。
我最初有一个 object 被传递给 child 组件并且能够让同步修改器正常工作。然后继续制作 object 的 object 并传递到每一列。
console.log(this.selected) 在 child 组件选择列表中打印为空。
注意:这是一个包含根本问题的示例。
table.vue#parent
<q-table
row-key="id"
:tableData
:columns
:visible-columns="visibleColumns">
<q-tr slot="top-row" slot-scope="props">
<q-td v-for="col in visibleColumns">
<child-component
:selected.sync="dropDownSelected[col]"
:options="dropDownOptions[col]"
/>
</q-td>
</q-tr>
</q-table>
<script>
import ChildComponent from 'path/to/child-component.vue';
export default{
name: 'table',
components: {
'child-component': ChildComponent
},
data(){
return{
tableData: [{id: 1, col1: 'a', col2: 'b', col3: 'c'}],
columns: [
{name: 'col1', label: 'Col1', field: 'col1'},
{name: 'col2', label: 'Col2', field: 'col2'},
{name: 'col3', label: 'Col3', field: 'col3'},
],
visibleColumns: ['col1', 'col2'],
dropDownSelected: {},
dropDownOptions: {}
}
},
created() {
this.initializeDropDown();
this.populateTableSelect();
},
methods: {
initializeDropDown(){
for(var col in this.columns){
this.dropDownSelected[col.name] = [];
this.dropDownOptions[col.name] = [];
}
},
populateTableSelect(){
// initiallize all columns with new Set
var tmp_set = {};
for(var col in this.dropDownOptions){
tmp_set[col] = new Set();
}
// iterate row, add items to set
for(var row = 0; row < this.tableData.length; row++){
for(var col in this.dropDownOptions){
tmp_set[col].add(this.tableData[row][col]);
}
}
for (var col in this.dropDownOptions) {
tmp_set[col] = [...tmp_set[col]];
tmp_set[col].sort();
tmp_set[col] = tmp_set[col].map(item => ({ label: item, value: item }));
tmp_set[col].unshift({ label: 'Select All', value: 'Select All' });
this.dropDownOptions[col] = tmp_set[col];
}
}
},
}
</script>
child-component.vue
<q-select
multiple
:options="options"
:value="selected"
@input="selectionList">
</q-select>
<script>
export default{
name: 'child-component',
props: {
options: {type: Array, required: true},
selected: {type: Array, default: () => ([])},
allValue: { type: String, default: 'Select All' }
},
methods: {
selectionList(inputList){
// logic below used from outside source
if (inputList.find(item => item === this.allValue)){
if(this.selected.find(item => item === this.allValue)){
// case 1: one item is unchecked while 'all' is checked -> unchecks 'all' + keep other
inputList.splice(inputList.indexOf(this.allValue), 1);
this.$emit('update:selected', inputList);
}
else {
// case 2: 'all' is checked -> select-all
this.$emit('update:selected', this.options.map(option => option.value));
}
}
else {
if(this.selected.find(item => item === this.allValue)){
// case 3: unchecking 'all' -> clear selected
this.$emit('update:selected', []);
}
else{
if(inputList.length === this.options.length -1){
// case 4: len is equal to options -> select-all
this.$emit('update:selected', this.options.map(option => option.value));
}
else {
// case 5: check an item
this.$emit('update:selected', inputList);
}
}
}
},
},
}
</script>
我预计从 object 的 object 传递 object 将允许 'Select All' 逻辑传播到 parent。
我没有看到任何错误,所以我不知道 js 在做什么。
据我所知,这是 documentation 中解释的一个简单的反应性问题。
dropDownOptions
和 dropDownSelected
是您添加新键的对象。每次执行此操作时,都需要调用 this.$set
.
我觉得如果只改这个方法应该不错:
initializeDropDown(){
for(var col in this.columns){
this.$set(this.dropDownSelected, col.name, []);
this.$set(this.dropDownOptions, col.name, []);
}
},
我有一个带有列下拉列表的 table,而不是为每个列创建 objects(即数据:{col1:{},..}),我有一个 object 的 object 个,在 "created".
上初始化和填充因此,我遇到的问题是,当 object 传递给 child 时,child 组件没有正确地将更改传播到 parent 组件] 道具是 object 来自 object 的 object。
仅供参考,table数据是通过 axios 检索的。 我正在使用 quasar 和 vue。
我最初有一个 object 被传递给 child 组件并且能够让同步修改器正常工作。然后继续制作 object 的 object 并传递到每一列。
console.log(this.selected) 在 child 组件选择列表中打印为空。
注意:这是一个包含根本问题的示例。
table.vue#parent
<q-table
row-key="id"
:tableData
:columns
:visible-columns="visibleColumns">
<q-tr slot="top-row" slot-scope="props">
<q-td v-for="col in visibleColumns">
<child-component
:selected.sync="dropDownSelected[col]"
:options="dropDownOptions[col]"
/>
</q-td>
</q-tr>
</q-table>
<script>
import ChildComponent from 'path/to/child-component.vue';
export default{
name: 'table',
components: {
'child-component': ChildComponent
},
data(){
return{
tableData: [{id: 1, col1: 'a', col2: 'b', col3: 'c'}],
columns: [
{name: 'col1', label: 'Col1', field: 'col1'},
{name: 'col2', label: 'Col2', field: 'col2'},
{name: 'col3', label: 'Col3', field: 'col3'},
],
visibleColumns: ['col1', 'col2'],
dropDownSelected: {},
dropDownOptions: {}
}
},
created() {
this.initializeDropDown();
this.populateTableSelect();
},
methods: {
initializeDropDown(){
for(var col in this.columns){
this.dropDownSelected[col.name] = [];
this.dropDownOptions[col.name] = [];
}
},
populateTableSelect(){
// initiallize all columns with new Set
var tmp_set = {};
for(var col in this.dropDownOptions){
tmp_set[col] = new Set();
}
// iterate row, add items to set
for(var row = 0; row < this.tableData.length; row++){
for(var col in this.dropDownOptions){
tmp_set[col].add(this.tableData[row][col]);
}
}
for (var col in this.dropDownOptions) {
tmp_set[col] = [...tmp_set[col]];
tmp_set[col].sort();
tmp_set[col] = tmp_set[col].map(item => ({ label: item, value: item }));
tmp_set[col].unshift({ label: 'Select All', value: 'Select All' });
this.dropDownOptions[col] = tmp_set[col];
}
}
},
}
</script>
child-component.vue
<q-select
multiple
:options="options"
:value="selected"
@input="selectionList">
</q-select>
<script>
export default{
name: 'child-component',
props: {
options: {type: Array, required: true},
selected: {type: Array, default: () => ([])},
allValue: { type: String, default: 'Select All' }
},
methods: {
selectionList(inputList){
// logic below used from outside source
if (inputList.find(item => item === this.allValue)){
if(this.selected.find(item => item === this.allValue)){
// case 1: one item is unchecked while 'all' is checked -> unchecks 'all' + keep other
inputList.splice(inputList.indexOf(this.allValue), 1);
this.$emit('update:selected', inputList);
}
else {
// case 2: 'all' is checked -> select-all
this.$emit('update:selected', this.options.map(option => option.value));
}
}
else {
if(this.selected.find(item => item === this.allValue)){
// case 3: unchecking 'all' -> clear selected
this.$emit('update:selected', []);
}
else{
if(inputList.length === this.options.length -1){
// case 4: len is equal to options -> select-all
this.$emit('update:selected', this.options.map(option => option.value));
}
else {
// case 5: check an item
this.$emit('update:selected', inputList);
}
}
}
},
},
}
</script>
我预计从 object 的 object 传递 object 将允许 'Select All' 逻辑传播到 parent。
我没有看到任何错误,所以我不知道 js 在做什么。
据我所知,这是 documentation 中解释的一个简单的反应性问题。
dropDownOptions
和 dropDownSelected
是您添加新键的对象。每次执行此操作时,都需要调用 this.$set
.
我觉得如果只改这个方法应该不错:
initializeDropDown(){
for(var col in this.columns){
this.$set(this.dropDownSelected, col.name, []);
this.$set(this.dropDownOptions, col.name, []);
}
},