feat: Highlight组件重构
This commit is contained in:
@@ -167,24 +167,29 @@ if (props.draggable) {
|
||||
color: #909399;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.com-dialog__content {
|
||||
.content__wrap {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
:deep(.el-scrollbar__wrap) {
|
||||
max-height: 600px; // 最大高度
|
||||
overflow-x: hidden; // 隐藏横向滚动栏
|
||||
}
|
||||
}
|
||||
|
||||
.com-dialog__content--fullscreen {
|
||||
:deep(.el-scrollbar__wrap) {
|
||||
height: calc(~'100vh - 46px - 60px'); // 最大高度
|
||||
}
|
||||
}
|
||||
|
||||
.com-dialog__content--footer {
|
||||
:deep(.el-scrollbar__wrap) {
|
||||
max-height: calc(~'100vh - 46px - 60px - 70px'); // 最大高度
|
||||
|
||||
68
src/components/Highlight/index.tsx
Normal file
68
src/components/Highlight/index.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { defineComponent, PropType, computed, h } from 'vue'
|
||||
export default defineComponent({
|
||||
name: 'Highlight',
|
||||
props: {
|
||||
tag: {
|
||||
type: String as PropType<string>,
|
||||
default: 'span'
|
||||
},
|
||||
keys: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => []
|
||||
},
|
||||
color: {
|
||||
type: String as PropType<string>,
|
||||
default: '#2d8cf0'
|
||||
}
|
||||
},
|
||||
emits: ['click'],
|
||||
setup(props, { emit }) {
|
||||
const keyNodes = computed(() => {
|
||||
return props.keys.map((key) => {
|
||||
return h(
|
||||
'span',
|
||||
{
|
||||
onClick: () => {
|
||||
emit('click', key)
|
||||
},
|
||||
style: {
|
||||
color: props.color,
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
key
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function parseText(text: string) {
|
||||
props.keys.forEach((key, index) => {
|
||||
const regexp = new RegExp(key, 'g')
|
||||
text = text.replace(regexp, `{{${index}}}`)
|
||||
})
|
||||
return text.split(/{{|}}/)
|
||||
}
|
||||
|
||||
return {
|
||||
keyNodes,
|
||||
parseText
|
||||
}
|
||||
},
|
||||
render(props: any) {
|
||||
if (!props.$slots.default) return null
|
||||
const node = props.$slots.default()[0].children
|
||||
if (!node) {
|
||||
console.warn('Highlight组件的插槽必须要是文本')
|
||||
return props.$slots.default()[0]
|
||||
}
|
||||
const textArray = props.parseText(node)
|
||||
const regexp = /^[0-9]*$/
|
||||
const nodes = textArray.map((t: any) => {
|
||||
if (regexp.test(t)) {
|
||||
return props.keyNodes[Math.floor(t)] || t
|
||||
}
|
||||
return t
|
||||
})
|
||||
return h(props.tag, nodes)
|
||||
}
|
||||
})
|
||||
@@ -238,28 +238,31 @@ function canvasRoundRect(ctx: CanvasRenderingContext2D) {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.qrcode__wrap {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.disabled__wrap {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
& > div {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-weight: bold;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
i {
|
||||
font-size: 30px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,32 +306,38 @@ function changeVal(val: any, item: any): void {
|
||||
.ant-form-item {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.ant-form-item-with-help {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.search__bottom {
|
||||
text-align: center;
|
||||
padding-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
.search__bottom--button {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.search__bottom--col {
|
||||
position: relative;
|
||||
padding-bottom: 0;
|
||||
margin-top: 5px;
|
||||
position: relative;
|
||||
|
||||
.search__bottom--button {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.search__bottom--col::before {
|
||||
content: '';
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-left: 1px solid #d9d9d9;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
border-left: 1px solid #d9d9d9;
|
||||
content: '';
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -200,7 +200,7 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||
meta: {
|
||||
title: '二维码'
|
||||
}
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: 'avatars',
|
||||
// component: () => import('_v/components-demo/avatars/index.vue'),
|
||||
@@ -209,14 +209,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||
// title: '头像组'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: 'highlight',
|
||||
// component: () => import('_v/components-demo/highlight/index.vue'),
|
||||
// name: 'HighlightDemo',
|
||||
// meta: {
|
||||
// title: '文字高亮'
|
||||
// }
|
||||
// }
|
||||
{
|
||||
path: 'highlight',
|
||||
component: () => import('_v/components-demo/highlight/index.vue'),
|
||||
name: 'HighlightDemo',
|
||||
meta: {
|
||||
title: '文字高亮'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<div class="action__item"> <span>suffix:</span><el-input v-model="suffix" /> </div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<div style="margin-top: 20px; text-align: center">
|
||||
<el-button type="primary" @click="start">start</el-button>
|
||||
<el-button style="margin-left: 10px" @click="pauseResume">pause/resume</el-button>
|
||||
</div>
|
||||
@@ -83,26 +83,31 @@ function pauseResume(): void {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.count-to {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
|
||||
&__item {
|
||||
font-size: 80px;
|
||||
color: #f6416c;
|
||||
font-weight: bold;
|
||||
color: #f6416c;
|
||||
}
|
||||
}
|
||||
|
||||
.action {
|
||||
margin-top: 20px;
|
||||
|
||||
&__item {
|
||||
padding: 0 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
margin-bottom: 10px;
|
||||
align-items: center;
|
||||
|
||||
& > span {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.el-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
38
src/views/components-demo/highlight/index.vue
Normal file
38
src/views/components-demo/highlight/index.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="文字高亮组件 -- 基础用法"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<highlight :keys="['vue-element-plus-admin', 'vue-element-admin', 'vben-admin']">
|
||||
vue-element-plus-admin是一个基于vue3、vite2、element-plus的后台解决方案,借鉴了vue-element-admin和vben-admin的写法和优点。内置了动态路由,权限验证,典型的业务模型,丰富的功能组件,并且提供了多页配置,开箱即用,可以用来作为项目的启动模版。它可以帮助你快速搭建企业级中后台产品原型,也可以作为一个示例,用于学习。
|
||||
</highlight>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="文字高亮组件 -- 点击事件"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<highlight
|
||||
:keys="['vue-element-plus-admin', 'vue-element-admin', 'vben-admin']"
|
||||
@click="keyClick"
|
||||
>
|
||||
vue-element-plus-admin是一个基于vue3、vite2、element-plus的后台解决方案,借鉴了vue-element-admin和vben-admin的写法和优点。内置了动态路由,权限验证,典型的业务模型,丰富的功能组件,并且提供了多页配置,开箱即用,可以用来作为项目的启动模版。它可以帮助你快速搭建企业级中后台产品原型,也可以作为一个示例,用于学习。
|
||||
</highlight>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="HighlightDemo">
|
||||
import Highlight from '_c/Highlight/index'
|
||||
import { Message } from '_c/Message'
|
||||
function keyClick(key: string) {
|
||||
Message.success(key)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -79,11 +79,12 @@ function disabledClick() {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.el-col {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
.title-item {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
:closable="false"
|
||||
title="经典风格。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px; margin-top: 20px"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="searh">
|
||||
<com-search :data="classicData" @search-submit="searchSubmit1" @reset-submit="resetSubmit1" />
|
||||
@@ -24,7 +24,7 @@
|
||||
:closable="false"
|
||||
title="底部操作按钮风格。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px; margin-top: 20px"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="searh">
|
||||
<com-search
|
||||
@@ -41,7 +41,7 @@
|
||||
:closable="false"
|
||||
title="右侧操作按钮风格。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px; margin-top: 20px"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="searh">
|
||||
<com-search
|
||||
@@ -89,7 +89,7 @@ function resetSubmit3(data: any): void {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.searh {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user