Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vue.js 如何在子事件发出的事件中捕获父组件事件_Vue.js_Vuejs2_Vue Component - Fatal编程技术网

Vue.js 如何在子事件发出的事件中捕获父组件事件

Vue.js 如何在子事件发出的事件中捕获父组件事件,vue.js,vuejs2,vue-component,Vue.js,Vuejs2,Vue Component,我试图在Vue中创建两个级别的动态表:子组件包含以“idx”为:key的单元格,父组件在表中以“line”为:key的子组件 我的问题是:当我捕获定制事件@update cellValue时,我将idx、oldValue和newValue引入范围,但我无法访问发出事件的父组件的详细信息(v-for中的哪一行)。我的意思是,我的目的是让这两个(直线,idx)都像矩阵(2D数组)一样工作 我有一个解决办法,可以在一个级别中完成所有工作,只需在“child's component”中直接使用v-for

我试图在Vue中创建两个级别的动态表:子组件包含以“idx”为:key的单元格,父组件在表中以“line”为:key的子组件

我的问题是:当我捕获定制事件@update cellValue时,我将idx、oldValue和newValue引入范围,但我无法访问发出事件的父组件的详细信息(v-for中的哪一行)。我的意思是,我的目的是让这两个(直线,idx)都像矩阵(2D数组)一样工作

我有一个解决办法,可以在一个级别中完成所有工作,只需在“child's component”中直接使用v-for,但我希望在两个不同的组件中分别使用它

子(嵌套)组件->包含单元格的表行

<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 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> 

//var editable=document.getElementById('cell');
//可编辑。addEventListener('input',function(){
//log('嘿,有人在我的文本中更改了某些内容!');
// });
导出默认值{
名称:'卡罗',
道具:{
cellValArr:{
类型:数组,
必填项:false,
默认值:()=>[],
},
标题:{
类型:字符串,
默认值:`noNameRow`
}
},
数据(){
返回{
单元格:[]
}
},
方法:{
updateCellValueEv(事件){
const idx=event.target.parentElement.cellIndex;
设val=event.target.value;
如果(val=='')val=0;
const oldNumber=parseFloat(this.cells[idx]);
const newNumber=parseFloat(val);
如果(!isNaN(新编号)&&!isNaN(旧编号)){
//log(`new${newNumber},old${oldNumber}`)
此.$emit('update-cellValue',idx,newNumber,oldname);
this.cells[idx]=newNumber;
}
},
},
已创建(){
此.cellValArr.map((val,idx)=>{
此.cells[idx]=val;
});
},
}
父组件(将直接在应用程序中使用)->包含子组件作为行的表

<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 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> 

{{line}}
从“./components/CaRow.vue”导入CaRow
导出默认值{
名称:“应用程序”,
组成部分:{
卡罗
},
数据(){
返回{
表:[[1,2,3],
[4,5,6],
[7,8,9]],
selectedCell:空,
}
},
方法:{
updateCellVal(idx、newValue、oldValue){
log(`cell[${idx}:New Value=${newValue},Old Value=${oldValue}]`)
//表[line][idx]=newValue;
//问题就在这里!!!
//行不在此范围内
}
},
}

CaRow.vue
中,将事件数据包装到单个对象中:

//这个。$emit('update-cellValue',idx,newNumber,oldname);
这个.$emit('update-cellValue',{idx,newValue:newNumber,oldValue:oldNumber});
然后在父模板中,更新事件处理程序绑定以传递行索引(在此上下文中为
idx
)和
$event
(存储发出的事件数据的特殊变量):


并更新处理程序以接收行索引和
$event

导出默认值{
方法:{
updateCellVal(行,{idx,newValue,oldValue}){
log({line,idx,newValue,oldValue});
}
}
}
Vue 2,因此您必须使用:

//this.table[line][idx]=newValue;
this.$set(this.table[line],idx,newValue);