高级前端vue【Q100】如何使用 react/vue 实现一个 message API

如何使用 react/vue 实现一个 message API

更多描述 可以实现如下 API

message.info() message.success()

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 101

Author 回答者: allan-hx

import React from 'react';
import ReactDOM from 'react-dom';
// info组件
import Info from 'info';
// success组件
import Success from 'success';

function createMessage(message, Com) {

  let el = document.createElement('div');

  document.body.appendChild(el);

  const component = React.createElement(Com, {
    message
  });

  ReactDOM.render(component, el);
}

const message = {
  info(message) {
    return createMessage(message, Info);
  },
  success(message) {
    return createMessage(message, Success);
  },
};

export default message;

主要实现思路就是创建一个div到body下,然后利用ReactDOM.render将组件渲染到这个容器下,这只是一个简单的实现,没实现关闭和多次调用

Author 回答者: wizzeng

Vue 实现也是差不多,可以先写好一个 render 函数,作用是把某一HTML片段挂载到 #root 下 / 从 #root 删除该片段。然后写一个 Vue 插件,就是一个暴露了包含 install 方法的模块,install 方法中将 设置 Vue.prototype.$message = message 对象。最后使用 Vue.use 全局注册这个插件即可。

Author 回答者: HuiFeiYa

// alert.js
import Alert from './alert.vue'
import Vue from 'vue'
// 创建构造器
const InstanceAlert = Vue.extend(Alert)

export default class Message {
  deaultOptions = {
    el: document.createElement('div')
    propsData: {
      title: '标题'
    }
  }
  instance = {}
  constructor (options) {
    options = Object.assign({},options,this.deaultOptions)
    this.instance = new InstanceAlert(options)
  }
  show() {
    document.body.appendChild(this.instance.$el)

  }
  hide() {
    document.body.removeChild(this.instance.$el)
  }
}
// alert.vue
<template>
  <div id="alert-mount">
    这里是{{ title }}
  </div>
</template>

<script>
  export default {
    props:{
      title:{
        type:String,
        default:""
      }
    }
  }
</script>

Author 回答者: Drowned-fish

用createPortal会好点,符合createPortal的使用场景并且如果message复杂点createElement就用不了