Skip to content

Commit

Permalink
增加文字组件
Browse files Browse the repository at this point in the history
  • Loading branch information
blryli committed Nov 25, 2023
1 parent 9ad0b7e commit 785a229
Show file tree
Hide file tree
Showing 25 changed files with 2,691 additions and 533 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
# dk-vui组件库(Vue 3 + Vite)

#### 主要组件
#### 组件

- VTable 表格组件(基于vxe-table二次封装)

- VPage 页面组件(覆盖所有页面)

- VGroup 组合组件(多元素组合)

- VButton 按钮组件(按钮级权限)

- VAuth 按钮组件(区块级权限)

- VText 文本组件(默认值、颜色、溢出、复制)

#### 指令

- V-dom-load dom加载完毕时触发

- V-dom-resize dom大小改变时触发

#### 安装

```git
Expand Down
15 changes: 14 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dk-vui",
"version": "0.0.22",
"version": "0.0.23",
"description": "dk-vui",
"private": false,
"author": "blryli",
Expand All @@ -23,14 +23,27 @@
"vue": "3.2.45"
},
"devDependencies": {
"@bytemd/plugin-breaks": "^1.21.0",
"@bytemd/plugin-frontmatter": "^1.21.0",
"@bytemd/plugin-gemoji": "^1.21.0",
"@bytemd/plugin-gfm": "^1.21.0",
"@bytemd/plugin-highlight": "^1.20.2",
"@bytemd/plugin-math": "^1.21.0",
"@bytemd/plugin-medium-zoom": "^1.21.0",
"@bytemd/plugin-mermaid": "^1.21.0",
"@bytemd/vue-next": "^1.20.2",
"@element-plus/icons-vue": "^2.1.0",
"@vitejs/plugin-vue": "^4.1.0",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@xqsit94/vue3-copy-to-clipboard": "^1.1.0",
"bytemd": "^1.21.0",
"element-plus": "^2.3.7",
"highlight.js": "^11.9.0",
"sass": "^1.63.6",
"unplugin-auto-import": "^0.16.4",
"vite": "^4.3.9",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vue-router": "^4.2.5",
"vxe-table": "^4.4.2",
"xe-utils": "^3.5.11"
}
Expand Down
13 changes: 13 additions & 0 deletions packages/Page/src/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ const resize = ({ width }, target) => {
footerWidth.value = w
}
// 页面级气泡
const tipRef = ref()
const tip = ref({
visible: false,
content: '',
ref: null
})
const updateTip = (val) => {
tip.value = val
}
provide('updateTip', updateTip)
</script>

<template>
Expand All @@ -45,6 +56,8 @@ const resize = ({ width }, target) => {
<slot />
</div>
</div>
<el-tooltip ref="tipRef" :visible="tip.visible" :content="tip.content" :virtual-ref="tip.ref" virtual-triggering
placement="top" popper-class="app-tip" :offset="3" enterable />
</template>

<style lang="scss">
Expand Down
5 changes: 5 additions & 0 deletions packages/Table/src/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ const resetForm = () => {
}
// 代理query请求,把form参数修改为当前组件form
let qr = attrs.proxyConfig?.ajax?.query
const loadData = ref(false)
if (qr) {
attrs.proxyConfig.ajax.query = (ags) => {
loadData.value = true
const fn = (data) => qr(data)
ags.form = getQueryForm()
const { total, pageSize, currentPage: pageNum } = ags.page
Expand Down Expand Up @@ -144,6 +146,9 @@ const toTop = () => {
gridRef?.value.scrollTo(null, 0)
}
nextTick(() => {
if(!loadData.value) query()
})
onActivated(() => {
const { fullData } = gridRef?.value?.getTableData() || {}
if (fullData && !fullData.length) query()
Expand Down
7 changes: 7 additions & 0 deletions packages/Text/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import index from './src/index.vue'

index.install = (vue) => {
vue.component(index.name, index)
}

export default index
181 changes: 181 additions & 0 deletions packages/Text/src/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<template>
<div class="v-text">
<span v-if="title" class="v-text-title" @click.stop="() => false">{{ title }}:</span>
<div v-if="line === 'full'" class="v-text-content">{{ showValue }}</div>
<template v-else>
<div class="v-text-content-wrapper" :style="{ maxHeight: (+line) * 24 + 'px' }" @mouseenter="mouseenter"
@mouseleave="mouseleave">
<slot>
<div ref="valueRef" class="v-text-content" :class="`is--${type}`" :style="style" @click="emit('click')">{{ showValue }}</div>
<div ref="textRef" class="v-text-content-wrap">{{ showValue }}</div>
</slot>
<!-- 未溢出时的复制 -->
<div v-if="copy && !isOverflow" class="v-text-btns" title="复制" @click="copyText">
<el-icon>
<DocumentCopy />
</el-icon>
</div>
</div>
</template>
<!-- 溢出时的复制 -->
<div v-if="copy && isOverflow" class="v-text-btns" title="复制" @click="copyText">
<el-icon>
<DocumentCopy />
</el-icon>
</div>
</div>
</template>

<script setup name="VText">
import { $copyToClipboard } from "@xqsit94/vue3-copy-to-clipboard"
import { ElMessage } from "element-plus"
import { DocumentCopy } from "@element-plus/icons-vue"
const props = defineProps({
value: { type: String, default: '' }, // 文本
title: { type: String, default: '' }, // 标题
type: { type: String, default: 'text' }, // 类型,text文本/button按钮/link链接
line: { type: [Number, String], default: 1 }, // 溢出行数
copy: { type: Boolean, default: false }, // 复制
})
const emit = defineEmits(['click'])
// 溢出
const line = +props.line
const style = line > 1 ? {
'display': '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': line
} : {
'text-overflow': 'ellipsis',
'white-space': 'nowrap'
}
// 显示的值/默认值
const showValue = computed(() => {
const { value } = props
if (value === 0) return 0
return props.value || '-'
})
// 复制
const copyText = () => {
try {
$copyToClipboard(showValue.value)
ElMessage.success("复制成功")
} catch (error) {
ElMessage.error(error || "复制失败")
}
}
// 溢出处理
const updateTip = inject('updateTip')
const valueRef = ref()
const textRef = ref()
const isOverflow = ref(false)
const mouseenter = ({ target }) => {
isOverflow.value = textRef?.value.offsetHeight / 24 > line || valueRef?.value.offsetWidth < textRef?.value.offsetWidth
if (!isOverflow.value) return
updateTip({
visible: true,
content: showValue.value,
ref: target
})
}
const mouseleave = () => {
if (!isOverflow.value) return
updateTip({
visible: false,
content: '',
ref: null
})
}
</script>
<style lang="scss" scoped>
.v-text {
display: flex;
gap: 3px;
&-title {
color: #666;
white-space: nowrap;
line-height: 1.5rem;
}
&-content {
display: inline-block;
color: #333;
line-height: 1.5rem;
overflow: hidden;
&-wrapper {
display: flex;
gap: 3px;
position: relative;
flex: 1;
overflow: hidden;
white-space: pre-wrap;
}
&-wrap {
position: absolute;
left: 0;
top: 0;
white-space: pre-wrap;
line-height: 1.5rem;
z-index: -1;
}
}
.is--button,
.is--link {
cursor: pointer;
color: var(--el-color-primary);
&:hover {
color: var(--el-color-primary-light-3);
}
}
.is--button{
user-select: none;
}
.is--link {
position: relative;
&:hover {
&::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 0;
bottom: 0;
border-bottom: 1px solid var(--el-color-primary);
}
}
}
&-btns {
opacity: 0;
transition: all 0.2s ease;
transform: translateX(-8px) scale(0.7);
i {
vertical-align: middle;
}
}
&:hover {
.v-text-btns {
cursor: pointer;
opacity: 1;
transform: translateX(0) scale(1);
}
}
}
</style>
5 changes: 5 additions & 0 deletions packages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import Table from './Table'
import Group from './Group'
import Button from './Button'
import Auth from './Auth'
import Text from './Text'
import directive from './directives'
import {getRoutes} from './utils'
import { gridConfig } from './Table/src/config'


Expand All @@ -13,6 +15,7 @@ const components = [
Group,
Button,
Auth,
Text,
]

const install = (app, options) => {
Expand All @@ -34,4 +37,6 @@ export default {
Group,
Button,
Auth,
Text,
getRoutes
}
54 changes: 54 additions & 0 deletions packages/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import XEUtils from 'xe-utils'

/**
*
* @param {array} routerFiles 文件列表
* @param {string} baseName 基础名称,子应用必须传
* @returns
*/
export const getRoutes = (routerFiles, baseName = '') => {
const routeList = []
const upperName = name => baseName + name.split('/').map(da => da.replace(/^\w/g, d => d.toUpperCase())).join('')
for (const [key, component] of Object.entries(routerFiles)) {
const path = key.replace('../views', '').replace('/index.vue', '')
const isEdit = path.indexOf('/edit') > -1
// 编辑页
if (isEdit) {
const page = component.default.name?.split(',') // 可配置要生成的编辑页
const pages = page?.length > 1 ? page : ['edit', 'create', 'view'] // 编辑页默认生成 添加、编辑、查看页面
const types = pages.map(name => ({ name, path: `/${name}/:id` }))
types.forEach(d => {
let name = upperName(path.replace('edit', d.name).replace('/', ''))
routeList.push({
path: path.replace('/edit', d.path),
name,
component: async () => {
// 重写页面name,与路由name保持一致,支持keep-alive缓存
let name = upperName(path.replace('edit', d.name).replace('/', ''))
const com = XEUtils.clone(component, true)
com.default.name = name
return com
},
props: true,
hidden: true,
meta: {}
})
})
} else {
// 基础页面
const name = upperName(path.replace('/', ''))
const com = XEUtils.clone(component, true)
// 重写页面name,与路由name保持一致,支持keep-alive缓存
com.default.name = name
routeList.push({
path: path,
name,
component: async () => com,
props: false,
hidden: false,
meta: {}
})
}
}
return routeList
}
Loading

0 comments on commit 785a229

Please sign in to comment.