vue2封装一个确认框组件

逛掘金社区的一个体验就是经常会打开很多页面。发个沸点也要打开新页面,一点不及时啊。

所以我使用油猴插件实现了在本页面直接打开确认框发沸点的功能。

封装一个确认框组件

js 复制代码
const ConfirmBox = {
  name: 'ConfirmBox',
  props: {
    title: {
      type: String,
      default: '提示',
    },
    content: String,
  },
  render(h) {
    const content = this.$slots.default || this.content;

    return h(
      'div',
      {
        staticClass: 'xx-confirm-box',
      },
      [
        h('div', { staticClass: 'xx-confirm-box-title' }, [
          h('div', { staticClass: 'title' }, this.title),
          h(
            'a',
            { staticClass: 'close', on: { click: this.handleClose } },
            '关闭'
          ),
        ]),
        h('div', { staticClass: 'xx-confirm-box-content' }, [content]),
        h('div', { staticClass: 'xx-confirm-box-footer' }, [
          h('button', { on: { click: this.handleClose } }, '取消'),
          h('button', { on: { click: this.handleConfirm } }, '确认'),
        ]),
      ]
    );
  },
  methods: {
    handleClose(e) {
      this.$emit('close', e);
    },
    handleConfirm(e) {
      this.$emit('confirm', e);
    },
  },
};
scss 复制代码
.xx-confirm-box {
  position: fixed;
  top: 80px;
  left: 0;
  right: 0;
  margin: auto;
  padding: 5px 10px;
  width: fit-content;
  background: #e8f3ff;
  z-index: 2999;
  color: var(--juejin-brand-1-normal);
  border-radius: 5px;
  white-space: pre-wrap;
  line-height: 1.8;
  border: solid 1px;
  
  &-title {
    display: flex;
    justify-content: space-between;
    padding-bottom: 4px;
    .title {
      flex: 1;
      font-weight: 600;
    }
  }
  &-footer {
    margin-top: 10px;
    display: flex;
    button {
      flex: 1;
      &:first-child {
        background-color: #7bbdff;
      }
    }
  }
}

便捷使用方式封装

js 复制代码
const ConfirmBoxConstructor = Vue.extend(ConfirmBox);

export const confirm = (options = {}) => {
  if (typeof options === 'string') options = { content: options };
  const { content, title, onConfirm, onClose } = options;
  let instance;
  const props = { content, title };
  const on = {};
  const close = () => instance.$destroy();
  on.close = onClose ? () => onClose(close) : close;
  on.confirm = onConfirm ? () => onConfirm(close) : close;

  if (typeof content === 'string') {
    instance = new ConfirmBoxConstructor({ propsData: props, on });
  } else {
    const CompConstructor = Vue.extend({
      render: h => h(ConfirmBox, { props, on }, [content]),
    });
    instance = new CompConstructor();
  }

  instance.$on('hook:mounted', () => {
    document.body.appendChild(instance.$el);
  });
  instance.$on('hook:destroyed', () => {
    instance.$el.remove();
  });

  instance.$mount();
};

使用方式

js 复制代码
const content = '每日打卡,从使用今日掘友分油猴插件开始。\nhttps://juejin.cn/post/7280006996572340283';

confirm({
  title: '输入沸点内容',
  content: h(
    'textarea',
    {
      attrs: { rows: '3' },
      style: { width: '300px' },
    },
    content
  ),
  onConfirm: close => {
    close();
    // 发接口
    publishShortMsg(content).then(msg => {
      message('发布一条沸点成功').then(() => {
        window.open(`/pin/${msg.msg_id}`);
      });
    });
  },
});
相关推荐
用户名1231 分钟前
我写了个脚本,让前端彻底告别 Swagger 手动搬砖
前端
爱编程的喵3 分钟前
深入理解JavaScript节流函数:从原理到实战应用
前端·javascript·html
尧木晓晓3 分钟前
开发避坑指南:Whistle 代理失效背后,localhost和 127.0.0.1 的 “爱恨情仇” 与终极解决方案
前端·javascript
风无雨35 分钟前
GO启动一个视频下载接口 前端可以边下边放
前端·golang·音视频
Rainbow_Pearl40 分钟前
Vue2_element 表头查询功能
javascript·vue.js·elementui
aha-凯心1 小时前
前端学习 vben 之 axios interceptors
前端·学习
熊出没2 小时前
Vue前端导出页面为PDF文件
前端·vue.js·pdf
VOLUN2 小时前
Vue3项目中优雅封装API基础接口:getBaseApi设计解析
前端·vue.js·api
此乃大忽悠2 小时前
XSS(ctfshow)
javascript·web安全·xss·ctfshow
用户99045017780092 小时前
告别广告干扰,体验极简 JSON 格式化——这款工具让你专注代码本身
前端