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}`);
      });
    });
  },
});
相关推荐
禅思院1 小时前
前端部署“三层漏斗”完全指南:从CI/CD到自动回滚的工程化实战【开题】
前端·架构·前端框架
快乐肚皮1 小时前
深入理解Loop Engineering
前端·后端
半个落月2 小时前
从递归到快速排序:用 JavaScript 把分治思想讲明白
javascript·算法·面试
风骏时光牛马2 小时前
VHDL十大经典基础功能设计实例代码合集
前端
小兔崽子去哪了2 小时前
Vue3 + Pinia 集成 IGV.js 实现 BAM 文件在线浏览
javascript·vue.js·后端
hunterandroid2 小时前
Notification 通知:从基础到渠道适配
前端
孟陬2 小时前
Claude Code 巧思 `Ctrl+S` 暂存键
前端·后端
PedroQue992 小时前
V1.6.1性能优化:高频路径提速与代码精简
前端·uni-app
猩猩程序员2 小时前
将 LiteLLM 迁移到 Rust —— 构建最快、最轻量的 AI Gateway
前端
小月土星2 小时前
JavaScript 快速排序:从 pivot、双指针到分治思想
javascript·算法·面试