当前位置:网站首页>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>
边栏推荐
- Internship: gradually moving towards project development
- C # joint Halcon application - Dahua camera acquisition class
- cocoaPods 添加成功后,导入不了头文件或者not found file 报错
- 实战项目笔记(一)——虚拟机的创建
- math_ Use differentiation to calculate approximate value
- Easycvr accesses the equipment through the national standard gb28181 protocol. What is the reason for the automatic streaming of the equipment?
- Myslq ten kinds of locks, an article will take you to fully analyze
- PHP gets the external chain address of wechat applet and applet store
- internship:逐渐迈向项目开发
- STC 32位8051单片机开发实例教程 三 程序编译设置与下载
猜你喜欢
走进如心小镇,数智化变革连接“未来社区”
目標檢測——Yolo系列
Gaussdb (for MySQL):partial result cache, which accelerates the operator by caching intermediate results
Uniapp uses Tencent map to select points without window monitoring to return users' location information. How to deal with it
Win11怎么关闭开机自启动软件
[multithreading] lock strategy
RichView RichEdit SRichViewEdit PageSize 页面设置与同步
JS proxy
STC 32-bit 8051 single chip microcomputer development example tutorial three program compilation setting and download
[Mysql]安装Mysql5.7
随机推荐
使用Zadig从0到1搭建持续交付平台
【多线程】 实现单例模式 ( 饿汉、懒汉 ) 实现线程安全的单例模式 (双重效验锁)
上大学后明白了哪些坑人的事?
3D panoramic model display visualization technology demonstration
Vulnerability recurrence - Net ueeditor upload
开发那些事儿:EasyCVR集群设备管理页面功能展示优化
Importance of EDA tools to chip industry knowledge popularization
Flask 常用组件
STC 32位8051单片机开发实例教程 二 I/O工作模式及其配置
Data analysts sound tall? Understand these points before you decide whether to transform
EasyCVR集群视频广场页面切换时,请求流未能终止的问题优化
漏洞复现-.Net-ueditor上传
C#聯合halcon應用——大華相機采集類
On the next generation entrance of the metauniverse -- the implementation of brain computer interface
math_利用微分算近似值
uniapp使用腾讯地图选点 没有window监听回传用户的位置信息,怎么处理
开发那些事儿:EasyCVR平台添加播放地址鉴权功能
How to connect the two nodes of the flow chart
Hls4ml entry method
How can I know if I want to get the preferential link of stock account opening? Is it safe to open an account online?