【问题标题】:Vue JS alert boxVue JS 警告框
【发布时间】:2018-06-07 21:26:59
【问题描述】:

我是 VueJS 的新手。
我用 jquery 写了一个警告框。现在我正在尝试在 VueJS 中提供它。
这是我所做的:

1- 创建了一个名为 NovinAlert.vue 的组件,包括:

<template>
    <div id="novin-alert-container">
        <div v-for="message in messages" class="alert novin-alert" :class="message.class">
            <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
            {{ message.body }}
        </div>
    </div>
</template>
<script>
    export default {
        data: function () {
            return {
                messages: [],
            }
        },
        methods: {
            novinAlert: function (message) {
                let app = this;
                message.type = typeof message.type !== 'undefined' ? message.type : 'info';
                message.class = 'alert' + message.type;
                let index = app.messages.push(message) - 1;
                if (typeof message.duration !== 'undefined') {
                    window.setTimeout(function () {
                        app.messages.splice(index, 1);
                    }, message.duration * 1000);
                }
            }
        }
    }
</script>

2- 我的示例组件是 Dashboard.vue

<template>
    ...
</template>
<script>
    export default {
        mounted() {
            novinAlert('test');
        }
    }
</script>

3- 我的主要布局是:

<body>
    <div id="app">
        <novin-alert></novin-alert>
        <router-view></router-view>
    </div>
</body>

4- 这是我的 app.js

require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router';
window.Vue.use(VueRouter);
import Dashboard from './components/Dashboard.vue';
const routes = [
    {path: '/', component: Dashboard, name: 'dashboard'},
];
import NovinAlert from './components/utils/NovinAlert.vue';
Vue.component('novin-alert', NovinAlert);
const router = new VueRouter({ routes: routes });
const app = new Vue({
    router,
    el: '#app'
});

当我运行仪表板页面时,它不知道novinAlert 功能。
我做错了什么?对于我正在尝试做的事情,最佳做法是什么?
任何帮助表示赞赏。

【问题讨论】:

    标签: javascript jquery vue.js vuejs2 vue-component


    【解决方案1】:

    这就是我最终所做的:
    我在app.js 中创建了一个 Vue 的实例:

    window.eventBus = new Vue();
    

    我使用此活动但有多种用途。每当我需要时,我都会触发(发出)一个事件,并且侦听器会执行所需的操作。

    对于警报框,我发出这样的事件:

    window.eventBus.$emit('alert', {
        text: app.trans('general.error_in_reading_data'),
        type: 'danger',
        duration: 5,
    });
    

    然后我的警报组件的反应是这样的:

    mounted() {
        window.eventBus.$on('alert', (message) => {
            this.novinAlert(message);
        });
    },
    

    【讨论】:

      【解决方案2】:

      您不能从另一个组件访问一个组件的方法。您需要将novinAlert 函数移动到Dashboard 组件并将消​​息作为属性传递给NovinAlert 组件:

      NovinAlert.vue

      <template>
          <div id="novin-alert-container">
              <div v-for="message in messages" class="alert novin-alert" :class="message.class">
                  <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
                  {{ message.body }}
              </div>
          </div>
      </template>
      <script>
          export default {
             props: ['messages']
          }
      
      </script>
      

      Dashboard.vue

      <template>
          <!-- pass the messages prop to the component -->
          <novin-alert :messages="messages"></novin-alert>
      </template>
      <script>
          export default {
              mounted() {
                  this.novinAlert('test');
              },
       data() {
          return {
              messages: []
          }
       },
       methods: {
                  novinAlert: function (message) {
                      let app = this;
                      message.type = typeof message.type !== 'undefined' ? message.type : 'info';
                      message.class = 'alert' + message.type;
                      let index = app.messages.push(message) - 1;
                      if (typeof message.duration !== 'undefined') {
                          window.setTimeout(function () {
                              app.messages.splice(index, 1);
                          }, message.duration * 1000);
                      }
                  }
              }
          }
      </script>
      

      如果你想要应用级别的novin警报,你需要将函数传递给应用组件

      【讨论】:

      • 谢谢胖子。我不认为这是一个好主意。因为我在许多其他组件中都需要这个功能。在每个组件中都复制它是不好的。我认为@divine 所说的在其他组件中导入组件可能是一个更好的解决方案。你怎么看?
      • 把它放在一个单独的模块(js 文件)中,然后在你需要的地方导入它。或使用混合:vuejs.org/v2/guide/mixins.html
      【解决方案3】:

      我现在用 Vuejs 2.* 设计了一个 SIMPLE 弹出窗口,它运行良好。
      在此示例中,弹出窗口作为本地组件包含在内。这将是要遵循的最佳做法之一。让我知道这是否有帮助。

      App.vue

      <template>
        <div>
          <div>Main page</div>
          <button @click="openpopup">Open popup</button>
          <popup :popupData="popupData" ></popup>
        </div>
      </template>
      <script>
        import Popup from'./Popup.vue';
        export default {
          components:{
            "popup" : Popup
          },
          data() {
            return {
              popupData : {
                "header" : "My popup",
                "body" : "hello world",
                "footer" : "divine inc.",
                "display" : "none"
              }
            }
          },
          methods : {
            openpopup(){
              this.popupData.display = "block";
            }
          },
          mounted(){
            this.popupData.display = "block";
          }
        }
      </script>
      

      Popup.vue

      <template>
        <div id="popup" :style="{display : popupData.display}">
            <div class="inner">
              <div class="header">
                  <div>{{popupData.header}}</div>
                  <div @click="closeFunction">Close</div>
              </div>
              <div class="body">{{popupData.body}}</div>
              <div class="footer">{{popupData.footer}}</div>
            </div>
        </div>
      </template>
      <script>
      export default {
          props : ["popupData"],
          methods : {
              closeFunction(){
                  this.popupData.display = "none";
              }
          }
      }
      </script>
      
      <style>
      html,body{
          padding: 0;
          margin:0;
      }
      #popup{
          position: absolute;
          width: 100%;
          height :100%;
          top: 0;
      }
      #popup .inner{
          background-color: green;
          position: inherit;
          top: 10%;
          left: 39%;
          width: 300px;
      }
      #popup .inner div{
          text-align: left;
      }
      #popup .inner .header{
          display: flex;
          justify-content: space-between;
      }
      </style>
      

      【讨论】:

      • 谢谢@divine。您的意思是在我想使用的任何组件中导入警报组件而不是将警报组件设为全局以便所有组件都可以使用它更好?这不会使代码变湿(而不是干)吗?
      • @AliFarhoudi 您可能需要针对您网站中的不同场景重复使用相同的 AlertPopup 功能。并且不同的场景可能需要在弹出窗口中使用不同的文本消息,并且某些页面可能不需要弹出窗口。如果是这种情况,那么我个人认为,使用弹出组件作为本地组件会是一种更好的方法
      • 您已经在组件中定义了openPopUp 函数。但我不想那样做。我想在另一个组件中调用方法。我尝试了您的代码,但无法调用 app.vue 的已安装部分中 popup.vue 中定义的方法。
      • @AliFarhoudi 你为什么要这么做?
      • @AliFarhoudi 我建议将处理后的原始数据传递给 Popup.vue 等组件。从而变得轻量级,实现低耦合
      猜你喜欢
      • 2020-05-28
      • 2022-01-09
      • 2017-09-09
      • 1970-01-01
      • 2019-02-12
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      相关资源
      最近更新 更多