当前位置:网站首页>Customize the insertion of page labels and realize the initial search of similar address books
Customize the insertion of page labels and realize the initial search of similar address books
2022-07-01 20:28:00 【Not enough time later】
- Customize and realize the function of page annotation and label

<template>
<div>
<Icon type="ios-pricetags-outline" size="16" style="margin-right: 6px" />
<Tag v-for="(item, index) in allCaseTags" :key="index" :class="active === item ? 'active' : 'Classification'" @click.native="oncheckTag(item)">
<span
:contenteditable="item.tagId === ''"
v-html="item.tagName"
@keyup="keydown(item, index, $event)"
@blur="tagNameBlur(item, index, $event)"
style="border: none; outline: none; display: inline-block"
:ref="`tagName${index}`"
></span>
<Icon type="ios-close" v-if="active === item" style="margin-left: 4px" @click="delCurCaseTag(index)" />
</Tag>
<span class="tag-add" @click="addTags()" ref="addTagBtnRef">
<Icon type="icon-add" size="12" />
Add tags
</span>
<div class="popInput" :style="`left: ${left}px !important;`">
<ul class="tagUl" id="tagUl"></ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
allCaseTags: [{
tagName: ' label 1', tagId: 1 }],
allProjectsTags: [
{
tagName: ' label 1', tagId: 1, count: 1 },
{
tagName: ' label 2', tagId: 2, count: 1 },
{
tagName: ' label 3', tagId: 3, count: 1 },
{
tagName: ' Test label ', tagId: 4, count: 1 },
{
tagName: 'vue', tagId: 5, count: 1 },
{
tagName: 'javascript', tagId: 6, count: 1 },
{
tagName: ' front end ', tagId: 7, count: 1 },
{
tagName: ' Back end ', tagId: 8, count: 1 },
{
tagName: ' test ', tagId: 9, count: 1 },
],
popDom: '',
active: {
},
left: 0,
}
},
mounted() {
var popDom = document.getElementById('tagUl')
this.popDom = popDom
popDom.addEventListener('click', this.onLiTag2Click, false)
window.addEventListener('click', (e) => this.onCancelCurrentTag(e))
},
methods: {
onLiTag2Click(e) {
console.log(e)
if (e.target.tagName.toLowerCase() === 'li') {
var len = this.allCaseTags.length
var _val = e.target.innerText
this.$refs[`tagName${
len - 1}`][0].innerText = _val
this.$set(this.allCaseTags[len - 1], 'tagName', _val)
this.popDom.innerHTML = []
}
},
addTags() {
const drag = this.$refs.addTagBtnRef
const canvasInfo = drag.getBoundingClientRect()
this.left = canvasInfo.left
this.allCaseTags.push({
caseId: this.id,
projectId: this.projectId,
tagName: '',
mapId: '',
tagId: '',
})
this.$nextTick(() => {
this.$refs[`tagName${
this.allCaseTags.length - 1}`][0].focus()
})
},
keydown(item, index, e) {
var _val = e.target.innerText.trim()
var _lis = []
if (_val) {
// TODO: duplicate removal
const newArr = this.allProjectsTags.filter((item) => {
return !this.allCaseTags.some((ele) => ele.tagId === item.tagId)
})
newArr.forEach((str) => {
if (str.tagName.indexOf(_val) !== -1) {
// Match all
// _lis.push('<li>' + str.tagName.replace(_val, '<font color=red>' + _val + '</font>') + '</li>')
_lis.push('<li>' + str.tagName + '</li>')
}
})
}
this.popDom.innerHTML = _lis.join('')
},
oncheckTag(item) {
this.active = item
},
// Used to monitor mouse click non tag Regional time , Cancel the selected tag
onCancelCurrentTag() {
this.active = {
}
this.popDom.innerHTML = []
},
delCurCaseTag(index) {
this.allCaseTags.splice(index, 1)
this.onCancelCurrentTag()
},
tagNameBlur(item, index, event) {
var curText = event.target.innerText.replace(/[^\w\u4E00-\u9FA5]/g, '')
if (curText) {
this.$set(item, 'tagName', curText)
// perform add operation
} else {
// Remove the tag
this.allCaseTags.splice(index, 1)
}
},
},
beforeDestroy() {
this.popDom.removeEventListener('click', this.onLiTag2Click, false)
window.removeEventListener('click', this.onCancelCurrentTag)
},
}
</script>
<style lang="less">
.active {
background: Var(--SubPrimary);
cursor: default;
}
.Classification {
background: Var(--TableHeader);
cursor: default;
}
.popInput {
position: fixed;
}
.tagUl {
// position: absolute;
list-style: none;
}
.tagUl li {
padding: 0 8px;
line-height: 28px;
background-color: Var(--Theme);
cursor: pointer;
&:hover {
background-color: Var(--SubSuccess);
}
}
</style>
- Realization A-Z Alphabetic quick search ( Similar to mobile phone address book )

Need to install plug-ins , In order to convert Chinese characters into Pinyin letters
npm install js-pinyinimport pinyin from 'js-pinyin'
<template>
<div>
<div
class="country"
ref="listview"
v-show="countryList.length > 0"
v-cloak
@scroll="setScrollY"
>
<ul class="country-list">
<li v-for="(group, index) in countryList" ref="listGroup" :key="index">
<h2 class="list-group-title">{
{
group.title }}</h2>
<ul>
<li v-for="(item, index) in group.items" :key="index" class="list-group-item">
<span class="name"> {
{
item.tagName }} </span>
<span> ( {
{
item.count }} ) </span>
</li>
</ul>
</li>
</ul>
<ul class="list-shortcut">
<li
@mouseover.stop.prevent="onMouseover(index)"
class="item"
v-for="(item, index) in shortcut"
:key="index"
>
{
{
item }}
</li>
</ul>
</div>
</div>
</template>
<script>
import pinyinUtil from 'js-pinyin'
export default {
data() {
return {
value1: true,
countryList: [],
shortcut: [],
phoneCode: '93',
touch: {
},
listHeight: [],
scrollY: -1,
currentIndex: 0,
}
},
created() {
// To obtain a list of
this.getCountryList()
},
computed: {
fixedTitle() {
return this.shortcut[this.currentIndex] ? this.shortcut[this.currentIndex] : 'A'
},
},
watch: {
scrollY(newY) {
var listHeight = this.listHeight
// When scrolling to the top , newY<=0
if (newY <= 0) {
this.currentIndex = 0
return
}
// Middle part scrolling
for (var i = 0; i < listHeight.length - 1; i++) {
var height1 = listHeight[i]
var height2 = listHeight[i + 1]
if (!height2 || (newY >= height1 && newY < height2)) {
this.currentIndex = i
return
}
}
// Scroll to the bottom and newY Greater than the upper limit of the last element
this.currentIndex = listHeight.length - 1
},
},
mounted() {
setTimeout(() => {
this.calculateTotalHeight()
}, 200)
},
methods: {
setScrollY() {
this.scrollY = this.$refs.listview.scrollTop
},
getCountryList() {
var res = [
{
tagName: 'qqs3', projectId: 1, tagId: 21, count: 3 },
{
tagName: 'qqs2', projectId: 1, tagId: 23, count: 1 },
{
tagName: 'qqs', projectId: 1, tagId: 24, count: 4 },
{
tagName: 'qqs4', projectId: 1, tagId: 36, count: 1 },
{
tagName: 'qqs5', projectId: 1, tagId: 37, count: 1 },
{
tagName: 'qqs6', projectId: 1, tagId: 38, count: 1 },
{
tagName: '1', projectId: 1, tagId: 39, count: -1 },
{
tagName: ' data 1', projectId: 1, tagId: 40, count: 0 },
{
tagName: ' test 2', projectId: 1, tagId: 41, count: 0 },
{
tagName: ' label 1', projectId: 1, tagId: 69, count: 0 },
{
tagName: '1233', projectId: 1, tagId: 70, count: 0 },
{
tagName: 'aca', projectId: 1, tagId: 71, count: 1 },
{
tagName: 'aaa2', projectId: 1, tagId: 99, count: 1 },
{
tagName: 'bab', projectId: 1, tagId: 1, count: 1 },
{
tagName: 'bac', projectId: 1, tagId: 2, count: 1 },
{
tagName: 'bbb', projectId: 1, tagId: 3, count: 1 },
{
tagName: 'baa', projectId: 1, tagId: 4, count: 1 },
{
tagName: 'cac', projectId: 1, tagId: 5, count: 1 },
{
tagName: 'cab', projectId: 1, tagId: 6, count: 1 },
{
tagName: 'ccc', projectId: 1, tagId: 7, count: 1 },
{
tagName: 'ddd', projectId: 1, tagId: 8, count: 1 },
{
tagName: 'dad', projectId: 1, tagId: 9, count: 1 },
{
tagName: 'dav', projectId: 1, tagId: 10, count: 1 },
{
tagName: 'ee', projectId: 1, tagId: 11, count: 1 },
{
tagName: 'ear', projectId: 1, tagId: 12, count: 1 },
{
tagName: 'faf', projectId: 1, tagId: 13, count: 1 },
{
tagName: 'fac', projectId: 1, tagId: 14, count: 1 },
{
tagName: 'fad', projectId: 1, tagId: 15, count: 1 },
{
tagName: 'faa', projectId: 1, tagId: 16, count: 1 },
{
tagName: 'gac', projectId: 1, tagId: 17, count: 1 },
{
tagName: 'gab', projectId: 1, tagId: 18, count: 1 },
{
tagName: 'gar', projectId: 1, tagId: 19, count: 1 },
]
var map = {
}
res.forEach((item, index) => {
var key =
item.tagName.charCodeAt(0) > 255
? pinyinUtil.getCamelChars(item.tagName).slice(0, 1)
: item.tagName.slice(0, 1).toUpperCase()
if (/^[a-zA-Z]*$/.test(key)) {
if (!map[key]) {
this.shortcut.push(key)
map[key] = {
title: key,
items: [],
}
}
map[key].items.push(item)
} else {
if (!map['#']) {
this.shortcut.push('#')
map['#'] = {
title: '#',
items: [],
}
}
map['#'].items.push(item)
}
})
// Converted to an array
var ret = []
for (var k in map) {
var val = map[k]
ret.push(val)
}
// Sort the initials
ret.sort((a, b) => {
return a.title.charCodeAt(0) - b.title.charCodeAt(0)
})
this.shortcut.sort((a, b) => {
return a.charCodeAt(0) - b.charCodeAt(0)
})
// Sort the data in each group
ret.map((v) => {
v.items.sort((a, b) => {
return a.tagName.localeCompare(b.tagName)
})
})
this.countryList = ret
},
onMouseover(index) {
this.touch.anchorIndex = index
this.scrollToIndex(index)
},
scrollToIndex(index) {
this.$refs.listview.scrollTo(0, this.listHeight[index])
},
calculateTotalHeight() {
var list = this.$refs.listGroup
var height = 0
this.listHeight.push(height)
if (list && list.length > 0) {
for (var i = 0; i < list.length; i++) {
var item = list[i]
height += item.clientHeight
this.listHeight.push(height)
}
}
},
},
}
</script>
<style scoped lang="less">
ul {
list-style: none;
}
.country {
position: fixed;
overflow-y: scroll;
overflow-x: hidden;
z-index: 3000;
width: 400px;
right: 0;
top: 50px;
bottom: 0;
}
/* Letter */
.country-list h2 {
padding: 6px 16px;
color: Var(--LightDebug);
background: Var(--TableHeader);
line-height: 16px;
font: 500 14px/16px SFProText-Regular;
}
/* data list */
.country-list ul {
background: Var(--Theme);
padding: 0 16px;
}
.list-group-item {
padding: 8px 0 8px 20px;
border-bottom: 0.5px solid Var(--Divider);
&:hover {
cursor: pointer;
background: Var(--SubPrimary);
}
}
.country-list ul li:last-child {
border: none;
}
/* Search navigation */
.list-shortcut {
position: fixed;
z-index: 30;
right: 0;
padding-right: 8px;
top: 45%;
transform: translateY(-45%);
text-align: center;
background: Var(--Theme);
cursor: pointer;
}
.list-shortcut .item {
line-height: 16px;
color: Var(--SubContent);
font-size: 12px;
}
@media (min-width: 640px) {
.list-shortcut {
right: 8px;
}
.list-shortcut .item {
padding: 0 10px;
}
}
</style>
边栏推荐
- Solve the problem of slow or failed vscode download
- Richview trvdocparameters page parameter settings
- Optimization of the problem that the request flow fails to terminate during page switching of easycvr cluster video Plaza
- C # joint Halcon application - Dahua camera acquisition class
- Écrire un document de blog
- Principle of motion capture system
- Keras机器翻译实战
- Win11怎么关闭开机自启动软件
- Big factories are wolves, small factories are dogs?
- Swiftui 4 new features complete toggle and mixed toggle multiple binding components
猜你喜欢

【多线程】锁策略

极客DIY开源方案分享——数字幅频均衡功率放大器设计(实用的嵌入式电子设计作品软硬件综合实践)

渗透工具-TrustedSec 公司的渗透测试框架 (PTF)

开发那些事儿:EasyCVR平台添加播放地址鉴权功能

Entering Ruxin Town, digital intelligence transformation connects "future community"

A quietly rising domestic software, low-key and powerful!

Win11怎么关闭开机自启动软件

【多线程】 实现单例模式 ( 饿汉、懒汉 ) 实现线程安全的单例模式 (双重效验锁)

Win11暂停更新点不了怎么办?Win11暂停更新是灰色的如何解决?

Easycvr accesses the equipment through the national standard gb28181 protocol. What is the reason for the automatic streaming of the equipment?
随机推荐
开发那些事儿:EasyCVR集群设备管理页面功能展示优化
[C language] explain the usage of memset() function in detail
What did you learn about cheating after you went to college?
3D panoramic model display visualization technology demonstration
Internship: gradually moving towards project development
小鸟逃票登机,如何反思,应如何解决,飞机为何怕小鸟?
Write blog documents
STC 32位8051单片机开发实例教程 二 I/O工作模式及其配置
独家消息:阿里云悄然推出RPA云电脑,已与多家RPA厂商开放合作
Related concepts of cookies and sessions
Easycvr accesses the equipment through the national standard gb28181 protocol. What is the reason for the automatic streaming of the equipment?
Gaussdb (for MySQL):partial result cache, which accelerates the operator by caching intermediate results
List is divided into sets that meet and do not meet conditions (partitioningby)
uniapp使用腾讯地图选点 没有window监听回传用户的位置信息,怎么处理
优质笔记软件综合评测和详细盘点(一) Notion、Obsidian、RemNote、FlowUs
What if win11 can't pause the update? Win11 pause update is gray. How to solve it?
Error in installing sharp
MYSLQ十种锁,一篇文章带你全解析
Face recognition system opencv face detection
关于new Set( )还有哪些是你不知道的