Javascript 如何在父事件的子组件上调用函数 上下文

Javascript 如何在父事件的子组件上调用函数 上下文,javascript,vue.js,event-handling,vuejs2,Javascript,Vue.js,Event Handling,Vuejs2,在Vue 2.0中,请参阅文档,并明确指出家长与孩子之间的沟通是通过道具进行的 问题: 父母如何通过道具告诉孩子事件发生了 我应该只看一个叫做“事件”的道具吗?这感觉不对劲,备选方案也不对劲($emit/$on用于子级到父级,而hub模型用于远程元素) 例子 我有一个父容器,它需要告诉它的子容器,可以在API上执行某些操作我需要能够触发函数。您描述的是父级中的状态变化。你通过道具把它传给孩子。正如您所建议的,您将观看该道具。当孩子采取行动时,它会通过一个发射通知家长,然后家长可能会再次更改状态

在Vue 2.0中,请参阅文档,并明确指出家长与孩子之间的沟通是通过道具进行的

问题: 父母如何通过道具告诉孩子事件发生了

我应该只看一个叫做“事件”的道具吗?这感觉不对劲,备选方案也不对劲(
$emit
/
$on
用于子级到父级,而hub模型用于远程元素)

例子
我有一个父容器,它需要告诉它的子容器,可以在API上执行某些操作我需要能够触发函数。

您描述的是父级中的状态变化。你通过道具把它传给孩子。正如您所建议的,您将观看该道具。当孩子采取行动时,它会通过一个
发射
通知家长,然后家长可能会再次更改状态

var子项={
模板:“{counter}}”,
道具:['canI'],
数据:函数(){
返回{
柜台:0
};
},
观察:{
canI:函数(){
if(this.canI){
++这个柜台;
这是.$emit('increment');
}
}
}
}
新Vue({
el:“#应用程序”,
组成部分:{
“我的组件”:子组件
},
数据:{
childState:错误
},
方法:{
permitChild:函数(){
this.childState=true;
},
lockChild:函数(){
this.childState=false;
}
}
})

您可以使用
$emit
$on
。使用@RoyJ代码:

html:


点击
javascript:

var Child = {
  template: '<div>{{value}}</div>',
  data: function () {
    return {
      value: 0
    };
  },
  methods: {
    setValue: function(value) {
        this.value = value;
    }
  },
  created: function() {
    this.$parent.$on('update', this.setValue);
  }
}

new Vue({
  el: '#app',
  components: {
    'my-component': Child
  },
  methods: {
    click: function() {
        this.$emit('update', 7);
    }
  }
})
var ChildComponent = {
  template: '<div>{{value}}</div>',
  data: function () {
    return {
      value: 0
    };
  },
  methods: {
    setValue: function(value) {
        this.value = value;
    }
  }
}

new Vue({
  el: '#app',
  components: {
    'child-component': ChildComponent
  },
  methods: {
    click: function() {
        this.$refs.childComponent.setValue(2.0);
    }
  }
})
var子项={
模板:“{value}}”,
数据:函数(){
返回{
数值:0
};
},
方法:{
设置值:函数(值){
这个值=值;
}
},
已创建:函数(){
this.$parent.$on('update',this.setValue);
}
}
新Vue({
el:“#应用程序”,
组成部分:{
“我的组件”:子组件
},
方法:{
单击:函数(){
此.$emit('update',7);
}
}
})

运行示例:

给子组件一个
ref
,并使用
$refs
直接调用子组件上的方法

html:


点击
javascript:

var Child = {
  template: '<div>{{value}}</div>',
  data: function () {
    return {
      value: 0
    };
  },
  methods: {
    setValue: function(value) {
        this.value = value;
    }
  },
  created: function() {
    this.$parent.$on('update', this.setValue);
  }
}

new Vue({
  el: '#app',
  components: {
    'my-component': Child
  },
  methods: {
    click: function() {
        this.$emit('update', 7);
    }
  }
})
var ChildComponent = {
  template: '<div>{{value}}</div>',
  data: function () {
    return {
      value: 0
    };
  },
  methods: {
    setValue: function(value) {
        this.value = value;
    }
  }
}

new Vue({
  el: '#app',
  components: {
    'child-component': ChildComponent
  },
  methods: {
    click: function() {
        this.$refs.childComponent.setValue(2.0);
    }
  }
})
var ChildComponent={
模板:“{value}}”,
数据:函数(){
返回{
数值:0
};
},
方法:{
设置值:函数(值){
这个值=值;
}
}
}
新Vue({
el:“#应用程序”,
组成部分:{
“子组件”:子组件
},
方法:{
单击:函数(){
此.refs.childComponent.setValue(2.0);
}
}
})

有关更多信息,请参阅。

如果您有时间,请使用Vuex store查看变量(也称为状态)或直接触发(称为分派)操作。

不喜欢在
创建期间在子项中使用
绑定。为什么?后续的
create
调用(我使用的是
vue路由器
)会多次绑定消息处理程序--导致每条消息都有多个响应

传统的解决方案是将道具从父母传给孩子,并在孩子身上放一个财产观察者,效果会好一点。唯一的问题是,孩子们只能在一个值转换上行动。多次传递同一消息需要某种簿记来强制转换,以便孩子能够接受更改

我发现,如果我将消息包装在一个数组中,它将始终触发子监视程序——即使值保持不变

家长:

{
   data: function() {
      msgChild: null,
   },
   methods: {
      mMessageDoIt: function() {
         this.msgChild = ['doIt'];
      }
   }   
   ...
}
儿童:

{
   props: ['msgChild'],
   watch: {
      'msgChild': function(arMsg) {
         console.log(arMsg[0]);
      }
   }
}
HTML:



我认为我们应该考虑一下家长使用孩子方法的必要性。事实上,家长不必关心孩子的方法,但可以将孩子组件视为FSA(有限状态机).Parents组件来控制子组件的状态。因此,监视状态更改或仅使用compute函数的解决方案就足够了

一种简单的对子组件调用方法的解耦方法是从子组件发出一个处理程序,然后从父组件调用它

var子项={
模板:“{value}}”,
数据:函数(){
返回{
数值:0
};
},
方法:{
设置值(值){
这个值=值;
}
},
创建(){
this.$emit('handler',this.setValue);
}
}
新Vue({
el:“#应用程序”,
组成部分:{
“我的组件”:子组件
},
方法:{
setValueHandler(fn){
this.setter=fn
},
单击(){
本.塞特(70)
}
}
})

点击
下面的例子是自我解释的。其中,REF和事件可用于从父级和子级调用函数和向父级和子级调用函数。

//父对象
子对象中的调用方法
导出默认值{
方法:{
callChild(){
此.refs.childRef.childMethod('Hi from parent');
},
childCallBack(消息){
console.log('来自子级的消息',消息);
}
}
};
//孩子
打电话给家长
导出默认值{
方法:{
callParent(){
此.emit('onChange','hi from child');
},
childMethod(消息){
console.log('来自父级的消息',消息);
}
}
}

您可以使用key来使用key重新加载子组件

<component :is="child1" :filter="filter" :key="componentKey"></component>

并使用筛选器触发调用父组件中的子组件的函数

<component :is="my_component" ref="my_comp"></component>
<v-btn @click="$refs.my_comp.alertme"></v-btn>

通过切换父级中的布尔属性,可以模拟将事件发送给子级

父代码:

...
<child :event="event">
...
export default {
  data() {
    event: false
  },
  methods: {
    simulateEmitEventToChild() {
      this.event = !this.event;
    },
    handleExample() {
      this.simulateEmitEventToChild();
    }
  } 
}

我很惊讶它能起作用。我认为向孩子发射是一种反模式,或者其目的是让发射只从孩子到父母。换一种方式有没有潜在的问题?我不知道,这可能不是最好的方式,但如果你知道你在做什么,我想这不是问题。另一种方法是使用中央总线:这会在子级和父级之间创建耦合,被认为是不好的做法。这只是因为父级不是组件,而是vue应用程序。在re
reloadData() {            
   this.filter = ['filter1','filter2']
   this.componentKey += 1;  
},
<component :is="my_component" ref="my_comp"></component>
<v-btn @click="$refs.my_comp.alertme"></v-btn>
    methods:{     
    alertme(){
            alert("alert")
            }
    }
...
<child :event="event">
...
export default {
  data() {
    event: false
  },
  methods: {
    simulateEmitEventToChild() {
      this.event = !this.event;
    },
    handleExample() {
      this.simulateEmitEventToChild();
    }
  } 
}
export default {
  props: {
    event: {
      type: Boolean
    }
  },
  watch: {
    event: function(value) {
      console.log("parent event");
    }
  }
}