vue实现公式编辑器组件

实现方式一

1、效果图

2、实现代码 

组件弹框实现 样式自己调整  公式的数字与汉字元素、符号 建立元素表 动态获取

完整代码(calculate.vue)

<template><div id="formulaPage"><divref="formulaView"class="formulaView"contentEditable="false"@click="recordPosition"@keyup="editEnter($event)"@copy="copy($event)"@paste="paste($event)"/><div class="infomationContent"><div class="infomationContent-leftFlexbox"><div class="tab"><ul style="width: 200px"><liv-for="(v, i) in Num":key="i"class="numberClass":style="{ background: v.backgroundColor }"@click="addItem($event, 2, v, false)">{{ v.displayValue }}</li></ul></div><div class="tab"><ul style="width: 500px"><liv-for="(v, i) in customType":key="i"class="typeClass":style="{ background: v.backgroundColor }":class="{ noclick: v.isFlag }"@click="addItem($event, 2, v, v.isFlag)">{{ v.displayValue }}</li></ul></div><div class="tab"><ul style="width: 200px"><liv-for="(v, i) in Symbol":key="i"class="symbolClass":style="{ background: v.backgroundColor }"@click="addItem($event, 2, v, false)">{{ v.displayValue }}</li></ul></div></div><div class="infomationContent-rightBtnbox"><div class="imgboxinfo" style="margin-bottom: 32px"><img src="@/assets/images/rolback.png" alt="" style="width: 40px; height: 40px" @click="deleteHumerText" /></div><div class="imgboxinfo"><img src="@/assets/images/calSave.png" alt="" style="width: 40px; height: 40px" @click="onSaveformulaEvent" /></div></div></div><!-- <div class="footerComtent"><el-button type="primary" style="width: 200px; height: 30px" @click="onSaveformulaEvent">保存</el-button></div> --><!-- <button @click="parsingFormula('(长+宽+高)*2')">反向解析公式</button> --><!-- <button @click="deleteHumerText()">删除</button> --></div></template><script>export default {name: 'FormulaPage',props: {content: { type: String, default: '' },recoverdate: {type: Array,default: () => []},domflag: {type: String,default: ''}},data() {return {// 权限分类 元素分类不可用集合btnsRuleArray: {offer: ['thickness', 'nailmouth', 'bellsocket', 'gramweight'], // 报价weight: ['thickness', 'unitprice'], // 重量areavolume: ['gramweight', 'unitprice'] // 体积、面积、纸宽、纸长},// 公式字符串formulaStr: '',// 公式编辑器最后光标位置formulaLastRange: null,Num: [{"displayValue":"1","saveValue":"1"},{"displayValue":"2","saveValue":"2"},{"displayValue":"3","saveValue":"3"},{"displayValue":"4","saveValue":"4"},{"displayValue":"5","saveValue":"5"},{"displayValue":"6","saveValue":"6"},{"displayValue":"7","saveValue":"7"},{"displayValue":"8","saveValue":"8"},{"displayValue":"9","saveValue":"9"},{"displayValue":"0","saveValue":"0"},{"displayValue":".","saveValue":"."}],Symbol: [{"displayValue":"+","saveValue":"+"},{"displayValue":"-","saveValue":"-"},{"displayValue":"x","saveValue":"*"},{"displayValue":"÷","saveValue":"/"},{"displayValue":"(","saveValue":"("},{"displayValue":")","saveValue":")"},{"displayValue":"{","saveValue":"{"},{"displayValue":"}","saveValue":"}"},],customType: [{"displayValue":"上报产量","saveValue":"report_production"},{"displayValue":"实际产量","saveValue":"reality_production"},{"displayValue":"红矿","saveValue":"red_ore"},{"displayValue":"青堆","saveValue":"black_stack"},{"displayValue":"红堆","saveValue":"red_stack"},{"displayValue":"煤存","saveValue":"coal_storage"},{"displayValue":"槽存","saveValue":"slot_storage"},{"displayValue":"土耗","saveValue":"soil_used"},{"displayValue":"土存","saveValue":"soil_stock"},{"displayValue":"煤耗","saveValue":"coal_used"},{"displayValue":"产量","saveValue":"production"},{"displayValue":"用电量","saveValue":"meter_used"}],backFormulaStrArray: [] // 按键值存储编辑器数据}},created() {this.backFormulaStrArray = []if (this.recoverdate) {this.backFormulaStrArray = this.recoverdatethis.$nextTick(function () {this.parsingFormulaCustom(this.recoverdate)})}//   this.getList()},methods: {/** 查询所有公式元素 */getList() {listElement({ pageNum: 1, pageSize: 50 }).then(response => {response.rows.forEach(item => {item.isFlag = falseif (this.domflag) {const newLegth = this.btnsRuleArray[this.domflag].filter(e => e == item.saveValue)if (newLegth.length > 0) {item.isFlag = true}}})const numberDate = response.rows.filter(e => {return e.elementType == 'number'}).sort((a, b) => {return a.order - b.order})const formulaElementDate = response.rows.filter(e => {return e.elementType == 'formulaElement'}).sort((a, b) => {return a.order - b.order})const symbolDate = response.rows.filter(e => {return e.elementType == 'symbol'}).sort((a, b) => {return a.order - b.order})this.Num = numberDatethis.Symbol = symbolDatethis.customType = formulaElementDate})},// 删除操作---从最后删除deleteHumerText() {if (this.backFormulaStrArray.length > 0) {this.backFormulaStrArray.splice(-1, 1)while (this.$refs.formulaView.firstChild) {this.$refs.formulaView.removeChild(this.$refs.formulaView.firstChild)}this.backFormulaStrArray.forEach(item => {const fd = document.createDocumentFragment()const empty = document.createTextNode(' ')const formulaEl = document.createTextNode(' ' + item.displayValue + ' ')fd.appendChild(empty)fd.appendChild(formulaEl)fd.appendChild(empty)this.$refs.formulaView.appendChild(fd)// 创建新的光标对象var range = document.createRange()// 光标对象的范围界定range.selectNodeContents(formulaEl)// 光标位置定位range.setStart(formulaEl, formulaEl.data.length - 1)// 使光标开始和光标结束重叠range.collapse(true)// 清除选定对象的所有光标对象window.getSelection().removeAllRanges()// 插入新的光标对象window.getSelection().addRange(range)// 保存新光标this.recordPosition()})}},// 保存数据 回调父组件onSaveformulaEvent() {const strParams = this.backFormulaStrArray.map(e => e.saveValue).join('')const strParamsValue = this.backFormulaStrArray.map(e => e.displayValue).join('')const newbackFormulaStrArray = []this.backFormulaStrArray.forEach(item => {const obj = {displayValue: item.displayValue,elementType: item.elementType,saveValue: item.saveValue}newbackFormulaStrArray.push(obj)})this.parsingFormula('')this.$emit('onChangeSuccess', strParams, strParamsValue, newbackFormulaStrArray)this.backFormulaStrArray = []console.log(strParams)console.log(strParamsValue)console.log(newbackFormulaStrArray)// const ifLegal1 = [...strParamsValue].reduce((a, i) => (i === '(' ? a + 1 : a - 1), 0)},isValidate(str) {const inArr = []const arr = str.split('')for (const s of arr) {if (s === '{' || s === '[' || s === '(') {// 入栈inArr.push(s)}if (s === '}' || s === ']' || s === ')') {let tempswitch (s) {case '}':temp = '{'breakcase ']':temp = '['breakcase ')':temp = '('break}// 出栈const out = inArr.pop()if (temp !== out) {return false}}}return true},// 获取公式getFormula: function () {var nodes = this.$refs.formulaView.childNodesvar 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 {// 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 公式addItem: function (e, type, itemRows, isusable) {if (isusable) {e.preventDefault()return false}if (this.backFormulaStrArray.length > 0) {if (itemRows.elementType == 'formulaElement' || itemRows.elementType == 'symbol') {// 检验连续相同两个元素不能重复 符号/元素if (this.backFormulaStrArray[this.backFormulaStrArray.length - 1].displayValue == itemRows.displayValue) {e.preventDefault()return false}// 检验不同元素连续两个不能是用一个类型if (this.backFormulaStrArray[this.backFormulaStrArray.length - 1].elementType == 'formulaElement' &&itemRows.elementType == 'formulaElement') {e.preventDefault()return false}if (this.backFormulaStrArray[this.backFormulaStrArray.length - 1].elementType == 'number' &&itemRows.elementType == 'formulaElement') {e.preventDefault()return false}}if (itemRows.elementType == 'number' && itemRows.saveValue == '.') {if (this.backFormulaStrArray[this.backFormulaStrArray.length - 1].displayValue == itemRows.displayValue) {e.preventDefault()return false}}//  this.backFormulaStrArray.forEach(item => {//         console.log(item.displayValue,itemRows.displayValue)// const reg = RegExp(`(${item.displayValue})\1`, 'g'))// console.log(strParamsValue.match(reg))// })}this.backFormulaStrArray.push(itemRows)const isValiStr = this.backFormulaStrArray.map(e => e.displayValue).join('')if (!this.isValidate(isValiStr)) {this.backFormulaStrArray.splice(-1, 1)e.preventDefault()return false}// 当前元素所有子节点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.innerHTMLvar 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)} else {// 添加前段文本fd.appendChild(empty)fd.appendChild(type == 1 ? spanEl : formulaEl)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 = 0for (let i = 0; i < nodes.length; i++) {const el = nodes[i]// console.log(el,el.nodeName == 'SPAN'&&el.getAttribute('new-el'));if (el.nodeName == 'SPAN' && el.getAttribute('new-el')) {elOffSet = iel.removeAttribute('new-el')}}// 创建新的光标对象var range = document.createRange()// 光标对象的范围界定range.selectNodeContents(type == 1 ? this.$refs.formulaView : formulaEl)// 光标位置定位range.setStart(type == 1 ? this.$refs.formulaView : formulaEl,type == 1 ? elOffSet + 1 : formulaEl.data.length - 1)// 使光标开始和光标结束重叠range.collapse(true)// 清除选定对象的所有光标对象window.getSelection().removeAllRanges()// 插入新的光标对象window.getSelection().addRange(range)// 保存新光标this.recordPosition()},// 复制copy: function (e) {// 选中复制内容e.preventDefault()//var selContent = document.getSelection().toString().split('\n')[0]// 替换选中内容e.clipboardData.setData('text/plain', selContent)},// 输入回车editEnter: function (e) {e.preventDefault()if (e.keyCode == 13) {// 获取标签内容 并把多个换行替换成1个var content = this.$refs.formulaView.innerHTML.replace(/(<div><br><\/div>){2,2}/g, '<div><br></div>')// 记录是否第一行回车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 = 0for (let i = 0; i < childNodes.length; i++) {var one = childNodes[i]if (one.nodeName == 'DIV') {rangeIndex = i}}// 如果有替换则进行光标复位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()},parsingFormulaCustom(arrayDatelist) {arrayDatelist.forEach(item => {// 当前元素所有子节点const nodes = this.$refs.formulaView.childNodes// 当前子元素偏移量const offset = this.formulaLastRange && this.formulaLastRange.startOffset// 当前光标后的元素const nextEl = this.formulaLastRange && this.formulaLastRange.endContainerconst fd = document.createDocumentFragment()const empty = document.createTextNode(' ')const formulaEl = document.createTextNode(' ' + item.displayValue + ' ')if (nextEl && nextEl.className != 'formulaView') {var content = nextEl.datafd.appendChild(document.createTextNode(content.substr(0, offset) + ' '))fd.appendChild(formulaEl)fd.appendChild(document.createTextNode(' ' + content.substr(offset)))this.$refs.formulaView.replaceChild(fd, nextEl)} else {fd.appendChild(empty)fd.appendChild(formulaEl)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 range = document.createRange()// 光标对象的范围界定range.selectNodeContents(formulaEl)// 光标位置定位range.setStart(formulaEl, formulaEl.data.length - 1)// 使光标开始和光标结束重叠range.collapse(true)// 清除选定对象的所有光标对象window.getSelection().removeAllRanges()// 插入新的光标对象window.getSelection().addRange(range)// 保存新光标this.recordPosition()})}}}</script><style lang="scss">#formulaPage {width: 100%;height: 100%;> .formulaView {margin-bottom: 20px;min-height: 130px;width: 100%;padding: 5px;border: 5px solid rgb(198, 226, 255);resize: both;overflow: auto;line-height: 25px;font-size: 20px;span {user-select: none;display: inline-block;/* // margin: 0 3px; */height: 20px;line-height: 20px;/* // letter-spacing: 2px; */border-radius: 3px;white-space: nowrap;&:first-child {margin-left: 0;}}}.footerComtent {margin-top: 20px;display: flex;align-items: center;justify-content: center;}.infomationContent {display: flex;&-leftFlexbox {flex: 1;display: flex;> .tab {flex: 1;> ul {margin: 0;padding: 0;display: flex;flex-wrap: wrap;/* // justify-content: space-between; */&:after {content: '';display: table;clear: both;}> li {/* // margin-right: 20px; */margin: 5px 10px;width: 65px;text-align: center;float: left;padding: 0 10px;height: 30px;line-height: 30px;border-radius: 5px;font-weight: bold;border: 1px solid #fff;list-style-type: none;cursor: pointer;-moz-user-select: none; /* 火狐 */-webkit-user-select: none; /* 谷歌、Safari */-ms-user-select: none; /* IE10+ */user-select: none;user-drag: none;box-shadow: 0px 0px 2px 2px rgba(55, 114, 203, 0.2), /*下面深蓝色立体阴影*/ 0px 0px 6px 1px #4379d0,/*内部暗色阴影*/ 0 -15px 2px 2px rgba(55, 114, 203, 0.1) inset;color: #333333;}> li:hover {color: #fff;/* // color: #409eff; */border-color: #c6e2ff;background-color: #ecf5ff;}> li:active {color: #3a8ee6;border-color: #3a8ee6;outline: none;}.numberClass {width: 40px;}.typeClass {width: 100px}.symbolClass {}.noclick {cursor: not-allowed !important;background: #bcc0c4 !important;color: #e4eaf1 !important;border: none !important;}}}}&-rightBtnbox {width: 50px;padding-top: 10px;box-sizing: border-box;.imgboxinfo {width: 40px;height: 40px;img {cursor: pointer;}}}}}</style>

在父组件中引用即可

实现方式二

 1、效果图

2、实现代码

<!-- 配置计算公式 --><el-dialog title="计算公式配置" :visible.sync="dragOpen" append-to-body :close-on-click-modal="false" width="1050px"><el-form label-width="90px" size="medium"><el-row><el-col :span="24"><el-form-item label="调度指标:"><div style="border: 1px solid #c2ddf8;padding: 5px;"><draggable class="dragArea list-group" :list="indexLists" :group="{ name: 'people', pull: 'clone', put: false }" animation="300"><el-tag v-for="tag in indexLists" :key="tag.id" effect="dark" class="fomula-tag" style="margin-right: 5px;" type="success">{{tag.dictLabel}}</el-tag></draggable></div></el-form-item></el-col><el-col :span="24"></el-col></el-row><el-row><el-col :span="24"><el-form-item label="运算符号:"><div style="border: 1px solid #c2ddf8;padding: 5px;"><draggable class="dragArea list-group" :list="operatorOptions" :group="{ name: 'people', pull: 'clone', put: false }" animation="300"><el-tag v-for="tag in operatorOptions" :key="tag.id" effect="dark" class="fomula-tag" @click="tagClick(tag)" style="margin-right: 5px;background-color: #7c9096;border: none;width: 40px;text-align: center">{{tag.dictLabel}}</el-tag></draggable></div></el-form-item></el-col><el-col :span="24"></el-col></el-row><el-row><el-col :span="24"><el-form-item label="算数符号:"><div style="border: 1px solid #c2ddf8;padding: 5px;"><draggable class="dragArea list-group" :list="nums" :group="{ name: 'people', pull: 'clone', put: false }" animation="300"><el-tag v-for="tag in nums" :key="tag.id" effect="dark" class="fomula-tag" @click="tagClick(tag)" style="margin-right: 5px;background-color: #2bcdff;border: none;width: 40px;text-align: center">{{tag.dictLabel}}</el-tag></draggable></div></el-form-item></el-col><el-col :span="24"></el-col></el-row><el-row><el-col :span="24"><el-form-item label="结果集:"><div style="border: 5px solid #c2ddf8;padding: 5px;position: relative;"><draggable class="list-group" :list="resultR" group="people" animation="300" style="height:100px;" @change="log"><el-tag v-for="tag in resultR" :key="tag.id" effect="dark" @click="tagClick(tag)" closable @close="handleClose(tag)" style="margin-right: 5px;">{{tag.dictLabel}}</el-tag></draggable><el-popover placement="left" title="公式:" trigger="hover" :content="previewFormula"><i class="el-icon-view show-fomula" slot="reference"></i></el-popover></div></el-form-item></el-col><el-col :span="24"><div class="explain">{{explain}}</div></el-col></el-row></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitDrag" v-if="this.confDisabled">保 存</el-button><el-button @click="cancelDrag">取 消</el-button></div></el-dialog>

js方法

import draggable from 'vuedraggable'

​​​​​​​

watch: {'resultR': {handler: function () {this.refreshFormula();}},},methods: {log() {this.refreshFormula();},refreshFormula() {this.previewFormula = "";if (this.resultR !== undefined && this.resultR !== null && this.resultR !== []) {for (let i = 0; i < this.resultR.length; i++) {this.previewFormula += this.resultR[i].dictLabel;}}console.log("this.previewFormula")console.log(this.previewFormula)},
handleDrag(item) {indexList({ "factory": item.factory }).then(resp => {this.indexLists = resp.data;this.resultFormula = this.form.indicatorFormulaif (typeof this.resultFormula !== 'undefined' && this.resultFormula.length > 0) {const strArr = this.resultFormula.split(',')this.resultR = [];for (let i = 0; i < strArr.length; i++) {let indexBoolean = falsefor (let j = 0; j < this.indexLists.length; j++) {if (this.indexLists[j].dictValue === strArr[i]) {this.resultR.push(this.indexLists[j]);indexBoolean = true}}if (!indexBoolean) {let opBoolean = falsefor (let z = 0; z < this.operatorOptions.length; z++) {if (this.operatorOptions[z].dictValue === strArr[i]) {this.resultR.push(this.operatorOptions[z]);opBoolean = true}}if (!opBoolean) {for (let c = 0; c < this.nums.length; c++) {if (this.nums[c].dictValue === strArr[i]) {this.resultR.push(this.nums[c]);}}}}}}this.dragOpen = true;})},submitDrag() {console.log(this.resultR)this.resultFormula = ''for (let i = 0; i < this.resultR.length; i++) {this.resultFormula = this.resultFormula + this.resultR[i].dictValue + ","}this.$set(this.form, 'indicatorFormula', this.resultFormula.substring(0, this.resultFormula.length - 1));this.dragOpen = false;this.resultR = [];this.previewFormula = '';},cancelDrag() {this.dragOpen = false;this.previewFormula = '';},tagClick(item) {},handleClose(item) {this.resultR.splice(this.resultR.findIndex(i => i.dictValue === item.dictValue), 1);},
}

css代码

<style>.mpc-model-dialogue-box .el-dialog {width: 29%;height: auto;}.clearfix .el-checkbox__inner {margin-bottom: 8px;}.clearfix .el-checkbox__label {width: 100%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;font-size: 16px;font-weight: bold;color: #409EFF;}.cardClass .el-card__header {padding: 10px 15px 0px;}.show-fomula {position: absolute;bottom: 10px;right: 10px;font-size: 20px;color: #237aeb;}.show-fomula:hover {opacity: 0.5;transition: 1s;transform: scale(1.3);}.fomula-tag:hover {opacity: 0.5;transform: scale(1.1);background-color: #2d52f7 !important;}.edit-fomula:hover {opacity: 0.5;transition: 1s;transform: scale(1.3);color: #43bb0b;}.explain {font-weight: bold;color: red;font-size: 12px;float: right;}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录今日将C语言的Windows程序更改为python语言Windows程序,实现子窗口控制,类似微信程序框架最简单的原型

基本思路 为什么要选择python制作Windows应用程序&#xff0c;主要就是源代码直接展示&#xff0c;发现问题随时修改&#xff0c;同时可以不断增加新的功能方便。 由于C语言的Windows程序中结构类型在python中不能使用&#xff0c; 因此我们按照ctypes模块指导意见继承structu…

Verilog自学还是报班?

FPGA作为国内领先的芯片产品&#xff0c;和传统芯片相比并不局限于单纯的研究和设计芯片&#xff0c;而是针对多种领域的产品通过特定的芯片模型进行优化设计。FPGA本身也构成了典型的半定制电路&#xff0c;涵盖了数字管理模块、输入、输出等单元。 FPGA最大的特点是可以在同…

Unity_C#中使用protobuf

Unity_C#中使用protobuf 下载官方protobuf地址&#xff1a; https://github.com/protocolbuffers/protobuf/releaseshttps://links.jianshu.com/go?tohttps%3A%2F%2Fgithub.com%2Fprotocolbuffers%2Fprotobuf%2Freleases protobuf-c#源码生成dll&#xff0c;导入unity 1.…

双向无线功率传输系统MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介&#xff1a; 初级侧转换器通过双向 AC/DC 转换器从电网获取电力&#xff0c;并由直流线电压 Vin 供电&#xff0c;而拾波侧被视为连接到 EV&#xff0c;并由连接到任一存储的单独直流源 Vout 表示或…

N26:构建无缝体验的平台工程之路-Part 2

​ 在第一​​​​​​部分&#xff0c;我们介绍了 N26 团队为达成 “在 Day 1 实现轻松部署” 的目标而设定的战略规划和开发人员体验图&#xff0c;在这一部分&#xff0c;我们将带您了解该团队如何构建最简可行平台以及该平台如何运作。 01 计划构建最简可行平台 我们通…

高通开发系列 - 功耗问题之添加CPU Idle和Hotplug的功能

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 返回:专栏总目录 目录 概述CPU IdleCPU TopologyCPU Idle DriverCPU Idle GovernorCPU的hotplug函数

TCP/UDP 协议

目录 一.TCP协议 1.介绍 2.报文格式 ​编辑 确认号 控制位 窗口大小 3.TCP特性 二.TCP协议的三次握手 1.tcp 三次握手的过程 三.四次挥手 2.有限状态机 四.tcp协议和udp协议的区别 五.udp协议 UDP特性 六.telnet协议 一.TCP协议 1.介绍 TCP&#xff08;Transm…

DBCA创建RAC的过程截图

以下错误是由于配置的内存较大&#xff0c;而大页&#xff08;HugePage&#xff09;配置较小导致&#xff0c;调整大页后就好了。

Kafka基础理论与常用命令详解(超详细)

文章目录 前言一、Kafka概述1. Kafka简介2. Kafka架构2.1 Broker&#xff08;代理服务器&#xff09;2.2 Topic&#xff08;主题&#xff09;2.3 Producer&#xff08;生产者&#xff09;2.4 Consumer&#xff08;消费者&#xff09;2.5 Consumer Group&#xff08;消费者组&am…

Centos硬盘操作合集

一、硬盘命令说明 lsblk 列出系统上的所有磁盘列表 查看磁盘列表 参数意义 blkid 列出硬盘UUID [rootzs ~]# blkid /dev/sda1: UUID"77dcd110-dad6-45b8-97d4-fa592dc56d07" TYPE"xfs" /dev/sda2: UUID"oDT0oD-LCIJ-Xh7r-lBfd-axLD-DRiN-Twa…

Mybatis详解

MyBatis是什么 MyBatis是一个持久层框架&#xff0c;用于简化数据库操作的开发。它通过将SQL语句和Java方法进行映射&#xff0c;实现了数据库操作的解耦和简化。以下是MyBatis的优点和缺点&#xff1a; 优点&#xff1a; 1. 灵活性&#xff1a;MyBatis允许开发人员编写原生的…

如何正确使用缓存来提升系统性能

文章目录 引言什么时候适合加缓存&#xff1f;示例1示例2&#xff1a;示例3&#xff1a; 缓存应该怎么配置&#xff1f;数据分布**缓存容量大小&#xff1a;**数据淘汰策略 缓存的副作用总结 引言 在上一篇文章IO密集型服务提升性能的三种方法中&#xff0c;我们提到了三种优化…

Kafka-Kafka基本原理与集群快速搭建

一、Kafka介绍 ​ ChatGPT对于Apache Kafka的介绍&#xff1a; Apache Kafka是一个分布式流处理平台&#xff0c;最初由LinkedIn开发并于2011年开源。它主要用于解决大规模数据的实时流式处理和数据管道问题。 Kafka是一个分布式的发布-订阅消息系统&#xff0c;可以快速地处理…

【基础篇】一,认识STM32

一&#xff0c;什么是STM32&#xff1f; STM32是一款由意法半导体公司开发的32位微控制器&#xff1b;其中ST指意法半导体&#xff1b;M指MCU或MPU&#xff0c;32指32 位。 STM32覆盖了Cortex-M的多种系列&#xff0c;包括M0、M0、M3、M7等。在分类上&#xff0c;STM32有很多…

MyBatisPlus基础入门笔记

MyBatisPlus基础入门笔记&#xff0c;源码可见下载链接 大家阅读时可善用目录功能&#xff0c;可以提高大家的阅读效率 下载地址&#xff1a;MyBatisPlus源码笔记 初识MyBatisPlus 入门案例 SpringBoot整合MyBatis&#xff08;复习&#xff09; 创建SpringBoot工程勾选使用的…

56.windows docker 安装ES、Go操作ES(github.com/olivere/elastic/v7库)

文章目录 一、环境准备1、 docker安装ES2、启动容器3、图像化客户端工具ElasticSearch-Head 二、Go ES连接与认证1、 连接ES2、配置ES认证 三、索引的增删改查四、文档的增删改创建单个文档根据文档id删除文档批量删除文档批量创建文档 五、文档查询列表查询精确匹配模糊匹配嵌…

五、Microsoft群集服务(MSCS)环境的搭建

一、【目的】 学会利用Windows Server布置群集环境。 二、【设备】 FreeNAS11.2&#xff0c;Windows Server 2019 三、【要求】 学会利用Windows Server布置群集环境&#xff0c;掌握处理问题的能力。 配置表&#xff1a; 节点公网IP(public)内网IP(private)群集IP(clust…

linux磁盘空间清理

查看磁盘使用情况 查看磁盘分区上可以使用的磁盘空间 $ df -h若要查看文件类型和block&#xff0c;使用下面的命令 $ df -T查看每个文件和目录的磁盘使用空间&#xff0c;也就是文件的大小。 $ sudo du -sh /* $ sudo du -h --max-depth1 /清理旧的 Snap 包版本以释放磁盘空…

华为OD试题六(数据最节约的备份方法、TLV解码)

1. 数据最节约的备份方法 题目描述&#xff1a; 有若干个文件&#xff0c;使用刻录光盘的方式进行备份&#xff0c;假设每张光盘的容量是500MB&#xff0c;求 使用光盘最少的文件分布方式 所有文件的大小都是整数的MB&#xff0c;且不超过500MB&#xff1b;文件不能分割、分卷…