参数 title-help 更改为 title-prefix

This commit is contained in:
xuliangzhan
2022-02-19 15:40:55 +08:00
parent 4ab7c39016
commit de8f89b214
14 changed files with 120 additions and 175 deletions

View File

@@ -64,8 +64,8 @@ export default {
titleWidth: 100,
titleAlign: 'right',
items: [
{ field: 'name', title: 'app.body.label.name', span: 8, titlePrefix: { message: 'app.body.valid.rName', icon: 'fa fa-exclamation-circle' }, itemRender: { name: '$input', props: { placeholder: '请输入名称' } } },
{ field: 'email', title: '邮件', span: 8, itemRender: { name: '$input', props: { placeholder: '请输入邮件' } } },
{ field: 'name', title: 'app.body.label.name', span: 8, titlePrefix: { message: 'app.body.valid.rName', icon: 'vxe-icon--question' }, itemRender: { name: '$input', props: { placeholder: '请输入名称' } } },
{ field: 'email', title: '邮件', span: 8, titlePrefix: { useHTML: true, message: '点击链接:<a class="link" href="https://vxetable.cn" target="_blank">vxe-table官网</a>', icon: 'vxe-icon--question' }, itemRender: { name: '$input', props: { placeholder: '请输入邮件' } } },
{ field: 'nickname', title: '昵称', span: 8, itemRender: { name: '$input', props: { placeholder: '请输入昵称' } } },
{ field: 'role', title: '角色', span: 8, folding: true, itemRender: { name: '$input', props: { placeholder: '请输入角色' } } },
{ field: 'sex', title: '性别', span: 8, folding: true, titleSuffix: { message: '注意,必填信息!', icon: 'fa fa-info-circle' }, itemRender: { name: '$select', options: [] } },
@@ -124,6 +124,7 @@ export default {
field: 'role',
title: 'Role',
sortable: true,
titleHelp: { useHTML: true, content: '点击链接:<a class="link" href="https://vxetable.cn" target="_blank">vxe-table官网</a>' },
filters: [
{ label: '前端开发', value: '前端' },
{ label: '后端开发', value: '后端' },

View File

@@ -1,6 +1,6 @@
{
"name": "vxe-table",
"version": "3.5.0-beta.0",
"version": "3.5.0-beta.1",
"description": "一个基于 vue 的 PC 端表格组件,支持增删改查、虚拟列表、虚拟树、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、弹窗、自定义模板、渲染器、贼灵活的配置项、扩展接口等...",
"scripts": {
"serve": "vue-cli-service serve",

View File

@@ -69,9 +69,9 @@ const renderItem = (h, _vm, item, slots) => {
}
const ons = showTooltip ? {
mouseenter (evnt) {
_vm.triggerHeaderHelpEvent(evnt, params)
_vm.triggerTitleTipEvent(evnt, params)
},
mouseleave: _vm.handleTargetLeaveEvent
mouseleave: _vm.handleTitleTipLeaveEvent
} : {}
return h('div', {
class: ['vxe-form--item', item.id, span ? `vxe-col--${span} is--span` : null, className ? (XEUtils.isFunction(className) ? className(params) : className) : '', {

View File

@@ -64,7 +64,7 @@ function getResetValue (value, resetValue) {
function renderItems (h, _vm, itemList) {
const { _e, rules, data, collapseAll, validOpts, titleOverflow: allTitleOverflow } = _vm
return itemList.map((item, index) => {
return itemList.map((item) => {
const { slots, title, folding, visible, visibleMethod, field, collapseNode, itemRender, showError, errRule, className, titleOverflow, children } = item
const compConf = isEnableConf(itemRender) ? VXETable.renderer.get(itemRender.name) : null
const span = item.span || _vm.span
@@ -111,9 +111,9 @@ function renderItems (h, _vm, itemList) {
}
const ons = showTooltip ? {
mouseenter (evnt) {
_vm.triggerHeaderHelpEvent(evnt, params)
_vm.triggerTitleTipEvent(evnt, params)
},
mouseleave: _vm.handleTargetLeaveEvent
mouseleave: _vm.handleTitleTipLeaveEvent
} : {}
return h('div', {
class: ['vxe-form--item', item.id, span ? `vxe-col--${span} is--span` : null, className ? (XEUtils.isFunction(className) ? className(params) : className) : '', {
@@ -123,7 +123,7 @@ function renderItems (h, _vm, itemList) {
'is--active': !itemVisibleMethod || itemVisibleMethod(params),
'is--error': showError
}],
key: index
key: item.id
}, [
h('div', {
class: 'vxe-form--item-inner'
@@ -190,6 +190,7 @@ export default {
rules: Object,
preventSubmit: { type: Boolean, default: () => GlobalConfig.form.preventSubmit },
validConfig: Object,
tooltipConfig: Object,
customLayout: { type: Boolean, default: () => GlobalConfig.form.customLayout }
},
data () {
@@ -199,7 +200,6 @@ export default {
formItems: [],
tooltipTimeout: null,
tooltipActive: false,
tooltipStore: {
item: null,
visible: false
@@ -216,11 +216,7 @@ export default {
return Object.assign({}, GlobalConfig.form.validConfig, this.validConfig)
},
tooltipOpts () {
const opts = Object.assign({ leaveDelay: 300 }, GlobalConfig.form.tooltipConfig, this.tooltipConfig)
if (opts.enterable) {
opts.leaveMethod = this.handleTooltipLeaveMethod
}
return opts
return Object.assign({}, GlobalConfig.tooltip, GlobalConfig.form.tooltipConfig, this.tooltipConfig)
}
},
watch: {
@@ -283,7 +279,7 @@ export default {
*/
hasUseTooltip ? h('vxe-tooltip', {
ref: 'tooltip',
...tooltipOpts
props: tooltipOpts
}) : _e()
])
},
@@ -375,15 +371,6 @@ export default {
this.reset()
this.$emit('reset', { data: this.data, $form: this, $event: evnt })
},
handleTooltipLeaveMethod () {
const { tooltipOpts } = this
setTimeout(() => {
if (!this.tooltipActive) {
this.closeTooltip()
}
}, tooltipOpts.leaveDelay)
return false
},
closeTooltip () {
const { tooltipStore } = this
const $tooltip = this.$refs.tooltip
@@ -398,7 +385,7 @@ export default {
}
return this.$nextTick()
},
triggerHeaderHelpEvent (evnt, params) {
triggerTitleTipEvent (evnt, params) {
const { item } = params
const { tooltipStore } = this
const $tooltip = this.$refs.tooltip
@@ -406,8 +393,9 @@ export default {
const content = (overflowElem.textContent || '').trim()
const isCellOverflow = overflowElem.scrollWidth > overflowElem.clientWidth
clearTimeout(this.tooltipTimeout)
this.tooltipActive = true
this.closeTooltip()
if (tooltipStore.item !== item) {
this.closeTooltip()
}
if (content && isCellOverflow) {
Object.assign(tooltipStore, {
item,
@@ -418,10 +406,9 @@ export default {
}
}
},
handleTargetLeaveEvent () {
handleTitleTipLeaveEvent () {
const { tooltipOpts } = this
let $tooltip = this.$refs.tooltip
this.tooltipActive = false
if ($tooltip) {
$tooltip.setActived(false)
}

View File

@@ -23,7 +23,7 @@ function renderSuffixIcon (h, titleSuffix) {
}
export function renderTitle (h, _vm, item) {
const { data } = _vm
const { data, tooltipOpts } = _vm
const { slots, field, itemRender, titlePrefix, titleSuffix } = item
const compConf = isEnableConf(itemRender) ? VXETable.renderer.get(itemRender.name) : null
const params = { data, property: field, item, $form: _vm }
@@ -34,9 +34,9 @@ export function renderTitle (h, _vm, item) {
(titlePrefix.content || titlePrefix.message)
? h('vxe-tooltip', {
props: {
content: getFuncText(titlePrefix.content || titlePrefix.message),
enterable: titlePrefix.enterable,
theme: titlePrefix.theme
...tooltipOpts,
...titlePrefix,
content: getFuncText(titlePrefix.content || titlePrefix.message)
}
}, [
renderPrefixIcon(h, titlePrefix)
@@ -60,9 +60,9 @@ export function renderTitle (h, _vm, item) {
(titleSuffix.content || titleSuffix.message)
? h('vxe-tooltip', {
props: {
content: getFuncText(titleSuffix.content || titleSuffix.message),
enterable: titleSuffix.enterable,
theme: titleSuffix.theme
...tooltipOpts,
...titlePrefix,
content: getFuncText(titleSuffix.content || titleSuffix.message)
}
}, [
renderSuffixIcon(h, titleSuffix)

View File

@@ -7,10 +7,10 @@ import { getColumnConfig } from './util'
function renderHelpIcon (h, params) {
const { $table, column } = params
const { titleHelp } = column
return titleHelp ? [
const titlePrefix = column.titlePrefix || column.titleHelp
return titlePrefix ? [
h('i', {
class: ['vxe-cell-help-icon', titleHelp.icon || GlobalConfig.icon.TABLE_HELP],
class: ['vxe-cell-help-icon', titlePrefix.icon || GlobalConfig.icon.TABLE_HELP],
on: {
mouseenter (evnt) {
$table.triggerHeaderHelpEvent(evnt, params)

View File

@@ -68,8 +68,10 @@ const props = {
exportMethod: Function,
// 表尾单元格数据导出方法
footerExportMethod: Function,
// 标题帮助图标配置项
// 已废弃,被 titlePrefix 替换
titleHelp: Object,
// 标题帮助图标配置项
titlePrefix: Object,
// 单元格值类型
cellType: String,
// 单元格渲染配置项

View File

@@ -92,6 +92,7 @@ export class ColumnInfo {
exportMethod: _vm.exportMethod,
footerExportMethod: _vm.footerExportMethod,
titleHelp: _vm.titleHelp,
titlePrefix: _vm.titlePrefix,
// 自定义参数
params: _vm.params,
// 渲染属性

View File

@@ -1902,10 +1902,6 @@ const Methods = {
footerSpanMethod,
isAllOverflow,
visibleColumn
// isMergeLeftFixedExceeded,
// isMergeRightFixedExceeded,
// isMergeFooterLeftFixedExceeded,
// isMergeFooterRightFixedExceeded
} = this
const containerList = ['main', 'left', 'right']
const emptyPlaceholderElem = $refs.emptyPlaceholder
@@ -2023,14 +2019,6 @@ const Methods = {
tableColumn = fixedColumn
} else {
tableColumn = visibleColumn
// 检查固定列是否被合并,合并范围是否超出固定列
// if (mergeList.length && !isMergeLeftFixedExceeded && fixedType === 'left') {
// tableColumn = fixedColumn
// } else if (mergeList.length && !isMergeRightFixedExceeded && fixedType === 'right') {
// tableColumn = fixedColumn
// } else {
// tableColumn = visibleColumn
// }
}
} else {
tableColumn = visibleColumn
@@ -2056,14 +2044,6 @@ const Methods = {
tableColumn = fixedColumn
} else {
tableColumn = visibleColumn
// 检查固定列是否被合并,合并范围是否超出固定列
// if (mergeFooterList.length && !isMergeFooterLeftFixedExceeded && fixedType === 'left') {
// tableColumn = fixedColumn
// } else if (mergeFooterList.length && !isMergeFooterRightFixedExceeded && fixedType === 'right') {
// tableColumn = fixedColumn
// } else {
// tableColumn = visibleColumn
// }
}
} else {
tableColumn = visibleColumn
@@ -2284,6 +2264,7 @@ const Methods = {
const isEsc = keyCode === 27
if (isEsc) {
this.preventEvent(evnt, 'event.keydown', null, () => {
this.emitEvent('keydown-start', {}, evnt)
if (keyboardConfig && mouseConfig && mouseOpts.area && this.handleKeyboardEvent) {
this.handleKeyboardEvent(evnt)
} else if (actived.row || filterStore.visible || ctxMenuStore.visible) {
@@ -2304,6 +2285,7 @@ const Methods = {
}
}
this.emitEvent('keydown', {}, evnt)
this.emitEvent('keydown-end', {}, evnt)
})
}
},
@@ -2549,19 +2531,9 @@ const Methods = {
this.updateCellAreas()
this.recalculate(true)
},
handleTooltipLeaveMethod () {
const tooltipOpts = this.tooltipOpts
setTimeout(() => {
if (!this.tooltipActive) {
this.closeTooltip()
}
}, tooltipOpts.leaveDelay)
return false
},
handleTargetEnterEvent (isClear) {
const $tooltip = this.$refs.tooltip
clearTimeout(this.tooltipTimeout)
this.tooltipActive = true
if (isClear) {
this.closeTooltip()
} else {
@@ -2573,7 +2545,6 @@ const Methods = {
handleTargetLeaveEvent () {
const tooltipOpts = this.tooltipOpts
let $tooltip = this.$refs.tooltip
this.tooltipActive = false
if ($tooltip) {
$tooltip.setActived(false)
}
@@ -2590,16 +2561,19 @@ const Methods = {
},
triggerHeaderHelpEvent (evnt, params) {
const { column } = params
const { titleHelp } = column
if (titleHelp.content || titleHelp.message) {
const titlePrefix = column.titlePrefix || column.titleHelp
if (titlePrefix.content || titlePrefix.message) {
const { $refs, tooltipStore } = this
const $tooltip = $refs.tooltip
const content = getFuncText(titleHelp.content || titleHelp.message)
const content = getFuncText(titlePrefix.content || titlePrefix.message)
this.handleTargetEnterEvent(true)
tooltipStore.visible = true
if ($tooltip) {
$tooltip.open(evnt.currentTarget, content)
}
tooltipStore.currOpts = { ...titlePrefix, content: null }
this.$nextTick(() => {
const $tooltip = $refs.tooltip
if ($tooltip) {
$tooltip.open(evnt.currentTarget, content)
}
})
}
},
/**
@@ -2665,7 +2639,6 @@ const Methods = {
const { $refs, tooltipOpts, tooltipStore } = this
const { column, row } = params
const { showAll, enabled, contentMethod } = tooltipOpts
const tooltip = $refs.tooltip
const customContent = contentMethod ? contentMethod(params) : null
const useCustom = contentMethod && !XEUtils.eqNull(customContent)
const content = useCustom ? customContent : (column.type === 'html' ? overflowElem.innerText : overflowElem.textContent).trim()
@@ -2674,11 +2647,15 @@ const Methods = {
Object.assign(tooltipStore, {
row,
column,
visible: true
visible: true,
currOpts: null
})
this.$nextTick(() => {
const $tooltip = $refs.tooltip
if ($tooltip) {
$tooltip.open(isCellOverflow ? overflowElem : (tipElem || overflowElem), UtilTools.formatText(content))
}
})
if (tooltip) {
tooltip.open(isCellOverflow ? overflowElem : (tipElem || overflowElem), UtilTools.formatText(content))
}
}
return this.$nextTick()
},
@@ -2702,7 +2679,8 @@ const Methods = {
row: null,
column: null,
content: null,
visible: false
visible: false,
currOpts: null
})
if (tooltip) {
tooltip.close()

View File

@@ -389,6 +389,13 @@ export default {
insertList: [],
removeList: []
},
// 存放 tooltip 相关信息
tooltipStore: {
row: null,
column: null,
visible: false,
currOpts: null
},
// 存放数据校验相关信息
validStore: {
visible: false,
@@ -480,11 +487,10 @@ export default {
return Object.assign({}, GlobalConfig.table.checkboxConfig, this.checkboxConfig)
},
tooltipOpts () {
const opts = Object.assign({ leaveDelay: 300 }, GlobalConfig.table.tooltipConfig, this.tooltipConfig)
if (opts.enterable) {
opts.leaveMethod = this.handleTooltipLeaveMethod
}
return opts
return Object.assign({}, GlobalConfig.tooltip, GlobalConfig.table.tooltipConfig, this.tooltipConfig)
},
tipConfig () {
return { ...this.tooltipOpts, ...this.tooltipStore.currOpts }
},
validTipOpts () {
return Object.assign({ isArrow: false }, this.tooltipOpts)
@@ -598,54 +604,6 @@ export default {
}
return false
}
// isMergeLeftFixedExceeded () {
// const { mergeList, columnStore, visibleColumn } = this
// const { leftList } = columnStore
// const lastFCIndex = visibleColumn.indexOf(leftList[leftList.length - 1])
// for (let i = 0, len = mergeList.length; i < len; i++) {
// const item = mergeList[i]
// if (item.col <= lastFCIndex && item.col + item.colspan > lastFCIndex) {
// return true
// }
// }
// return false
// },
// isMergeRightFixedExceeded () {
// const { mergeList, columnStore, visibleColumn } = this
// const { rightList } = columnStore
// const firstFCIndex = visibleColumn.indexOf(rightList[0])
// for (let i = 0, len = mergeList.length; i < len; i++) {
// const item = mergeList[i]
// if (item.col < firstFCIndex && item.col + item.colspan >= firstFCIndex) {
// return true
// }
// }
// return false
// },
// isMergeFooterLeftFixedExceeded () {
// const { mergeFooterList, columnStore, visibleColumn } = this
// const { leftList } = columnStore
// const lastFCIndex = visibleColumn.indexOf(leftList[leftList.length - 1])
// for (let i = 0, len = mergeFooterList.length; i < len; i++) {
// const item = mergeFooterList[i]
// if (item.col <= lastFCIndex && item.col + item.colspan > lastFCIndex) {
// return true
// }
// }
// return false
// },
// isMergeFooterRightFixedExceeded () {
// const { mergeFooterList, columnStore, visibleColumn } = this
// const { rightList } = columnStore
// const firstFCIndex = visibleColumn.indexOf(rightList[0])
// for (let i = 0, len = mergeFooterList.length; i < len; i++) {
// const item = mergeFooterList[i]
// if (item.col < firstFCIndex && item.col + item.colspan >= firstFCIndex) {
// return true
// }
// }
// return false
// }
},
watch: {
data (value) {
@@ -713,8 +671,6 @@ export default {
scrollXStore: {},
// 存放纵向 Y 虚拟滚动相关信息
scrollYStore: {},
// 存放 tooltip 相关信息
tooltipStore: {},
// 表格宽度
tableWidth: 0,
// 表格高度
@@ -984,7 +940,6 @@ export default {
highlightHoverColumn,
editConfig,
validTipOpts,
tooltipOpts,
initStore,
columnStore,
filterStore,
@@ -1176,7 +1131,7 @@ export default {
*/
hasTip ? h('vxe-tooltip', {
ref: 'tooltip',
props: tooltipOpts
props: this.tipConfig
}) : _e(),
/**
* 校验提示

View File

@@ -41,6 +41,29 @@ function showTip (_vm) {
return _vm.updatePlacement()
}
function renderContent (h, _vm) {
const { $scopedSlots, useHTML, tipContent } = _vm
if ($scopedSlots.content) {
return h('div', {
key: 1,
class: 'vxe-table--tooltip-content'
}, $scopedSlots.content.call(this, {}))
}
if (useHTML) {
return h('div', {
key: 2,
class: 'vxe-table--tooltip-content',
domProps: {
innerHTML: tipContent
}
})
}
return h('div', {
key: 3,
class: 'vxe-table--tooltip-content'
}, UtilTools.formatText(tipContent))
}
export default {
name: 'VxeTooltip',
mixins: [vSize],
@@ -49,19 +72,19 @@ export default {
size: { type: String, default: () => GlobalConfig.tooltip.size || GlobalConfig.size },
trigger: { type: String, default: () => GlobalConfig.tooltip.trigger },
theme: { type: String, default: () => GlobalConfig.tooltip.theme },
content: [String, Number],
content: { type: [String, Number], default: null },
useHTML: Boolean,
zIndex: [String, Number],
isArrow: { type: Boolean, default: true },
enterable: Boolean,
enterDelay: { type: Number, default: () => GlobalConfig.tooltip.enterDelay },
leaveDelay: { type: Number, default: () => GlobalConfig.tooltip.leaveDelay },
leaveMethod: Function
leaveDelay: { type: Number, default: () => GlobalConfig.tooltip.leaveDelay }
},
data () {
return {
isUpdate: false,
visible: false,
message: '',
tipContent: '',
tipActive: false,
tipTarget: null,
tipZindex: 0,
@@ -74,7 +97,7 @@ export default {
},
watch: {
content (value) {
this.message = value
this.tipContent = value
},
value (value) {
if (!this.isUpdate) {
@@ -94,7 +117,7 @@ export default {
const { $el, trigger, content, value } = this
const parentNode = $el.parentNode
let target
this.message = content
this.tipContent = content
this.tipZindex = UtilTools.nextZIndex()
XEUtils.arrayEach($el.children, (elem, index) => {
if (index > 1) {
@@ -134,7 +157,7 @@ export default {
}
},
render (h) {
const { $scopedSlots, vSize, theme, message, tipActive, isArrow, visible, tipStore, enterable } = this
const { $scopedSlots, vSize, theme, tipActive, isArrow, visible, tipStore, enterable } = this
let on
if (enterable) {
on = {
@@ -155,9 +178,7 @@ export default {
ref: 'tipWrapper',
on
}, [
h('div', {
class: 'vxe-table--tooltip-content'
}, $scopedSlots.content ? $scopedSlots.content.call(this, {}) : message),
renderContent(h, this),
h('div', {
class: 'vxe-table--tooltip-arrow',
style: tipStore.arrowStyle
@@ -165,8 +186,8 @@ export default {
].concat($scopedSlots.default ? $scopedSlots.default.call(this, {}) : []))
},
methods: {
open (target, message) {
return this.toVisible(target || this.target, message)
open (target, content) {
return this.toVisible(target || this.target, content)
},
close () {
this.tipTarget = null
@@ -193,13 +214,13 @@ export default {
this.tipZindex = UtilTools.nextZIndex()
}
},
toVisible (target, message) {
toVisible (target, content) {
if (target) {
const { trigger, enterDelay } = this
this.tipActive = true
this.tipTarget = target
if (message) {
this.message = message
if (content) {
this.tipContent = content
}
if (enterDelay && trigger === 'hover') {
this.showDelayTip()
@@ -246,17 +267,15 @@ export default {
wrapperMouseenterEvent () {
this.tipActive = true
},
wrapperMouseleaveEvent (evnt) {
const { leaveMethod, trigger, enterable, leaveDelay } = this
wrapperMouseleaveEvent () {
const { trigger, enterable, leaveDelay } = this
this.tipActive = false
if (!leaveMethod || leaveMethod({ $event: evnt }) !== false) {
if (enterable && trigger === 'hover') {
setTimeout(() => {
if (!this.tipActive) {
this.close()
}
}, leaveDelay)
}
if (enterable && trigger === 'hover') {
setTimeout(() => {
if (!this.tipActive) {
this.close()
}
}, leaveDelay)
}
}
}

View File

@@ -37,10 +37,9 @@ export default {
// trigger: 'default',
strict: true
},
// tooltipConfig: {
// theme: 'dark',
// enterable: false
// },
tooltipConfig: {
enterable: true
},
validConfig: {
showMessage: true,
message: 'default'
@@ -244,12 +243,15 @@ export default {
},
form: {
// preventSubmit: false,
// size: null,
// colon: false,
validConfig: {
showMessage: true,
autoPos: true
},
// size: null,
// colon: false,
tooltipConfig: {
enterable: true
},
titleAsterisk: true
},
input: {

View File

@@ -104,7 +104,7 @@
.vxe-select-option {
padding: 0 10px;
max-width: 400px;
max-width: 600px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

View File

@@ -7,7 +7,7 @@
top: -100%;
left: -100%;
font-size: 12px;
max-width: 500px;
max-width: 600px;
border-radius: $vxe-border-radius;
padding: 8px 12px;
white-space: normal;