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 小时前
CSS 和 JS 如何阻塞浏览器渲染 DOM
javascript
c***V3232 小时前
Vue优化
前端·javascript·vue.js
努力往上爬de蜗牛3 小时前
react native真机调试
javascript·react native·react.js
李@十一₂⁰4 小时前
HTML 特殊字体符号
前端·html
y***86695 小时前
TypeScript在Electron应用中的使用
javascript·typescript·electron
小奶包他干奶奶6 小时前
Webpack学习——Loader(文件转换器)
前端·学习·webpack
zy happy7 小时前
若依 vue3 报错:找不到模块“@/api/xxxx/xxxxx”或其相应的类型声明。。Vue 3 can not find mod
前端·javascript·vue.js
潘小安7 小时前
Git Worktree + Claude Code:让你的开发效率翻倍的秘密武器
前端
meichaoWen7 小时前
【Vue3】vue3的全面学习(一)
前端·javascript·学习
小猪努力学前端8 小时前
在 React + React Router v7 SSR 项目里做多端适配,我踩的两个坑
前端·react.js