修改大佬的代码,原来是可以修改参数的,我这边要求不能手动修改参数

增加删除功能,自定义添加参数,

反向解析公式没整好,有大佬会的,可以修改一下,联系一下我,不胜感激

原文  用vue手写一个公式组件 - SegmentFault 思否

后来进行了改进 功能进行了简化 ,可详见vue公式编辑器 加强版(简化版)_你好,我叫A某人的博客-CSDN博客_vue公式编辑器

<template><div id="formulaPage"><h1>formulaPage</h1><p>{{ formulaStr }}</p><div class="btnGroup"><!-- <button @click="mouseRange($event)">获取光标</button> --><button @click="getFormula">获取公式</button><button@click="parsingFormula('#字段1#+plus(#字段1#+#字段3#)*abs(#字段4#/#字段2#)')">反向解析公式</button></div><!-- <div class="tab"><div class="tit">添加公式</div><ul><li @click="addItem($event, 2)">plus()</li><li @click="addItem($event, 2)">abs()</li></ul></div> --><div class="tab"><div class="tit">添加字段</div><ul><li @click="addItem($event, 1)">字段1</li><li @click="addItem($event, 1)">字段2</li><li @click="addItem($event, 1)">字段3</li><li @click="addItem($event, 1)">字段4</li></ul></div><div class="tab"><div class="tit">数字</div><ul><li @click="addItem($event, 3)">1</li><li @click="addItem($event, 3)">2</li><li @click="addItem($event, 3)">3</li><li @click="addItem($event, 3)">4</li><li @click="addItem($event, 3)">5</li><li @click="addItem($event, 3)">6</li><li @click="addItem($event, 3)">7</li><li @click="addItem($event, 3)">8</li><li @click="addItem($event, 3)">9</li><li @click="addItem($event, 3)">0</li></ul></div><div class="tab"><div class="tit">数学运算符</div><ul><li @click="addItem($event, 3)">+</li><li @click="addItem($event, 3)">-</li><li @click="addItem($event, 3)">*</li><li @click="addItem($event, 3)">/</li><li @click="addItem($event, 3)">(</li><li @click="addItem($event, 3)">)</li><li @click="remove()">del</li></ul></div><!-- 公式编辑区域 --><divclass="formulaView"id="formulaView"ref="formulaView"@click="recordPosition"@keyup="editEnter($event)"@copy="copy($event)"@paste="paste($event)"contentEditable="false "></div></div>
</template>
<script>
export default {name: "formulaPage",data: function () {return {// 公式字符串formulaStr: "",// 公式编辑器最后光标位置formulaLastRange: null,};},methods: {// 获取公式getFormula: function () {var nodes = this.$refs.formulaView.childNodes;var str = "";for (let i = 0; i < nodes.length; i++) {var el = nodes[i];if (el.nodeName == "SPAN") {// console.log(el);str += "#" + el.innerHTML.trim() + "#";} else if (el.nodeName == "B") {// console.log(el);str += el.innerHTML.trim() ;}else {// console.log(el.data);str += el.data ? el.data.trim() : "";}}// console.log(str);this.formulaStr = str;},// 点选时记录光标位置recordPosition: function () {// 保存最后光标点this.formulaLastRange = window.getSelection().getRangeAt(0);},// 添加字段 type 1 字段  2 公式 3 数字或者数字运算符addItem: function (e, type) {// 当前元素所有子节点var nodes = this.$refs.formulaView.childNodes;// 当前子元素偏移量var offset =this.formulaLastRange && this.formulaLastRange.startOffset;// 当前光标后的元素var nextEl =this.formulaLastRange && this.formulaLastRange.endContainer;// 创建节点片段var fd = document.createDocumentFragment();// 创建字段节点  空白间隔节点  公式节点var spanEl = document.createElement("span");spanEl.setAttribute("contentEditable", false);// 标识为新添加元素 用于定位光标spanEl.setAttribute("new-el", true);spanEl.innerHTML = e.target.innerHTML;var spanEl2 = document.createElement("b");// 标识为新添加元素 用于定位光标spanEl2.setAttribute("new-el", true);spanEl2.innerHTML = e.target.innerHTML;var empty = document.createTextNode(" ");var formulaEl = document.createTextNode(" " + e.target.innerHTML + " ");// 区分文本节点替换 还是父节点插入if (nextEl && nextEl.className != "formulaView") {// 获取文本节点内容var content = nextEl.data;// 添加前段文本fd.appendChild(document.createTextNode(content.substr(0, offset) + " "));fd.appendChild(type == 1 ? spanEl : formulaEl);// 添加后段文本fd.appendChild(document.createTextNode(" " + content.substr(offset)));// 替换节点this.$refs.formulaView.replaceChild(fd, nextEl);// 添加前段文本// fd.appendChild(empty);// fd.appendChild(type == 1 ? spanEl : spanEl2);// fd.appendChild(empty);// // 如果有偏移元素且不是最后节点  中间插入节点  最后添加节点// if (nodes.length && nodes.length > offset) {//     this.$refs.formulaView.insertBefore(//         fd,//         nextEl && nextEl.className != "formulaView"//             ? nextEl//             : nodes[offset]//     );// } else {//     this.$refs.formulaView.appendChild(fd);// }} else {// 添加前段文本fd.appendChild(empty);fd.appendChild(type == 1 ? spanEl : spanEl2);fd.appendChild(empty);// 如果有偏移元素且不是最后节点  中间插入节点  最后添加节点if (nodes.length && nodes.length > offset) {this.$refs.formulaView.insertBefore(fd,nextEl && nextEl.className != "formulaView"? nextEl: nodes[offset]);} else {this.$refs.formulaView.appendChild(fd);}}// 遍历光标偏移数据 删除标志var elOffSet = 0;for (let i = 0; i < nodes.length; i++) {let el = nodes[i];// console.log(el,el.nodeName == 'SPAN'&&el.getAttribute('new-el'));if (el.nodeName == "SPAN" && el.getAttribute("new-el")) {elOffSet = i;el.removeAttribute("new-el");}if (el.nodeName == "B" && el.getAttribute("new-el")) {elOffSet = i;el.removeAttribute("new-el");}}// 创建新的光标对象var range = document.createRange();// 光标对象的范围界定range.selectNodeContents(type == 1 ? this.$refs.formulaView : formulaEl);// 光标位置定位range.setStart(type == 1? this.$refs.formulaView: type == 2? formulaEl: formulaEl,type == 1? elOffSet + 1: type == 2? formulaEl.data.length - 2: formulaEl.data.length - 1);// 使光标开始和光标结束重叠range.collapse(true);// 清除选定对象的所有光标对象window.getSelection().removeAllRanges();// 插入新的光标对象window.getSelection().addRange(range);// 保存新光标// this.recordPosition();},remove() {var formulaView = document.getElementById("formulaView");console.log(formulaView);formulaView.removeChild(formulaView.lastElementChild);},// 复制copy: function (e) {// 选中复制内容e.preventDefault();//var selContent = document.getSelection().toString().split("\n")[0];// 替换选中内容e.clipboardData.setData("text/plain", selContent);},// 输入回车editEnter: function (e) {// console.log(e);e.preventDefault();// return '<br/>';// returnif (e.keyCode == 13) {// 获取标签内容 并把多个换行替换成1个var content = this.$refs.formulaView.innerHTML.replace(/(<div><br><\/div>){2,2}/g,"<div><br></div>");// debugger;// 记录是否第一行回车var divCount = this.$refs.formulaView.querySelectorAll("div");// var tE = this.$refs.formulaView.querySelect('div');// console.log(this.$refs.formulaView.childNodes);// console.log(this.$refs.formulaView.querySelectorAll("div"));// 获取当前元素内所有子节点var childNodes = this.$refs.formulaView.childNodes;// 记录当前光标子节点位置var rangeIndex = 0;for (let i = 0; i < childNodes.length; i++) {var one = childNodes[i];if (one.nodeName == "DIV") {rangeIndex = i;}}// console.log(rangeIndex);// debugger;// console.log(content);// 如果有替换则进行光标复位if (divCount.length >= 1) {// 替换回车插入的div标签content = content.replace(/<div>|<\/div>/g,function (word) {// console.log(word);if (word == "<div>") {// 如果是第一行不在替换brreturn divCount.length > 1 ? " " : " <br>";} else if (word == "</div>") {return " ";}});// 更新替换内容,光标复位this.$refs.formulaView.innerHTML = content;// 创建新的光标对象var range = document.createRange();// 光标对象的范围界定为新建的表情节点range.selectNodeContents(this.$refs.formulaView);// 光标位置定位在表情节点的最大长度range.setStart(this.$refs.formulaView,rangeIndex + (divCount.length > 1 ? 0 : 1));// 使光标开始和光标结束重叠range.collapse(true);// 清除选定对象的所有光标对象window.getSelection().removeAllRanges();// 插入新的光标对象window.getSelection().addRange(range);}}// 保存最后光标点this.formulaLastRange = window.getSelection().getRangeAt(0);},// 获取粘贴事件paste: function (e) {e.preventDefault();// var txt=e.clipboardData.getData();// console.log(e, e.clipboardData.getData());return "";},// 公式反向解析parsingFormula: function (formulaStr) {// 渲染视口var view = this.$refs.formulaView;// 反向解析公式var str = formulaStr.replace(/#(.+?)#/g, function (word, $1) {// console.log(word,$1);return "<span contentEditable='false'>" + $1 + "</span>";});// console.log(str,fd.innerHTML);view.innerHTML = str;// this.$refs.formulaView.appendChild(fd);// 创建新的光标对象var range = document.createRange();// 光标对象的范围界定为新建的表情节点range.selectNodeContents(view);// 光标位置定位在表情节点的最大长度range.setStart(view, view.childNodes.length);// 使光标开始和光标结束重叠range.collapse(true);// 清除选定对象的所有光标对象window.getSelection().removeAllRanges();// 插入新的光标对象window.getSelection().addRange(range);// 保存新光标// this.recordPosition();},},
};
</script>
<style lang="less">
#formulaPage {> .tab {> ul {&:after {content: "";display: table;clear: both;}> li {margin-right: 20px;float: left;padding: 0 10px;height: 25px;line-height: 25px;border-radius: 5px;border: 1px solid #000;}}}> .formulaView {margin-top: 20px;min-height: 100px;width: 300px;padding: 5px;border: 2px solid #000;resize: both;overflow: auto;line-height: 25px;span {user-select: none;display: inline-block;margin: 0 3px;height: 20px;line-height: 20px;letter-spacing: 2px;background: #aaa;border-radius: 3px;white-space: nowrap;color: red;&:first-child {margin-left: 0;}}}
}
</style>

vue 一个公式 编辑器 组件相关推荐

  1. 【一个简单的vue公式编辑器组件】

    vue 一个简单的公式编辑器组件 示例 一个基于vue实现数据统计公式的基本功能. 新建一个 formula.vue 组件, 使用 <formula ref="formulaPage& ...

  2. vue中使用kindeditor编辑器_vue富文本编辑器组件vue-quill-edit使用教程

    这篇文章主要为大家详细介绍了vue富文本编辑器组件vue-quill-edit使用教程,具有一定的参考价值,可以用来参考一下. 感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! 之前使用的 ...

  3. excel公式编辑器_职场办公技巧—Word公式编辑器怎么用

    在使用办公软件的时候,Excel是经常使用公式的一个软件,那么Word中有没有公式可以使用呢?其实在Word中有一个非常好用的公式编辑器,你们知道怎么用吗?一起来看看我的公式编辑器怎么用吧!! 首先点 ...

  4. 基于web的在线复杂公式编辑器的实现

    基于web的在线复杂公式编辑器的实现 直接调用word的公式编辑器,关键是解决web调用word,借用word的公式编辑器,解决在线编辑公式的问题.如何在线使用word是关键所在. 由于能力问题没有解 ...

  5. 使用Python书写的公式编辑器

    0 前言 最近在导师的引导下,自己使用python写了一个公式编辑器,这里向大家介绍一下,如果需要的可以拿去使用.对于当下的公式编辑器有很多缺陷,例如MathType,不可以一边写latex代码,一边 ...

  6. animation基础练习源码_用vue简单写一个音乐播放组件「附源码」

    作者:vipbic 转发链接:https://segmentfault.com/a/1190000022980992 前言 上次小编也分享一个关于Vue 开发过音乐播放对项目: 基于 electron ...

  7. antd picker 使用 如何_如何基于jsoneditor二次封装一个可实时预览的json编辑器组件?(react版)...

    前言 做为一名前端开发人员,掌握vue/react/angular等框架已经是必不可少的技能了,我们都知道,vue或react等MVVM框架提倡组件化开发,这样一方面可以提高组件复用性和可扩展性,另一 ...

  8. 写一个组织架构图组件来深入认识vue函数式高阶组件

    本文涉及到的知识点: Vue函数式组件 递归函数 深拷贝对象 正则匹配 近期在开发一个vue组织架构图组件时,为了实现高性能渲染和一些特殊用法,使用了函数式组件,要实现的效果是这样: 写一个组织架构图 ...

  9. vue树形结构html,怎么在vue中利用递归组件实现一个树形控件

    怎么在vue中利用递归组件实现一个树形控件 发布时间:2021-06-11 17:26:48 来源:亿速云 阅读:81 作者:Leah 本篇文章为大家展示了怎么在vue中利用递归组件实现一个树形控件, ...

  10. javascript --- 利用Sortable实现一个可视化公式编辑器

    Sortable的依赖引入和简单使用参见:https://blog.csdn.net/piano9425/article/details/90437182 先简单的介绍一下可视化公式编辑器的功能(样式 ...

最新文章

  1. SpringCloud微服务云架构构建B2B2C电子商务平台之-(八)消息总线(Spring Cloud Bus)...
  2. QCustomPlot使用手册(二)
  3. NO_CHANGE_ALLOWED error code
  4. MySQL 的索引是什么?怎么优化?
  5. Cocos2dx---------------------添加Admob广告
  6. [转] 如何看透一个人
  7. Tableau+财务领域数据分析+应用
  8. 大学计算机信息技术教程电子书资源,教与学中用好教材《大学计算机信息技术教程》.pdf...
  9. 微信PC版的API接口
  10. 浏览器播放语音SpeechSynthesisUtterance
  11. python做估值模型_理解债券估值中的摊销/摊余成本,利用EXCEL+Python估值建模
  12. 人工智能商业实战应用:金融知识图谱构建与实战【企业内训现场实录】
  13. linux 截屏_如何在Linux上截图
  14. pytorch RuntimeError: size mismatch, m1: [16 x 86016], m2: [25088 x 512] at /opt/conda/conda-bld/pyt
  15. TX2--Tegra架构介绍
  16. 多路视频直播播放器系统框架
  17. error超频 whea win10_win10蓝屏whea_uncorr修复
  18. 基础编程入门题目-Fortran
  19. 每位iOS开发者不容错过的10大有用工具
  20. 江南大学计算机水平怎么样,江南大学在211中什么水平?无锡人眼中的江南大学怎么样?...

热门文章

  1. Php把ts转为mp4,ts格式转换mp4 - 狸窝
  2. 移动端web开发之坑---input内文字与同行文字不对齐问题
  3. js文本框设置必填项_显示隐藏js字段 设置必填非必填
  4. ele input事件 输入后0.5秒触发
  5. HTML - 空链接
  6. 修改计算机照片格式怎么修,电脑上如何修改照片文件大小?2种免费方法简单解决...
  7. python实现 猴子摘香蕉
  8. Cesium 加载实景三维模型 优化建议
  9. jquery boxy插件
  10. 国内外优秀的设计素材网站推荐