【问题标题】:Is it possible to call a component method in nuxt from a page?是否可以从页面调用nuxt中的组件方法?
【发布时间】:2019-12-20 09:54:14
【问题描述】:

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

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

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

【问题讨论】:

    标签: vue.js nuxt.js


    【解决方案1】:

    可能有几种方法可以做到这一点,我会创建一个plugin

    那么你就有了<snackbar/> 用于放置的组件和一个全局API 来调用调用方法this.$snackbar.open({someOptions: '...'})

    例如:

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

    ./plugins/snackbar/index.js

    import Vue from "vue";
    import snackbar from "~/plugins/snackbar/snackbar";
    
    Vue.use(snackbar);
    

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

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

    好的,现在创建

    ./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;
    

    现在……

    ./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>
    

    然后在使用它的任何组件/页面中,您可以使用&lt;snackbar/&gt; 放置,并调用如下方法:

    this.$snackbar.show({
      text: "Hello, snackbar!",
      type: "success"
    });
    

    上面的一个工作示例可以在这里找到https://codesandbox.io/s/codesandbox-nuxt-oeo4h

    【讨论】:

    • 奇迹发生了!谢谢你的回答,很有用。它工作得很好,我学到了一些新东西
    • np,很高兴它有帮助
    猜你喜欢
    • 2021-07-20
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 2012-01-04
    • 2020-01-27
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    相关资源
    最近更新 更多