极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。

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

更多描述

可以实现如下 API

message.info() message.success()

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 101 (opens new window)

Author

回答者: allan-hx (opens new window)

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 (opens new window)

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

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

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

Last Updated: 2/23/2022, 11:56:07 AM