Vue 功能实现之①、一键复制 ②、ctrl+s保存等键盘监听事件 ③、每三个数字字符加一个逗号④、前端过滤集合⑤、指定顺序排序⑦数组指定位置截取⑧滚动条置顶⑨ 值位置整体切换⑩、搜索的文本高亮

1.一键复制

本地测试是没有问题的,但更新到服务器的时候,却不生效

 navigator.clipboard.writeText(val).then(() => {
    this.$Message.success('复制成功')
})

经查找资料发现是浏览器禁用了非安全域的 navigator.clipboard 对象。
安全域包括本地访问与开启TLS安全认证的地址,如https协议的地址、127.0.0.1localhost
所以要解决这个bug就是要做一个兼容写法,在安全域下使用 navigator.clipboard 提升效率,非安全域退回到 > document.execCommand('copy'); 保证功能一直可用。

建议使用textarea保证了复制的文本格式

    // 先给要复制的文本或者按钮加上点击事件后,并将要复制的值传过来
    async copyValue(val) {
      if (navigator.clipboard && window.isSecureContext) {
        // navigator clipboard 向剪贴板写文本
        this.$message.success('复制成功')
        return navigator.clipboard.writeText(val)
      } else {
        // 创建text area
        const textArea = document.createElement('textarea')
        // 设置元素的样式属性
	    textArea.style.position = 'absolute';
	    textArea.style.top = '0';
	    textArea.style.right = '0';
        textArea.value = val
        // 使text area不在viewport,同时设置不可见
        document.body.appendChild(textArea)
        textArea.focus()
        textArea.select()
        this.$message.success('复制成功')
        return new Promise((res, rej) => {
          // 执行复制命令并移除文本框
          document.execCommand('copy') ? res() : rej()
          textArea.remove()
        })
      }
    },

但是很奇怪 当我复制的时候,块1会消失,具体原因不知道,但换了拼接到的div就好了。

在这里插入图片描述
块1 的样式设定如下

.eqp-title {
    font-size: 1rem;
    font-weight: 600;
    color: #484848;
    padding: 0.3rem 0.3rem 0.3rem 1.5rem;
    height: 2.3rem;
    line-height: 2.3rem;
    top: 12px;
    left: 0px;
    z-index: 999;
}

解决方案如下:

右侧需要复制的最外层div 设定class="equipment-list"
将新建的文本textArea由拼接到 body 改为拼接到equipment-list

document.body.appendChild(textArea) —> document.getElementsByClassName('equipment-list')[0].appendChild(textArea)

注意:报错 document.getElementsByClassName(...).appendChild is not a function,是因为当使用 getElementsByClassName() 获取元素时,其返回的是数组,而没有定位到某一具体对象,所以带下标即可

2.Ctrl+s 保存等键盘监听事件

我这里主要是实现 保存 功能

mounted() {
    window.addEventListener('keydown', this.handleEvent)
},
beforeDestroy() {
    window.removeEventListener('keydown', this.handleEvent) // 在页面销毁的时候记得解除
},
methods: {
    async handleEvent(event) {
      switch (event.keyCode) {
        case 37:
          console.log('ctrl + ←')
          break
        case 38:
          console.log('ctrl + ↑')
          break
        case 39:
          console.log('ctrl + →')
          break
        case 40:
          console.log('ctrl + ↓')
          break
        case 67:
          console.log('ctrl + c')
          break
        case 83:
          console.log('ctrl + s')
          event.preventDefault()
          event.returnValue = false // 阻止直接保存网页
          // eslint-disable-next-line no-prototype-builtins
          if (event.ctrlKey && event.code === 'KeyS' && store.getters.forbidden.hasOwnProperty('ctrlS')) {
            // 在这里写保存需要执行的逻辑
          }
          if (event.ctrlKey && event.code === 'KeyS') return false
          break
        case 86:
          console.log('ctrl + v')
          break
        case 89:
          console.log('ctrl + y')
          if (event.ctrlKey && event.code === 'KeyY') {
            this.$router.go(+1)
          }
          break
        case 90:
          if (this.$route.path === '登录成功重定向的路由,比如控制台:/dashboard') return // 防止退出项目
          if (event.ctrlKey && event.code === 'KeyZ') {
            this.$router.go(-1)
          }
          break
      }
    }
}

通过打印 知道自己已经有监听到 ctrl 事件 和s 事件,但ctrls 同时 发生的时候,发现自己并没有监听执行内部的打印命令。当自己点 浏览器别的地方 ctrl+s的时候,就会监听执行。认为是ctrl+smonico editor是不生效的,研究后发现 monico editor 有自己的ctrl+s事件监听方式:如下所示:

this.editorInstance.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, () => {
	this.$emit("save", this.editorInstance.getValue());
});

父组件 就可以做相对应的 事件

<monaco-editor v-model.trim="validationRules" language="csharp" style="height: 700px" v-if="drawerFlag" @save="checkClick" />

3.每三个数字字符加一个逗号

利用过滤器,来将需要的数据每隔三个字符 加一个逗号。如下图所示:

在这里插入图片描述
实现方式:Vue2

<div class="card">
	<div class="card-box">
		<div class="title">产量</div>
		<div class="num">{{ data.capacity | num }}</div>
	</div>
	<div class="card-box">
		<div class="title">标准</div>
		<div class="num">{{ data.standard | num }}</div>
	</div>
	<div class="card-box">
		<div class="title">达成率</div>
		<div class="num">{{ data.rate }}%</div>
	</div>
</div>
filters: {
	num: (val) => {
		const value = val.toString().split("").reverse().join("");
		//每个三位价格逗号
		let temp = ""; // 临时变量
		for (let i = 0; i < value.length; i++) {
			temp += value[i];
			if ((i + 1) % 3 == 0 && i != value.length - 1) {
				temp += ","; // 每隔三个数字拼接一个逗号
			}
		}
		temp = temp.split("").reverse().join("");
		return temp; // 返回
	},
},

注:边框背景及样式

background: rgba(14, 78, 164, 0.4);
box-shadow: inset 0px 0px 12px 0px rgba(36, 115, 239, 0.58);

4.前端集合搜索

computed: {
	filterData() {
		const keyWord = this.submitData.filterTable?.toUpperCase() || "";
		const reg = new RegExp(keyWord);
		const arr = [];
		this.treeData.forEach((item) => {
			if (reg.test(item)) {
				arr.push(item);
			}
		});
		return arr;
	},
},

传参数的写法:
使用方式:filterData(111)

filterData() {
return function (key) {
		const keyWord = this.submitData.filterTable[key]?.toUpperCase() || "";
		const reg = new RegExp(keyWord);
		const arr = [];
		this.treeData[key].forEach((item) => {
			if (reg.test(item)) {
				arr.push(item);
			}
		});
		return arr;
	};
},

5.插入数据至光标处

在这里插入图片描述

  • HTML
	<Input
		v-model="submitData.fieldFunction"
		type="textarea"
		ref="fieldFunction"
		draggable
		:autosize="{ minRows: 20, maxRows: 20 }"
		style="margin-top: 10px"
	></Input>
  • JAVASCRIPT
// 调用
this.insertAtCursor(`${row}()`);
//插入数据至光标处
async insertAtCursor(myValue) {
	const myField = this.$refs.fieldFunction.$el.children[0];

	if (myField.selectionStart || myField.selectionStart === 0) {
		let startPos = myField.selectionStart; //开始位置
		let endPos = myField.selectionEnd; //结束位置
		let selectionPos = endPos + myValue.length - 1; //光标选中位置(-1)

		const fieldFunction = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
		this.submitData = { ...this.submitData, fieldFunction };

		await this.$nextTick(); // 这句是重点, 圈起来,不加的话后面两步有问题
		myField.focus();
		myField.setSelectionRange(selectionPos, selectionPos);
	} else {
		this.submitData = { ...this.submitData, fieldFunction: (this.submitData.fieldFunction += myValue) };
	}
},

注:由于我需要调整光标位置至括号()内,所以selectionPos 有-1操作

6.指定顺序排序

const order = ["LCL", "UCL", "CL", "mean", "LSL", "USL"];
data.seriesDatas.sort((a, b) => {
						return order.indexOf(a.name) - order.indexOf(b.name);
					})

7.数组指定位置截取

data.slice(0, 4)

8.滚动条置顶

this.$nextTick(() => {
// 当滚动条从没有到有时,不加setTimeout滚动条将不会滚动到底部
	setTimeout(() => {
		let overflowY = this.$el.getElementsByClassName("timeline")[0];
		if (!overflowY) {
			return;
		}
		overflowY.scrollTop = 0;
		//置底
		// overflowY.scrollTop = overflowY.scrollHeight;
	}, 1);
});

9.值位置整体切换-数值实现轮播类型转化

逻辑概述:点击0索引值,将0值切换到1索引,依次往后推,末尾值到首位
点击2索引值,将0值放到末尾,1值到首位,依次往前推

图片说明:
在这里插入图片描述

//改变线体
//index 当前点击的值索引,

changeStationData(index) {
	//当点击当前的 不修改此值
	if (index === 1) return;

	let result = [];
	//说明数据从后到前切换
	if (index == 2) {
		//第0个值到末尾,第一个值到第0个,第二个值到第一个
		const [num1, ...num2] = this.stationData;
		result = [...num2, num1];
	} else {
		//数据从前往后切换
		//末位置到第一个,第一个值到第二个,第二个值到第三个
		const [num1, ...num2] = this.stationData.reverse();
		result = [num1, ...num2.reverse()];
	}
	this.stationData = [...result];
	this.$forceUpdate();
},

10.搜索文本高亮

在这里插入图片描述

this.highlightSearch(["出站成功"]);
//查询字段高亮
	highlightSearch(keyWords) {
		let content = document.getElementsByClassName("content");
		keyWords.forEach((keyWord) => {
			for (let i = 0; i < content.length; i++) {
				const item = content[i];
				let regex = new RegExp("(" + keyWord + ")", "gi");
				let highlightedContent = item.innerHTML.replace(regex, "<span class='highlight'>$1</span>");
				item.innerHTML = highlightedContent;
			}
		});
	},
#equipment-list .highlight {
	background-color: #feff02;
	color: #000;
}
  • 参考的原始代码:
<!DOCTYPE html>
<html>
<head>
    <style>
        .highlight {
            background-color: yellow;
        }
    </style>
</head>
<body>
    <input type="text" id="searchInput" placeholder="搜索">
    <div id="content">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac viverra diam. Integer ut justo nec massa aliquet fermentum.
    </div>

    <script>
        function highlightSearch() {
            var searchInput = document.getElementById("searchInput");
            var content = document.getElementById("content");

            var searchQuery = searchInput.value;
            var regex = new RegExp("(" + searchQuery + ")", "gi");

            var highlightedContent = content.innerHTML.replace(regex, "<span class='highlight'>$1</span>");
            content.innerHTML = highlightedContent;
        }

        var searchInput = document.getElementById("searchInput");
        searchInput.addEventListener("input", highlightSearch);
    </script>
</body>
</html>

11. 根据数值的精度 加数值精度的0.01、0.001。。。。

//获取精度
getAccuracy(data) {
	const decimal = data.toString().split(".")[1];
	const decimalLength = decimal ? decimal.length : 0;
	return 1 / Math.pow(10, decimalLength); //次方函数
},

12 所有key转大写

keysToUpperCase(obj) {
	return Object.keys(obj).reduce((result, key) => {
		result[key.toUpperCase()] = obj[key];
		return result;
	}, {});
},

13 对象数组List 按字母顺序排序

Object.keys(this.dataItemList).forEach((item) => {
	if (this.sortDataItem) {
		this.dataItemList[item].sort((a, b) => a.detailName.localeCompare(b.detailName));
	} else {
		this.dataItemList[item].sort((a, b) => b.detailName.localeCompare(a.detailName));
	}
});

字符串和数字结合的List 按照数字排序

[{a:'Z01'},{a:'Z05'},{a:'Z03'}].sort((x,y)=>Number(x.a.replace(/\D/g, ''))-Number(y.a.replace(/\D/g, '')))
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue实现给一个数字逗号可以使用Vue过滤器。 首先,在Vue组件的`filters`选项中注册一个名为`addComma`的过滤器函数。 ```javascript filters: { addComma: function(value) { // 将数字转换为字符串 var str = value.toString(); // 使用正则表达式将每三个数字一个逗号 return str.replace(/(\d)(?=(\d{3})+$)/g, '$1,'); } } ``` 然后,在模板中使用该过滤器函数对数字进行过滤。 ```html <template> <div> <!-- 使用过滤器对数字进行过滤 --> {{ number | addComma }} </div> </template> ``` 以上代码会将`number`变量中的数字逗号后显示在页面上。 请注意,在Vue中,过滤器函数的名称需要与模板中调用过滤器时的名称相匹配,在这个例子中就是`addComma`。 接下来,你可以将需要添逗号的三个数字通过`v-model`绑定到Vue组件的变量中,并在模板中使用过滤器函数对它们进行过滤。 ```html <template> <div> <input type="number" v-model="number1"> <input type="number" v-model="number2"> <input type="number" v-model="number3"> <!-- 使用过滤器对数字进行过滤 --> {{ number1 | addComma }}, {{ number2 | addComma }}, {{ number3 | addComma }} </div> </template> <script> export default { data() { return { number1: 1000, number2: 2000, number3: 3000 }; }, filters: { addComma: function(value) { var str = value.toString(); return str.replace(/(\d)(?=(\d{3})+$)/g, '$1,'); } } }; </script> ``` 以上代码会将输入的三个数字逗号后显示在页面上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值