上下文

在Vue 2.0中,文档和其他文档清楚地表明,从父母到孩子的交流是通过道具进行的。

问题

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

我该看个道具节目吗?这感觉不对,替代方法也是如此($emit/$on用于从子到父,而hub模型用于远程元素)。

例子

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


当前回答

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

html:

<div id="app">
  <my-component></my-component>
  <button @click="click">Click</button>  
</div>

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);
    }
  }
})

运行示例:https://jsfiddle.net/rjurado/m2spy60r/1/

其他回答

我认为我们应该考虑父母使用孩子的方法的必要性。实际上,父组件不需要关心子组件的方法,而可以将子组件视为FSA(有限状态机)。父组件来控制子组件的状态。因此,观察状态变化或仅使用计算功能就足够了

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

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

如果要重新加载带有新过滤器的组件,如果按钮单击过滤子组件

reloadData() {            
   this.filter = ['filter1','filter2']
   this.componentKey += 1;  
},

并使用过滤器来触发该函数

您所描述的是父进程状态的变化。你把它通过道具传递给孩子。就像你说的,你会看好那个道具。当子进程执行操作时,它会通过emit通知父进程,然后父进程可能会再次更改状态。

var Child = { template: '<div>{{counter}}</div>', props: ['canI'], data: function () { return { counter: 0 }; }, watch: { canI: function () { if (this.canI) { ++this.counter; this.$emit('increment'); } } } } new Vue({ el: '#app', components: { 'my-component': Child }, data: { childState: false }, methods: { permitChild: function () { this.childState = true; }, lockChild: function () { this.childState = false; } } }) <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script> <div id="app"> <my-component :can-I="childState" v-on:increment="lockChild"></my-component> <button @click="permitChild">Go</button> </div>

如果您确实希望将事件传递给子节点,可以通过创建一个总线(它只是一个Vue实例)并将其作为道具传递给子节点来实现。

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

html:

<div id="app">
  <my-component></my-component>
  <button @click="click">Click</button>  
</div>

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);
    }
  }
})

运行示例:https://jsfiddle.net/rjurado/m2spy60r/1/

Vue 3组合API

为子组件创建一个ref,在模板中赋值它,并使用<ref>. ref。值直接调用子组件。

<script setup>
import {ref} from 'vue';

const childComponentRef = ref(null);

function click() {
  // `childComponentRef.value` accesses the component instance
  childComponentRef.value.doSomething(2.0);
}
</script>

<template>
  <div>
    <child-component ref="childComponentRef" />
    <button @click="click">Click me</button>
  </div>
</template>

有几件事需要注意

如果你的子组件使用<script setup>,你需要使用defineExpose声明公共方法(例如上面的doSomething)。 如果你使用的是Typescript,详细的注释方法在这里。

Vue 3 Options API / Vue 2

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

html:

<div id="app">
  <child-component ref="childComponent"></child-component>
  <button @click="click">Click</button>  
</div>

javascript:

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);
    }
  }
})

有关更多信息,请参阅Vue 3文档中的组件参考或Vue 2文档中的参考。