如何在子事件发出的事件中捕获父组件事件
How Can I capture parent component event in an event emitted by a child event
我正在尝试在 Vue 中创建两个级别的动态 table:子组件包含带有 'idx' 作为 :key 的单元格,父组件在 [=28] 中包含子组件=] 与 'line' 作为 :key.
我的问题是:当我捕获自定义事件@update-cellValue 时,我将 idx、oldValue 和 newValue 引入了作用域,但我无法访问事件发生的父组件的详细信息发出(来自 v-for 的那一行)。我的意思是,我的意图是同时拥有 (line, idx) 并像矩阵(二维数组)一样工作。
我有一个解决方法,可以在一个级别上完成所有工作,只需在“子组件”中直接使用 v-for,但我想在两个不同的组件中单独使用它
子(嵌套)组件 -> Table 包含单元格的行
<template>
<div >
<tr class='center'>
<!-- add title to the tr as prop -->
<td
id='cell'
@click="selectCellEv"
v-for="(cell, idx) in cells" :key="idx">
<input type=number @input="updateCellValueEv"
v-model.lazy.trim="cells[idx]"/>
</td>
</tr>
</div>
</template>
<script>
// var editable = document.getElementById('cell');
// editable.addEventListener('input', function() {
// console.log('Hey, somebody changed something in my text!');
// });
export default {
name: 'CaRow',
props: {
cellValArr: {
type: Array,
required: false,
default: () => [],
},
title: {
type: String,
default: `noNameRow`
}
},
data(){
return {
cells: []
}
},
methods: {
updateCellValueEv(event){
const idx = event.target.parentElement.cellIndex;
let val = event.target.value;
if (val === '') val = 0;
const oldNumber = parseFloat(this.cells[idx]);
const newNumber = parseFloat(val);
if(!isNaN(newNumber) && !isNaN(oldNumber)){
// console.log(`new ${newNumber}, old ${oldNumber}`)
this.$emit('update-cellValue', idx, newNumber, oldNumber);
this.cells[idx] = newNumber;
}
},
},
created() {
this.cellValArr.map((val,idx) => {
this.cells[idx] = val;
});
},
}
</script>
父组件(将在应用程序中直接使用)-> Table 包含子组件作为行
<table class="center">
<CaRow
v-for="(line, idx) in table"
:key="idx"
:cellValArr="table[idx]"
@update-cellValue="updateCellVal"
>{{line}} </CaRow>
</table>
</template>
<script>
import CaRow from './components/CaRow.vue'
export default {
name: 'App',
components: {
CaRow
},
data(){
return{
table: [[1,2,3],
[4,5,6],
[7,8,9]],
selectedCell: null,
}
},
methods: {
updateCellVal(idx, newValue, oldValue) {
console.log(`cell[${idx}: New Value= ${newValue}, Old Value= ${oldValue}]`)
// this.table[line][idx] = newValue;
//HERE IS THE PROBLEM!!!
//LINE IS NOT IN THIS SCOPE
}
},
}
</script>
在CaRow.vue
中,将事件数据包装到一个对象中:
//this.$emit('update-cellValue', idx, newNumber, oldNumber);
this.$emit('update-cellValue', { idx, newValue: newNumber, oldValue: oldNumber });
然后在父模板中,更新事件处理程序绑定以传递行索引(在此上下文中为 idx
)和 $event
(存储发出的事件数据的特殊变量) :
<CaRow @update-cellValue="updateCellVal(idx, $event)">
并更新处理程序以接收行索引和 $event
:
export default {
methods: {
updateCellVal(line, { idx, newValue, oldValue }) {
console.log({ line, idx, newValue, oldValue });
}
}
}
Vue 2 cannot detect the change when you directly set an item with the index, so you have to use this.$set()
:
//this.table[line][idx] = newValue;
this.$set(this.table[line], idx, newValue);
我正在尝试在 Vue 中创建两个级别的动态 table:子组件包含带有 'idx' 作为 :key 的单元格,父组件在 [=28] 中包含子组件=] 与 'line' 作为 :key.
我的问题是:当我捕获自定义事件@update-cellValue 时,我将 idx、oldValue 和 newValue 引入了作用域,但我无法访问事件发生的父组件的详细信息发出(来自 v-for 的那一行)。我的意思是,我的意图是同时拥有 (line, idx) 并像矩阵(二维数组)一样工作。
我有一个解决方法,可以在一个级别上完成所有工作,只需在“子组件”中直接使用 v-for,但我想在两个不同的组件中单独使用它
子(嵌套)组件 -> Table 包含单元格的行
<template>
<div >
<tr class='center'>
<!-- add title to the tr as prop -->
<td
id='cell'
@click="selectCellEv"
v-for="(cell, idx) in cells" :key="idx">
<input type=number @input="updateCellValueEv"
v-model.lazy.trim="cells[idx]"/>
</td>
</tr>
</div>
</template>
<script>
// var editable = document.getElementById('cell');
// editable.addEventListener('input', function() {
// console.log('Hey, somebody changed something in my text!');
// });
export default {
name: 'CaRow',
props: {
cellValArr: {
type: Array,
required: false,
default: () => [],
},
title: {
type: String,
default: `noNameRow`
}
},
data(){
return {
cells: []
}
},
methods: {
updateCellValueEv(event){
const idx = event.target.parentElement.cellIndex;
let val = event.target.value;
if (val === '') val = 0;
const oldNumber = parseFloat(this.cells[idx]);
const newNumber = parseFloat(val);
if(!isNaN(newNumber) && !isNaN(oldNumber)){
// console.log(`new ${newNumber}, old ${oldNumber}`)
this.$emit('update-cellValue', idx, newNumber, oldNumber);
this.cells[idx] = newNumber;
}
},
},
created() {
this.cellValArr.map((val,idx) => {
this.cells[idx] = val;
});
},
}
</script>
父组件(将在应用程序中直接使用)-> Table 包含子组件作为行
<table class="center">
<CaRow
v-for="(line, idx) in table"
:key="idx"
:cellValArr="table[idx]"
@update-cellValue="updateCellVal"
>{{line}} </CaRow>
</table>
</template>
<script>
import CaRow from './components/CaRow.vue'
export default {
name: 'App',
components: {
CaRow
},
data(){
return{
table: [[1,2,3],
[4,5,6],
[7,8,9]],
selectedCell: null,
}
},
methods: {
updateCellVal(idx, newValue, oldValue) {
console.log(`cell[${idx}: New Value= ${newValue}, Old Value= ${oldValue}]`)
// this.table[line][idx] = newValue;
//HERE IS THE PROBLEM!!!
//LINE IS NOT IN THIS SCOPE
}
},
}
</script>
在CaRow.vue
中,将事件数据包装到一个对象中:
//this.$emit('update-cellValue', idx, newNumber, oldNumber);
this.$emit('update-cellValue', { idx, newValue: newNumber, oldValue: oldNumber });
然后在父模板中,更新事件处理程序绑定以传递行索引(在此上下文中为 idx
)和 $event
(存储发出的事件数据的特殊变量) :
<CaRow @update-cellValue="updateCellVal(idx, $event)">
并更新处理程序以接收行索引和 $event
:
export default {
methods: {
updateCellVal(line, { idx, newValue, oldValue }) {
console.log({ line, idx, newValue, oldValue });
}
}
}
Vue 2 cannot detect the change when you directly set an item with the index, so you have to use this.$set()
:
//this.table[line][idx] = newValue;
this.$set(this.table[line], idx, newValue);