从 Vue.js 中的另一个组件调用方法

Posted

技术标签:

【中文标题】从 Vue.js 中的另一个组件调用方法【英文标题】:Call method from another component in Vue.js 【发布时间】:2018-06-14 22:00:42 【问题描述】:

在这种情况下,如何从另一个组件调用该方法?在组件 1 到组件 2 中单击按钮后,我想从 API 加载额外的数据。

谢谢

这是我在单独文件中的两个组件:

compbutton.vue

<template>
    <div>
        <a href v-on:click="buttonClicked">Change Name</a>
    </div>
</template>

<script>
    export default 
        name: 'compbutton',
        methods: 
            buttonClicked: function () 
                //call changeName here
            
        
    
</script>

compname.vue

<template>
    <div>name</div>
</template>

<script>
    export default 
        name: 'compname',
        data: function () 
            return 
                name: 'John'
            
        ,
        methods: 
            changeName: function () 
                this.name = 'Ben'
            
        
    
</script>

【问题讨论】:

将数据存储在父级中。将该数据作为道具传递给 compname.vue。让 compbutton.vue 在点击时发出一个事件,父级监听该事件。更改父项中的数据。 compname.vue 将收到更新后的值。 你能告诉我我的例子吗? 您可以先尝试执行我的建议吗?之后我很乐意提供帮助。这是相关文档。 vuejs.org/v2/guide/components.html#Passing-Data-with-Props | vuejs.org/v2/guide/… @Ben 是 compbutton.vue 的父组件吗? 【参考方案1】:

您可以命名组件,然后 $ref 从另一个组件到方法。

compbutton.vue

<template>
  <div>
    <a href v-on:click="buttonClicked">Change Name</a>
  </div>
</template>

<script>
export default 
  name: "compbutton",
  methods: 
    buttonClicked: function() 
      //call changeName here
      this.$root.$refs.compname_component.changeName();
    
  
;
</script>

compname.vue

<template>
  <div>name</div>
</template>

<script>
export default 
  name: "compname",
  data: function() 
    return 
      name: "John"
    ;
  ,
  methods: 
    changeName: function() 
      this.name = "Ben";
    
  ,
  created() 
    // set componenent name
    this.$root.$refs.compname_component = this;
  
;
</script>

【讨论】:

【参考方案2】:

另一种答案:您可以将希望子组件调用的函数作为prop来自父组件传递。使用您的示例:

compbutton.vue

<template>
    <div>
        <a href v-on:click="buttonClicked">Change Name</a>
    </div>
</template>

<script>
    export default 
        name: 'compbutton',
        props: 
            clickHandler: 
                type: Function,
                default() 
                    return function () ;
                
            
        ,
        methods: 
            buttonClicked: function () 
                this.clickHandler(); // invoke func passed via prop
            
        
    
</script>

compname.vue

<template>
    <div>name</div>
    <compbutton :click-handler="changeName"></compbutton>
</template>

<script>
    export default 
        name: 'compname',
        data: function () 
            return 
                name: 'John'
            
        ,
        methods: 
            changeName: function () 
                this.name = 'Ben'
            
        
    
</script>

请注意,在您的示例中,它没有出现在您希望渲染“compbutton”组件的位置,因此在 compname.vue 的模板中也添加了它。

【讨论】:

【参考方案3】:

您可以使用服务作为中间人。通常,服务用于共享数据,但在 javascript 中,函数也可以被视为数据。

服务代码很琐碎,只需为函数changeName添加一个存根

changeName.service.js

export default 
  changeName: function () 

要将服务注入到组件中,您需要在项目中包含 vue-injector

npm install --save vue-inject
or
yarn add vue-inject

并且有一个服务的注册,

injector-register.js

import injector from 'vue-inject';

import ChangeNameService from '@/services/changeName.service'

injector.service('changeNameService', function ()  
  return ChangeNameService 
);

然后在main.js(或主文件可能称为index.js)中,初始化注入器的部分。

import injector from 'vue-inject';
require('@/services/injector-register');
Vue.use(injector);

最后将服务添加到组件dependencies数组中,并使用服务

compname.vue

<script>
  export default 
    dependencies : ['changeNameService'],
    created() 
      // Set the service stub function to point to this one
      this.changeNameService.changeName = this.changeName;
    ,
    ...

compbutton.vue

<script>
  export default 
    dependencies : ['changeNameService'],
    name: 'compbutton',
    methods: 
       buttonClicked: function () 
         this.changeNameService.changeName();
       
    
    ...

在按钮 href 中添加 # 以停止页面重新加载

<a href="#" v-on:click="buttonClicked">Change Name</a>

在CodeSandbox中查看全部内容

【讨论】:

确实如此,我倾向于在 Vue 中发现这一点——简单的部分,但在很多地方。注入是官方正确的方法(我觉得有义务展示这种模式),但您可能会发现它也适用于服务的简单导入。不要忘记,注入使单元测试变得容易得多。

以上是关于从 Vue.js 中的另一个组件调用方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从 React.js 中的另一个类组件调用方法

从组件外部调用 Vue.js 组件方法

vue.js(19)--vue中子组件调用父组件的方法

发出的事件不会调用 Vue JS 组件中的父方法

Vue.js 打印原始 html 并调用组件方法

从 vue.js 3 中传递数据的方法渲染组件