Javascript 如何在Vue中的不相关组件之间共享方法?

Javascript 如何在Vue中的不相关组件之间共享方法?,javascript,vue.js,Javascript,Vue.js,我可能缺少VueJS的一些概念,所以我需要这方面的帮助。为了使我的问题更清楚,我做了一个简短的回答。假设我有一些多用途的组件,比如窗户。我正在从Vuex获取数据 /components/modal.vue <script> export default { methods: { modalClose() { this.$store.commit("modalClose"); }, }, computed: { bod

我可能缺少VueJS的一些概念,所以我需要这方面的帮助。为了使我的问题更清楚,我做了一个简短的回答。假设我有一些多用途的组件,比如窗户。我正在从Vuex获取数据

/components/modal.vue

<script>
export default {
  methods: {
    modalClose() {
      this.$store.commit("modalClose");
    },
  },
  computed: {
    body() {
      return this.$store.state.modal.body;
    },
    footer() {
      return this.$store.state.modal.footer;
    },
    show() {
      return this.$store.state.modal.show;
    },
  },
};
</script>

<template>
  <div class="wrap" @click.self="modalClose" v-if="show">
    <div id="modal" class="modal">
      <div class="modal-body" v-html="this.body">body</div>
      <div class="modal-footer" v-html="this.footer">footer</div>
    </div>
  </div>
</template>

<style>
/* whatever */
</style>

<script>
export default {
  data: function () {
    return {
      persons: [
        { name: "John Johnson", id: 1 },
        { name: "David Lynch", id: 2 },
        { name: "Marshall Attack", id: 3 },
      ],
    };
  },
  methods: {
    showModal: function (person) {
      this.$store.commit("modal", {
        body: "Name: " + person.name,
        footer: `<a href="#" person-id="${person.id}">Add</a>`,
      });
    },
    addPerson: function (id) {
      // how to trigger this function with "Add" button?
      console.log("Success! Person " + id + " was added!");
    },
  },
};
</script>
<template>
  <div id="page1">
    <div v-for="person in persons" :key="person.id">
      {{ person.name }}
      <a href="#" @click="showModal(person)"> Open modal </a>
    </div>
  </div>
</template>

在本例中,您可以看到方法
addPerson
。它属于
persons.vue
,应该通过单击模式窗口内的“添加”按钮来执行(需要参数)。因此,我有两个问题:

  • 我怎么做
  • 我在推广不良行为吗

  • p.S.我读到了关于
    $emit
    的文章,但我没有任何运气。

    我没有完全理解您的问题,但基本思想是各种组件可以将数据提交到您的存储。并向存储区发送操作。并且存储本身应该能够使用已经提交的数据处理像
    addPerson
    这样的操作。通常,在多个组件“创建”条目的情况下,您的存储(或存储模块)将

    • 具有相关条目的状态,例如在一般CRUD中,它通常是存储临时条目的
      人员
      新人
      数组
    • 允许编辑某些数据的突变
    • 一个getter
      canAddPerson
      ,它计算
      newPerson
      对象中是否有足够的数据来实际创建一个新的person
    • 使用
      newPerson
      的操作
      addPerson
      ,可以选择执行AJAX POST,提交要包含在人员数组中的新人员,并清除
      newPerson
      字段
    我偶尔会遇到的一个警告是,这个
    newPerson
    不应该是
    {}
    ,而是应该用所有字段定义
    {name:null,height:null,…}
    ,否则这些字段将不会是被动的

    我在推广不良行为吗

    您不应该将HTML放在存储中,而应该将数据放在存储中

    另外,标题中问题的答案是“混合”,但我不认为这是你在问题正文中提出的问题。

    看起来很糟糕

    通常: modal.vue以个人身份进入。vue 然后,在数据属性中,模式显示后必须为false(modalShow:false)


    如果显示带有选定数据的模态,则必须向模态组件发送“道具”。

    这里有很多给猫换皮的方法

  • 模态组件将自己的数据写入存储
  • 因为模式已经从存储中读取了数据,所以您也可以直接从模式中设置存储值。创建一个执行此操作的新方法。这里的好处是model可以读取和写入自己的数据。缺点是模式现在与应用程序中的特定类型的数据绑定,并且通常不可重用

  • 来自
    persons.vue
    和:
  • 当某个事件发生时,例如当用户单击“添加”时,您的模式应
    $emit
    。无论您在何处定义了该链接,请向其添加
    @单击=“$emit('add',whateverDataYouWantToReturn)”
    。然后在父组件中,当您使用模式时,使用
    @add=“addPerson($event)”
    侦听事件。这里的好处是你不一定需要使用商店;您可以将数据作为
    props
    传递到模式,并使用
    $emit
    捕捉事件

  • 在模态上使用a:

  • 无论何时在父模板中使用模态,都可以在模态中插入所需的任何可视内容,就像提供给模态的插槽一样。这样做的好处是,可以保持模态组件的可重用性,同时还允许您调用父级上的方法。

    实际上,我考虑过它,但后来我阅读了引导文档,其中指出:Modals使用position:fixed,这在渲染时可能有点特殊。只要有可能,将模态HTML放在顶层位置,以避免来自其他元素的潜在干扰。在另一个固定元素中嵌套.modal时可能会遇到问题。“”在另一个固定元素中嵌套.modal时可能会遇到问题。“这不是为了地位。模态必须在父组件内。如主组件->模态组件。所以数据钩子必须是主要的模态和道具。研究Vue文档中的道具然后在您了解meSorry之后,我是Vue新手,所以我可能会出错<代码>添加按钮只是按钮的随机名称。我真正想让它了解的是,如何通过在模式窗口内单击来触发
    addPerson
    函数。我想说的是,
    addPerson
    函数应该是您商店中的一个操作(请参阅Vuex操作)。然后您只需在按钮中添加一个
    @click=“$store.dispatch('addPerson')”
    属性,它就会被调用。绝对不要将html放入存储,+1我可以阅读任何约定来了解更多信息吗?我分叉了演示代码并实现了您的第一个建议,如下所示:在这个实现中,我将模态窗口的按钮作为对象存储在Vuex存储中,并使用
    handleClick
    方法收听
    modal.vue
    中的单击事件。这就是你的意思吗?它的功能有限,但可以正常工作。此外,我不知道在这种情况下如何使用
    插槽
    (建议3)。我特别指出,两个(或更多)组件假定是不相关的。您在
    footer
    computed属性中做了大量不必要的工作,可以直接在模板中使用
    v-for
    轻松处理这些工作。只需将
    @click=”“
    直接添加到使用
    v-for
    呈现的元素中。带插槽的组件非常适合包装需要父范围的通用/无关内容。e、 g.您的模式模板可以是
    ,让家长将其与
    您的内容一起使用