侧边栏壁纸
博主头像
不会水的鱼 博主等级

人生就是白干加白干!

  • 累计撰写 4 篇文章
  • 累计创建 4 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
Vue

tiptap编辑器实现分页效果

shmily1214
2026-02-28 / 0 评论 / 0 点赞 / 3 阅读 / 0 字

前言

项目中使用tiptap编辑器实现在线报告的功能,由于业务需要,每一页内容都是有固定的模板的,所以每一页的内容不会超出,后台返回的报告内容就是一个数组,基于此数据结构实现类似于word的一样的分页效果,如果内容不是类似结构或者每页内容不确定的不适合此方法。

解决方法

一开始想用纯样式去控制,后面发现有点复杂,最后决定增加一个类似于page的扩展实现这个功能。扩展的代码如下:

export const PageParagraph = Node.create({
  name: 'PageParagraph',
  content: 'block*',
  priority: 1000,
  group: 'block',
  atom: false,
  draggable: false,
  addAttributes() {
    return {
      class: '',
      id: '',
      contenteditable: false
    };
  },
  parseHTML() {
    return [
      {
        tag: 'pp'
      },
    ];
  },
  renderHTML({ HTMLAttributes }) {
    return ['div', mergeAttributes(HTMLAttributes, { contenteditable: HTMLAttributes.contenteditable }), 0];
  }
});

priority 是扩展的优先级,必须要大于其他扩展的优先级才能优先加载,包括默认扩展和自定义扩展。同时给它设置了几个属性,class是用于控制竖版和横版的页面的样式;节点取名叫pp,后续就可以在代码中使用这个标签了:

const totalContent = pages.reduce((prev, next, i) => {
  const isHorizontal = pages[i].layout === 'horizontal';
  const wrapper = `<pp id="page-${i}" class="${isHorizontal ? 'horizontal-page' : 'vertical-page'}" draggable=false contenteditable=${!docReadOnly}>`;
  const content = (wrapper + (next.content || '') + '</pp>');
  return prev + content;
}, '');

pages是所有页面的内容数组,docReadOnly用于控制编辑器是否可以编辑,最后得到的totalContent就是处理完的内容,直接使用editor.setContent方法设置新的内容就行了。接下来是页面的css:

  .vertical-page {
    width: calc(8.27in - 2.54cm);
    height: calc(11.7in - 4.08cm);
    padding: 2.04cm 1.27cm;
    position: relative;
    background-color: #ffffff;
    overflow: clip;
  }
  .horizontal-page {
    width: calc(11.7in - 2.54cm);
    height: calc(8.27in - 4.08cm);
    padding: 2.04cm 1.27cm;
    position: relative;
    background-color: #ffffff;
    overflow: clip;
  }
  .vertical-page,
  .horizontal-page {
    margin: auto;
    box-shadow: 0px 0px 8px 2px rgb(0 0 0 / 10%);
  }
  .horizontal-page+.horizontal-page,
  .horizontal-page+.vertical-page,
  .vertical-page+.horizontal-page,
  .vertical-page+.vertical-page {
    margin-top: 15px;
  }

效果如下:

example.gif

最后 如果需要保存编辑器内容的话需要手动把新增的pp节点去除哦!

0
vue

评论区