【问题标题】:Call method from another component in Vue.js从 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 的父组件吗?

标签: vue.js vuejs2 components


【解决方案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 中发现这一点——简单的部分,但在很多地方。注入是官方正确的方法(我觉得有义务展示这种模式),但您可能会发现它也适用于服务的简单导入。不要忘记,注入使单元测试变得容易得多。
      猜你喜欢
      • 2016-05-22
      • 2020-04-05
      • 2017-08-16
      • 2016-07-14
      • 2019-06-16
      • 2022-01-25
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      相关资源
      最近更新 更多