vue如何獲取光標(biāo)位置
vue獲取光標(biāo)位置
新建組件configFormulaSalary
<template> <div> <el-dialog title="公式配置" :visible="isConfigFormula" top="15vh" width="1200px" custom-class="config-dialog" :before-close="onClose" append-to-body :close-on-click-modal="false" @mousedown.native="handleDialogMousedown($event)" @mouseup.native="handleDialogMouseup($event)" > <div class="form-main"> <div class="left-cont"> <div class="left-title">{{info? info.name : ''}}=</div> <div class="input-box"> <el-input type="textarea" v-model="formulaValue" autofocus="autofocus" @keyup.enter.native="searchHandle" ref="configInput" id="configInput" placeholder="請(qǐng)輸入計(jì)算公式或選擇函數(shù)" @focus="getCursor"></el-input> </div> <div class="formula-btn"> <div class="formula-left"> <el-button class="btn-experience" @click="onCheckItemFormula">公式校驗(yàn)</el-button> <span class="margin-l-20 tips-box" v-if="msgSuccessTips"> <i class="el-icon-circle-check"></i> {{msgSuccessTips}} </span> <span class="margin-l-20 tips-box err" v-if="msgErrorTips"> <i class="el-icon-circle-close"></i> {{msgErrorTips}} </span> </div> <div class="right-form-btn"> <el-select v-model="formulaRule" placeholder="請(qǐng)選擇" class="config-select-btn"> <el-option v-for="item in formulaRuleList" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> <span class="label-text">保留</span> <el-select v-model="decimalPoint" placeholder="請(qǐng)選擇" class="select-right"> <el-option v-for="item in decimalPointList" :key="item" :label="item" :value="item"> </el-option> </el-select> <span class="label-text">位小數(shù)</span> </div> </div> <div class="formula-item"> <span class="item-title">快捷運(yùn)算符</span> <span class="formula-label" v-for="(unit,indexU) in formulaTypeList" :key="indexU" @click="onSelectOperator(unit.value)">{{unit.label}}</span> </div> <div class="bottom-drap"> <div class="drap-title">點(diǎn)擊選擇薪資字段</div> <div class="drap-list"> <!-- <el-checkbox-group v-model="drapSelectList" @change="onSelect"> <el-checkbox-button v-for="(drap,indexD) in drapList" :label="'#'+drap+'#'" :key="indexD">{{drap}}</el-checkbox-button> </el-checkbox-group> --> <div class="list" v-for="(drap,indexD) in drapList" :key="indexD"> <div class="item" @click="onSelect(drap,'#')" v-if="info.name !==drap">{{drap}}</div> </div> </div> </div> </div> <div class="right-cont" @mouseleave="onLeave"> <div class="title-bar">插入函數(shù)</div> <div class="right-box"> <div class="box-title-bar">常用函數(shù)</div> <ul class="box-item-list" > <li class="item-cont" v-for="(formula,indexV) in formulaData.common" :key="indexV" @mouseenter="onEnterFormulaData(indexV,formula,1)" :class="isSelectIndex1 == indexV?'is-active':''" @click="onSelect(formula.grammar)"> <span>{{formula.title}}</span> <el-button type="text">插入</el-button> </li> </ul> <div class="box-title-bar">系統(tǒng)函數(shù)</div> <ul class="box-item-list"> <li class="item-cont" v-for="(formula,indexV) in formulaData.system" :key="indexV" @mouseenter="onEnterFormulaData(indexV,formula,2)" :class="isSelectIndex2 == indexV?'is-active':''" @click="onSelect(formula.grammar)"> <span>{{formula.title}}</span> <el-button type="text">插入</el-button> </li> </ul> </div> <div class="right-item-por" v-show="selectClass"> <div class="title">{{selectFunObj.title}}</div> <p v-html="selectFunObj.describe"></p> </div> </div> </div> <span slot="footer" class="dialog-footer"> <el-button @click="onClose">取 消</el-button> <el-button type="primary" @click="onSubmit('ruleForm')">確 定</el-button> </span> </el-dialog> </div> </template>
<script> // import {getCommonAndSystemFunctions,checkItemFormula} from "@/api/salary" export default { props: { isConfigFormula: Boolean, info: Object, drapList: Array, fieldGroupList: Array }, data () { return { formulaValue: '', formulaRule: 'round', formulaRuleList: [ { value: 'round', label:'四舍五入' }, { value: 'floor', label:'向下取整' }, { value: 'ceil', label:'向上取整' }, ], blurIndex: null,//輸入框光標(biāo)位置 msgSuccessTips: '', msgErrorTips: '', decimalPoint: 2, decimalPointList: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], formulaTypeList: [ {value: '+', label: '+'}, {value: '-', label: '-'}, {value: '*', label: '*'}, {value: '/', label: '/'}, {value: '()', label: '()'}, {value: '>', label: '>'}, {value: '<', label: '<'}, {value: '=', label: '='}, {value: '>=', label: '≥'}, {value: '<=', label: '≤'}, {value: '!=', label: '≠'}, {value: "''", label: "''"}, ], drapSelectList: [], selectFunObj: {}, selectClass: false, isSelectIndex1: null, isSelectIndex2: null, formulaData:{ system: [], common: [], }, classDialogmodel: false, } }, created(){ if (this.info) { this.formulaValue = this.info.text this.formulaRule = this.info.mode || 'round' this.decimalPoint = this.info.count !==null && this.info.count !== undefined ? this.info.count : 2 this.getList() } }, methods: { // 選擇薪資項(xiàng) onSelect(e,value){ let index=this.blurIndex let str=this.formulaValue if(value) { // this.formulaValue = this.formulaValue + ' #'+e+'#' let formulaValue ='#'+e+'#' this.insertAtCursor(formulaValue) } else { // this.formulaValue = this.formulaValue +e // this.formulaValue=str.slice(0, index) + e + str.slice(index); this.insertAtCursor(e) } }, onSelectOperator(e){ // this.formulaValue = this.formulaValue +e this.insertAtCursor(e) }, // 獲取光標(biāo)位置 async insertAtCursor(myValue) { const myField = document.querySelector('#configInput'); // const myField = this.$refs.configInput; if (myField.selectionStart || myField.selectionStart === 0) { var startPos = myField.selectionStart var endPos = myField.selectionEnd this.formulaValue = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length) await this.$nextTick() // 這句是重點(diǎn), 圈起來(lái) myField.focus() // 檢測(cè)函數(shù)是否下一次插入點(diǎn)位置 設(shè)置光標(biāo)位置 if(myValue.indexOf('(') !== -1) { let arr = myValue.split('') let index = arr.findIndex(o=>{return o=='('}) // myField.setSelectionRange(endPos + myValue.length, endPos + myValue.length) myField.setSelectionRange(endPos + index+1, endPos + index+1) } else { myField.setSelectionRange(endPos + myValue.length, endPos + myValue.length) } } else { this.formulaValue += myValue } }, onCheckItemFormula() { let arr = this.fieldGroupList.reduce((last,next)=>{ return last.concat(...next.fieldList) },[]) let parmetn = { checkItemName: this.info.name, formulaText: this.formulaValue, salaryItemGroupList: Array.from(new Set(arr)), } this.msgSuccessTips = '' this.msgErrorTips = '' // checkItemFormula(parmetn).then(res=> { // if(res.code='SUCCESS') { // this.msgSuccessTips = res.message // } // }).catch(err=> { // this.$message.error({ // message: err.message // }) // this.msgErrorTips = err.message // }) }, getCursor(e){ this.blurIndex = e.srcElement.selectionStart }, searchHandle(event) { event.preventDefault(); }, onLeave(vule){ this.selectClass = false; this.isSelectIndex1 = null this.isSelectIndex2 = null }, onEnterFormulaData(index,row,type) { this.selectClass = true this.selectFunObj = row if(type==1) { this.isSelectIndex1 = index this.isSelectIndex2 = null } else { this.isSelectIndex1 = null this.isSelectIndex2 = index } }, onClose () { this.$emit('onClose') }, onSubmit () { let data = { formulaValue: this.formulaValue, mode: this.formulaRule, count: this.decimalPoint, } this.$emit('onSubmitEdit',data) }, onRuleChange(event) { this.ruleForm.ruleId = event }, getList () { // getCommonAndSystemFunctions().then(res=> { // if(res.code=="SUCCESS") { // this.formulaData.common = res.common // this.formulaData.system = res.system // } // }).catch(err=> { // this.$message.error({ // message: err.message // }) // }) }, // 監(jiān)測(cè)彈框鼠標(biāo)事件 handleDialogMousedown(e) { // 如果為true,則表示點(diǎn)擊發(fā)生在遮罩層 this.classDialogmodel= !!e.target.classList.contains('el-dialog__wrapper') }, handleDialogMouseup(e) { if((!!e.target.classList.contains('el-dialog__wrapper')) && this.classDialogmodel){ this.onClose() } this.classDialogmodel=false }, }, watch: { isConfigFormula() { if(this.isConfigFormula) { this.getList() } } } } </script>
<style lang="less" scoped> @deep: ~'>>>'; // 刪除薪資組 @{deep}.config-dialog { .el-dialog__header { padding: 20px 24px 14px; font-size: 18px; line-height: 18px; font-family: PingFang SC; font-weight: 400; color: #333; border-bottom: 1px solid #E9E9E9; } .form-main { display: flex; justify-content: flex-start; } .el-dialog__body { padding: 0 !important; } .el-dialog__footer { text-align: right; padding-top: 10px; padding-bottom: 14px; border-top: 1px solid #E9E9E9; .el-button { padding: 0; width: 80px; height: 32px; text-align: center; line-height: 32px; font-size: 14px; font-family: PingFang SC; font-weight: 400; } .close-but { border: 1px solid #D9D9D9; border-radius: 4px; color: #666666; &:hover { background: transparent; } } .primary-btn { color: #FFFFFF; background: #3277FF; border-radius: 4px; } } .left-cont { width: 850px; padding: 0 24px; border-right: 1px solid #E8E8E8; .left-title { font-size: 14px; font-family: 'PingFang-SC-Bold'; font-weight: bold; color: #333; padding: 14px 0; } .input-box { padding-bottom: 10px; .el-textarea__inner { width: 100%; height: 124px; line-height: 26px; border: 1px solid #D5D5D5; border-radius: 4px; font-size: 14px; color: #333; padding: 0 10px; &::placeholder { font-size: 14px; font-family: PingFang SC; font-weight: 400; // color: #CCCCCC; } } } .formula-btn { display: flex; justify-content: space-between; align-items: center; padding-bottom: 24px; .btn-experience { width: 86px; height: 32px; padding: 0; text-align: center; line-height: 32px; background: #3277FF; border-radius: 4px; border-color: #3277FF; font-size: 14px; font-family: PingFang SC; font-weight: 400; color: #FFFFFF; } .right-form-btn { } .config-select-btn { .el-input__inner { width: 102px; height: 32px; line-height: 32px; background: #FFFFFF; border: 1px solid #D5D5D5; border-radius: 4px; // color: #333; &::placeholder { // color: #666; } } .el-input__icon { line-height: 32px; } } .select-right { margin-left: 10px; .el-input__inner { width: 56px; height: 32px; line-height: 32px; background: #FFFFFF; border: 1px solid #D5D5D5; border-radius: 4px; // color: #333; &::placeholder { // color: #666; } } .el-input__icon { line-height: 32px; } } .label-text { display: inline-block; font-size: 14px; font-family: PingFang SC; padding-left: 10px; font-weight: 400; color: #666666; } } .formula-item { display: flex; justify-content: flex-start; align-items: center; padding-bottom: 14px; .item-title { display: inline-block; font-size: 14px; font-family: 'PingFang-SC-Bold'; font-weight: bold; color: #333; margin-right: 12px; } .formula-label { display: inline-block; width: 44px; height: 32px; text-align: center; line-height: 30px; font-size: 20px; font-family: 'PingFang-SC-Medium'; font-weight: 500; color: #666666; border: 1px solid #D5D5D5; border-radius: 4px; margin-right: 14px; cursor: pointer; &:hover,&.is-active { border-color: #3277FF; color: #3277FF; } } } .bottom-drap { padding-bottom: 25px; .drap-title { font-size: 14px; line-height: 14px; padding-bottom: 15px; font-family: 'PingFang-SC-Bold'; font-weight: bold; color: #333; } .drap-list { width: 801px; height: 200px; background: #FAFAFA; overflow: hidden; overflow-y: scroll; padding: 15px 10px; display: flex; // align-items: center; flex-wrap: wrap; .item{ width: 118px; padding: 0 10px; height: 32px; line-height: 30px; text-align: center; font-size: 14px; font-family: PingFang SC; font-weight: 400; color: #333; background: #FFFFFF; border: 1px solid #D9D9D9; border-radius: 4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin-right: 14px; margin-bottom: 14px; cursor: pointer; } &::-webkit-scrollbar { /*滾動(dòng)條整體樣式*/ display: none; } } .el-checkbox-button { .el-checkbox-button__inner { width: 118px; padding: 0 10px; height: 32px; line-height: 30px; text-align: center; font-size: 14px; font-family: PingFang SC; font-weight: 400; color: #333; background: #FFFFFF; border: 1px solid #D9D9D9; border-radius: 4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin-right: 14px; margin-bottom: 14px; } &:nth-child(6n){ .el-checkbox-button__inner { margin-right: 0; } } &.is-checked,&:hover { .el-checkbox-button__inner { border-color: #3277FF; color: #3277FF; } } } } } .formula-left { display: flex; justify-content: flex-start; align-items: center; .tips-box { display: inline-block; font-size: 14px; max-width: 350px; line-height: 16px; color: #15bc83; &.err { color: #ff4141; } } } .right-cont { padding: 0 24px; position: relative; .title-bar { font-size: 14px; font-family: PingFang SC; font-weight: 400; color: #333; line-height: 42px; } .right-box { width: 301px; height: 480px; border: 1px solid #DCDCDC; border-radius: 4px; overflow: hidden; overflow-y: scroll; padding: 12px 0px; &::-webkit-scrollbar { /*滾動(dòng)條整體樣式*/ width: 6px; /*高寬分別對(duì)應(yīng)橫豎滾動(dòng)條的尺寸*/ height: 1px; background-color: transparent; } &::-webkit-scrollbar-thumb { /*滾動(dòng)條里面小方塊*/ border-radius: 2px; border: 5px solid #A9AAB1; box-shadow: 5px 0 0 #A9AAB1 inset; } &::-webkit-scrollbar-thumb:hover { box-shadow: 5px 0 0 #A9AAB1 inset; } .box-title-bar { font-size: 14px; font-family: PingFang SC; font-weight: 400; color: #AEAEAE; line-height: 14px; padding:0 5px, } .box-item-list { padding: 8px 0; } .item-cont { font-size: 14px; font-family: PingFang SC; font-weight: 400; color: #333; line-height: 14px; padding: 10px 12px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; &:hover, &.is-active { background: #3277FF; color: #fff; } .el-button { padding: 0; color: #fff; } } } .right-item-por { position: absolute; left: -280px; height: 480px; width: 300px; overflow: hidden; overflow-y: scroll; padding: 10px 20px; background: #fff; border: 1px solid #DCDCDC; top: 41px; border-radius: 4px; font-size: 12px; color: #333; line-height: 30px; &::-webkit-scrollbar { /*滾動(dòng)條整體樣式*/ width: 6px; /*高寬分別對(duì)應(yīng)橫豎滾動(dòng)條的尺寸*/ height: 1px; background-color: transparent; } &::-webkit-scrollbar-thumb { /*滾動(dòng)條里面小方塊*/ border-radius: 2px; border: 5px solid #A9AAB1; box-shadow: 5px 0 0 #A9AAB1 inset; } &::-webkit-scrollbar-thumb:hover { box-shadow: 5px 0 0 #A9AAB1 inset; } .title { font-size: 16px; color: #333; line-height: 30px; } } } } </style>
在父組件中引入configFormulaSalary
<!-- 配置 --> <configFormulaSalary :isConfigFormula="isConfigFormula" :drapList="drapList" :info="formulaSalaryInfo" @onClose="onConfigFormulaClose" @onSubmitEdit="onConfigFormulaGroup" v-if="isConfigFormula" :fieldGroupList="fieldGroupList"></configFormulaSalary> <script> import configFormulaSalary from './components/configFormulaSalary.vue' export default { name: 'App', components: { HelloWorld, configFormulaSalary }, data () { return { isConfigFormula:false, classmodel: false, drapList:[], formulaSalaryInfo:{}, fieldGroupList: [] } }, methods: { // 關(guān)閉配置彈框 onConfigFormulaClose(){ this.isConfigFormula = false }, // 打開(kāi)配置彈框 onConfigFormulaGroup(e){ this.isConfigFormula = true }, } } </script>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解vite2.0配置學(xué)習(xí)(typescript版本)
這篇文章主要介紹了詳解vite2.0配置學(xué)習(xí)(typescript版本),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02vue測(cè)試環(huán)境打包與生產(chǎn)環(huán)境打包文件數(shù)量不一致解決方案
這篇文章主要為大家介紹了vue測(cè)試環(huán)境打包與生產(chǎn)環(huán)境打包文件數(shù)量不一致的解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05vue中動(dòng)態(tài)參數(shù)與計(jì)算屬性的使用方法
在平時(shí)vue開(kāi)發(fā)中,我們經(jīng)常會(huì)用到計(jì)算屬性(計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值)來(lái)計(jì)算我們需要的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于vue中動(dòng)態(tài)參數(shù)與計(jì)算屬性使用的相關(guān)資料,需要的朋友可以參考下2021-08-08Vue.js每天必學(xué)之過(guò)濾器與自定義過(guò)濾器
Vue.js每天必學(xué)之過(guò)濾器與自定義過(guò)濾器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09解決vue 界面在蘋(píng)果手機(jī)上滑動(dòng)點(diǎn)擊事件等卡頓問(wèn)題
這篇文章主要介紹了vue 界面在蘋(píng)果手機(jī)上滑動(dòng)點(diǎn)擊事件等卡頓解決方案,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?dif
最近vue/cli創(chuàng)建項(xiàng)目后出現(xiàn)了錯(cuò)誤,下面這篇文章主要給大家介紹了關(guān)于vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?different?content?to?the?same?filename?index.html問(wèn)題的解決辦法,需要的朋友可以參考下2023-02-02解決vue2.0動(dòng)態(tài)綁定圖片src屬性值初始化時(shí)報(bào)錯(cuò)的問(wèn)題
下面小編就為大家分享一篇解決vue2.0動(dòng)態(tài)綁定圖片src屬性值初始化時(shí)報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Vue2.0學(xué)習(xí)之詳解Vue 組件及父子組件通信
本篇文章主要介紹了Vue2.0學(xué)習(xí)之詳解Vue 組件及父子組件通信,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12