1. 自定义实现页面标注标签功能
<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" />添加标签</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: '标签1', tagId: 1 }],allProjectsTags: [{ tagName: '标签1', tagId: 1, count: 1 },{ tagName: '标签2', tagId: 2, count: 1 },{ tagName: '标签3', tagId: 3, count: 1 },{ tagName: '测试标签', tagId: 4, count: 1 },{ tagName: 'vue', tagId: 5, count: 1 },{ tagName: 'javascript', tagId: 6, count: 1 },{ tagName: '前端', tagId: 7, count: 1 },{ tagName: '后端', tagId: 8, count: 1 },{ tagName: '测试', tagId: 9, count: 1 },],popDom: '',active: {},left: 0,}},mounted() {var popDom = document.getElementById('tagUl')this.popDom = popDompopDom.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.lengthvar _val = e.target.innerTextthis.$refs[`tagName${len - 1}`][0].innerText = _valthis.$set(this.allCaseTags[len - 1], 'tagName', _val)this.popDom.innerHTML = []}},addTags() {const drag = this.$refs.addTagBtnRefconst canvasInfo = drag.getBoundingClientRect()this.left = canvasInfo.leftthis.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: 去重const newArr = this.allProjectsTags.filter((item) => {return !this.allCaseTags.some((ele) => ele.tagId === item.tagId)})newArr.forEach((str) => {if (str.tagName.indexOf(_val) !== -1) {// 匹配所有// _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},// 用来监听鼠标点击非tag区域时,取消已选择的tagonCancelCurrentTag() {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)// 执行add操作} else {// 移除该tagthis.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>
  1. 实现A-Z的字母排序快速搜索(类似手机通讯录)

需要安装插件,以便把汉字转化为拼音字母
npm install js-pinyin
import pinyin from 'js-pinyin'

<template><div><divclass="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() {// 获取列表this.getCountryList()},computed: {fixedTitle() {return this.shortcut[this.currentIndex] ? this.shortcut[this.currentIndex] : 'A'},},watch: {scrollY(newY) {var listHeight = this.listHeight// 当滚动到顶部时, newY<=0if (newY <= 0) {this.currentIndex = 0return}// 中间部分滚动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 = ireturn}}// 滚动到底部且newY大于最后一个元素的上限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: '数据1', projectId: 1, tagId: 40, count: 0 },{ tagName: '测试2', projectId: 1, tagId: 41, count: 0 },{ tagName: '标签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)}})// 转为数组var ret = []for (var k in map) {var val = map[k]ret.push(val)}// 对首字母排序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)})// 对每个分组里面的数据进行排序ret.map((v) => {v.items.sort((a, b) => {return a.tagName.localeCompare(b.tagName)})})this.countryList = ret},onMouseover(index) {this.touch.anchorIndex = indexthis.scrollToIndex(index)},scrollToIndex(index) {this.$refs.listview.scrollTo(0, this.listHeight[index])},calculateTotalHeight() {var list = this.$refs.listGroupvar height = 0this.listHeight.push(height)if (list && list.length > 0) {for (var i = 0; i < list.length; i++) {var item = list[i]height += item.clientHeightthis.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;
}
/* 字母 */
.country-list h2 {padding: 6px 16px;color: Var(--LightDebug);background: Var(--TableHeader);line-height: 16px;font: 500 14px/16px SFProText-Regular;
}
/* 数据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;
}
/* 搜索导航 */
.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>

自定义插入页面标签以及实现类似通讯录的首字母搜索相关推荐

  1. android通讯录首字母分类,通讯录获取首字母并以首字母归类返回

    通讯录获取首字母并以首字母归类返回 效果1 - 返回首字母 效果2 - 返回拼音 代码 package com.dt.wx.miniprogram.app.util; import lombok.ex ...

  2. 手机通讯录java首字母排序,Android联系人按拼音排序以及按汉字首字母或全拼搜索...

    今天用了整整一下午去捣鼓这块,为什么模拟器上可以按拼音排序,中英文混排,及按字母搜索联系人,但到了开发板(平台是根据android2.2改过的)上就怎么不行了呢,虽然现在还没有解决,但也是知道了问题所 ...

  3. HtmlWebpackPlugin实现资源的自定义插入

    目前碰到的问题 我们用html-webpack-plugin的inject属性去自动插入打包后的js, css到页面中,但是如果想给script标签添加一个crossorigin属性呢, 例如: &l ...

  4. 给你的Zeit page自定义404页面

    本文章最初发表在XJHui's Blog,未经允许,任何人禁止转载! 为使您获得最好的阅读体验,强烈建议您点击 这里 前往 XJHui's Blog 查看! 前言 本教程仅适用于部署在Zeit.co的 ...

  5. react 错误边界_React with GraphQL和错误边界中的自定义错误页面

    react 错误边界 by Abi Noda 通过Abi Noda React with GraphQL和错误边界中的自定义错误页面 (Custom error pages in React with ...

  6. html页面在ie上出现404怎么解决,如何解决自定义404页面在IE等浏览器中无法显示问题...

    网站设置自定义404页面之后(如何在IIS下正确设置404页面?),如无法在浏览器中正常显示,可能是以下原因: 1.404页面文件权限设置错误 我们需要为404页面文件添加上用户everyone的可读 ...

  7. android edittext标签,TagEditText,类似微博标签的文本控件

    TagEditText实现了显示类似微博中的活动标签, 其特点是将一段文字中用'#'包裹的部分以特殊的颜色显示,并能进行点击交互. 如果你觉得还不错,欢迎star.fork.在使用过程中遇到任何问题, ...

  8. ASP.NET自定义错误页面(转)

    ASP.NET自定义错误页面(转) ASP.NET 提供三种用于在出现错误时捕获和响应错误的主要方法:Page_Error 事件.Application_Error 事件以及应用程序配置文件 (Web ...

  9. 017_SpringBoot异常处理方式-自定义错误页面

    1. 使用maven构建SpringBoot的名叫spring-boot-exception1项目 2. pom.xml <project xmlns="http://maven.ap ...

最新文章

  1. php 给图片增加背景平铺水印代码
  2. pt-table-checksum与pt-table-sync使用实践
  3. 22行代码AC——习题5-6 对称轴(Symmetry,UVa1595)——解题报告
  4. 【转】在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
  5. 多选框实现全选_Angular1.x-checkbox-全选amp;单选amp;多选
  6. Linux内核分析 - 网络[四补]:路由表补充
  7. Vue属性绑定~非常详细
  8. SQL里面也能用Split()
  9. 【C语言项目合集】这十个入门必备练手项目,让C语言对你来说不再难学!
  10. c#样条曲线命令_C#基数样条曲线的模拟实现(对应Graphics的DrawCurve)
  11. Django数据库的增删改查学习笔记
  12. 使用HttpClient通过POST方式发送XML,使用TCP/IP Monitor观察数据
  13. 金融危机对中国IT产业四大深层影响
  14. Vim快捷键汇总 - Jeffery Lee的专栏 - CSDNBlog
  15. yigo 第一阶段 异常处理 解决方案
  16. 测绘专业计算机知识,测绘科学技术的发展趋势
  17. opengl实现太阳系、地球系,并加上地球的贴图
  18. 良心推荐:看完这 20 部 BBC 神级纪录片,英语水平提升几个 Level!
  19. 脉冲神经网络学习笔记(综述)
  20. 输入一个整数n及一个n阶方阵,判断该方阵是否以主对角线对称,输出“Yes”或“No”。

热门文章

  1. 数据结构与算法——红黑树(Red Black Tree)
  2. 坚果云企业版服务器端,坚果云团队版和企业版的区别
  3. 2022-2028年全球与中国化学抑尘剂行业市场深度调研及投资预测分析
  4. amcharts学习笔记
  5. linux grep命令要查找的内容有双引号
  6. 企业如何做好终端设备管理?
  7. Android Studio修改工程项目名称以及修改包名
  8. Elasticsearch:Hadoop 大数据集成 (Hadoop => Elasticsearch)
  9. 幼儿园观察记录的目的和目标_幼儿园观察目的是什么?
  10. MySQL 为什么需要 redo log?