Vue API - extend 开发消息弹窗组件

栏目: JavaScript · 发布时间: 6年前

内容简介:通常情况使用vue时都是挂在某个节点下,例如:App.vuemain.js

通常情况使用vue时都是挂在某个节点下,例如:

App.vue

<body>
    <div id="app"></div>
</body>
复制代码

main.js

import Vue from "vue";
import App from "./App.vue";
new Vue({
  render: h => h(App)
}).$mount("#app");
复制代码

借助webpack vue-loader App.vue将会导出成一个对象App,h函数将App数据渲染成节点再挂载到#app节点下。至此所有页面操作都在该节点下,包括路由跳转等等。

但是有时候我们也可能需要将节点挂载在其他位置,而非#app上,或者说需要多个可以挂载vue的节点。

例如我们需要开发一个类似element-ui的通知组件

Vue API - extend 开发消息弹窗组件

这个组件有着如下特点:

  • 页面每个地方都可能使用到,不可能每个页面都写alert组件
<!--这里假设组件名称为alert-->
<alert :show="isShow"></alert> 
复制代码

我们需要的是这样调用组件:

this.$Alert({content:'hello',duration:2})
复制代码
  • 组件的位置需要fix定位,为避免这个组件被其他元素遮住,最理想的情况是这样的:
<body>
    <!-- vue渲染区域-->
    <div id="app"></div>
    <!--alert组件渲染区,并且为fixed定位-->
    <div class="alert"></div>
</body>
复制代码

所以我们需要第二个区域使用vue了,Vue提供了extend API 可以拓展vue实例。 例如在main.js中

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");

const Tips = Vue.extend({
    template: `<h1>{{message}}</h1>`,
       data() {
         return {
           message: "hello,world"
         };
       }
});
const comp = new Tips().$mount();
document.body.appendChild(comp.$el);
复制代码

上述代码即可在渲染出第二块区域h1,在h1内一样可以使用vue

所以开发思路如下:

  1. this.$Alert({}) 调用时new一个Vue 并通过render函数渲染出一个alert组件。
  2. 通过Vue.extend和$mounted挂载上去

main.js 注册$Alert()

import { info } from "./components/alert.js";
Vue.prototype.$Alert = info;
复制代码

alert.js

import Vue from "vue";
import Alert from "./alert.vue";

// 向Alert组件传递data数据
export const info = options => {
  const Instance = new Vue({
    render(h) {
      return h(Alert, {
        props: options
      });
    }
  });
  const comp = Instance.$mount();
  document.body.appendChild(comp.$el);
  const alert = Instance.$children[0];
  alert.add(options);
};

复制代码

alert.vue

<template>
  <div class="alert">
    <div class="alert-main" v-for="item in notices" :key="item.name">
      <div class="alert-content">{{ item.content }}</div>
    </div>
  </div>
</template>
<script>
import { setTimeout } from "timers";
let seed = 0;
function getUuid() {
  return `alert_${seed++}`;
}
export default {
  data() {
    return {
      notices: []
    };
  },
  methods: {
    add(notice) {
      const uuid = getUuid();
      let _notice = Object.assign({ name: uuid }, notice);
      this.notices.push(_notice);
      const { duration } = _notice; 
      setTimeout(() => {
        this.remove(_notice.name);
      }, duration * 1000);
    },

    remove(name) {
      alert(name);
      const notices = this.notices;
      for (let i = 0; i < notices.length; i++) {
        if (notices[i].name === name) {
          this.notices.splice(i, 1);
          break;
        }
      }
    }
  }
};
</script>
<style>
.alert {
  position: fixed;
  width: 100%;
  top: 16px;
  left: 0;
  text-align: center;
  pointer-events: none;
}
.alert-content {
  display: inline-block;
  padding: 8px 16px;
  background: #fff;
  border-radius: 3px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
  margin-bottom: 8px;
}
</style>
复制代码

具体页面使用:

this.$Alert({
    content: "这是一条提示信息",
    duration: 3
});
复制代码

一个最原始的alert组件就实现了,后续可自行优化!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mission Python

Mission Python

Sean McManus / No Starch Press / 2018-9-18 / GBP 24.99

Launch into coding with Mission Python, a space-themed guide to building a complete computer game in Python. You'll learn programming fundamentals like loops, strings, and lists as you build Escape!, ......一起来看看 《Mission Python》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具