是否可以从页面调用nuxt中的组件方法?

Jav*_*ina 4 vue.js nuxt.js

我开始使用 Vue.js,我正在使用 Nuxt.js。我创建了一个组件(小吃店),在这个组件中我创建了一个方法“showSnackbar”,它可以传递 2 个参数:颜色和文本。所以当我调用 showSnackbar(color,text) 时,它就会出现。

但是,我想从页面调用这个方法。因为我想在一些页面中使用这个snackbar,而且我不想一直写相同的代码,所以这就是我决定创建一个组件的原因。但是我无法从页面调用此组件内的方法。

这就是为什么我想知道是否可以从页面调用组件方法(当然我在其中导入组件)

Law*_*one 5

可能有几种方法可以做到,我会创建一个插件

然后您拥有<snackbar/>用于放置的组件和用于调用调用方法的全局 APIthis.$snackbar.open({someOptions: '...'})

例如:

在其中创建一个文件夹./plugins/snackbar并将以下内容放入:

./plugins/snackbar/index.js

import Vue from "vue";
import snackbar from "~/plugins/snackbar/snackbar";

Vue.use(snackbar);
Run Code Online (Sandbox Code Playgroud)

这是为了nuxt.config.js, 全局加载。看起来像:

  ...
  /*
   ** Plugins to load before mounting the App
   ** Doc: https://nuxtjs.org/guide/plugins
   */
  plugins: ["~/plugins/snackbar/index.js"],
  ...

Run Code Online (Sandbox Code Playgroud)

好的,现在创建

./plugins/snackbar/snackbar.js

这是保持组件状态并充当事件代理的插件

import snackbar from "~/plugins/snackbar/snackbar.vue";

const Plugin = {
  install(Vue, options = {}) {
    /**
     * Makes sure that plugin can be installed only once
     */
    if (this.installed) {
      return;
    }
    this.installed = true;

    /**
     * Create event bus
     */

    this.event = new Vue();

    /**
     * Plugin methods
     */
    Vue.prototype.$snackbar = {
      show(options = {}) {
        Plugin.event.$emit("show", options, true);
      }
    };

    /**
     * Registration of <snackbar/> component
     */
    Vue.component("snackbar", snackbar);
  }
};

export default Plugin;
Run Code Online (Sandbox Code Playgroud)

现在...

./plugins/snackbar/snackbar.vue

奇迹发生的地方...

<template>
  <div>
    <transition name="snackbar">
      <div v-if="show" :class="['snackbar', 'box-shadow', type]">
        <slot>{{ options.text }}</slot>
      </div>
    </transition>

    <pre>options: {{ options }}</pre>
    <pre>show: {{ show }}</pre>
    <pre>type: {{ type }}</pre>
  </div>
</template>

<script>
import snackbar from "~/plugins/snackbar/snackbar";

export default {
  data: () => ({
    options: {
      text: "",
      type: ""
    },
    show: false,
    type: "",
    timer: 0
  }),
  beforeMount() {
    snackbar.event.$on("show", options => {
      this.options = options;
      this.type = options.type;
      this.show = true;
      this.close(this.options.closeWait || 3000);
    });
  },
  methods: {
    close(timeout) {
      clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.show = false;
      }, timeout);
    }
  }
};
</script>

<style>
.snackbar {
  min-width: 300px;
  margin-left: -150px;
  background-color: #F48024;
  color: #fff;
  text-align: center;
  border-radius: 5px;
  padding: 16px;
  position: fixed;
  z-index: 1;
  left: 50%;
  bottom: 30px;
}

.snackbar.success {
  background-color: rgb(71, 244, 36);
}

.snackbar.danger {
  background-color: rgb(244, 36, 47);
}

.snackbar-enter-active {
  animation: snackbar-in 0.8s;
}
.snackbar-leave-active {
  animation: snackbar-in 0.8s reverse;
}
@keyframes snackbar-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.box-shadow {
  -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
    0 0 40px rgba(0, 0, 0, 0.1) inset;
  -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
    0 0 40px rgba(0, 0, 0, 0.1) inset;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
</style>
Run Code Online (Sandbox Code Playgroud)

然后在使用它的任何组件/页面中,您可以放置​​ with <snackbar/>,并调用如下方法:

this.$snackbar.show({
  text: "Hello, snackbar!",
  type: "success"
});
Run Code Online (Sandbox Code Playgroud)

可以在此处找到上述工作示例https://codesandbox.io/s/codesandbox-nuxt-oeo4h