当前位置:网站首页>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-pinyin
import 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>
边栏推荐
- Practical project notes (I) -- creation of virtual machine
- 目标检测——Yolo系列
- Arduino Stepper库驱动28BYJ-48步进电机测试程序
- Importance of EDA tools to chip industry knowledge popularization
- A quietly rising domestic software, low-key and powerful!
- [C language] explain the usage of memset() function in detail
- Big factories are wolves, small factories are dogs?
- How can I know if I want to get the preferential link of stock account opening? Is it safe to open an account online?
- 写博客文档
- Getting started with fastdfs
猜你喜欢
How to connect the two nodes of the flow chart
Myslq ten kinds of locks, an article will take you to fully analyze
编译原理复习笔记
Develop those things: easycvr platform adds playback address authentication function
Niuke programming question -- must brush the string of 101 (brush the question efficiently, draw inferences from one instance)
Win11如何取消任务栏隐藏?Win11取消任务栏隐藏的方法
喜马拉雅自研网关架构演进过程
8K HDR!| Hevc hard solution for chromium - principle / Measurement Guide
cocoaPods 添加成功后,导入不了头文件或者not found file 报错
运动捕捉系统原理
随机推荐
Stack overflow 2022 developer survey: where is the industry going?
300题线性代数 第四讲 线性方程组
全国职业院校技能大赛网络安全“splunk“详细配置
MYSLQ十种锁,一篇文章带你全解析
写博客文档
Architect graduation summary
On the usage of a magic function
想得到股票开户的优惠链接,如何得知?在线开户是安全么?
Internship: gradually moving towards project development
EDA工具对芯片产业的重要性知识科普
人脸识别系统 —— OpenCV人脸检测
#yyds干货盘点#SQL聚合查询方法总结
目標檢測——Yolo系列
After adding cocoapods successfully, the header file cannot be imported or an error is reported in not found file
How to prevent repeated submission of new orders
Uniapp uses Tencent map to select points without window monitoring to return users' location information. How to deal with it
Oracle deadlock test
Solve the problem of slow or failed vscode download
Niuke programming question -- must brush the string of 101 (brush the question efficiently, draw inferences from one instance)
大厂做狼,小厂做狗?