import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
import { filterDictText } from '@/components/dict/JDictSelectUtil'
|
import { getEnhancedMixins, JVXERenderType, replaceProps } from '@/components/jeecg/JVxeTable/utils/cellUtils'
|
|
// noinspection JSUnusedLocalSymbols
|
export default {
|
inject: {
|
getParentContainer: {default: () => ((node) => node.parentNode)},
|
},
|
props: {
|
value: PropTypes.any,
|
row: PropTypes.object,
|
column: PropTypes.object,
|
// 组件参数
|
params: PropTypes.object,
|
// 渲染选项
|
renderOptions: PropTypes.object,
|
// 渲染类型
|
renderType: PropTypes.string.def('default'),
|
},
|
data() {
|
return {
|
innerValue: null,
|
}
|
},
|
computed: {
|
caseId() {
|
return this.renderOptions.caseId
|
},
|
originColumn() {
|
return this.column.own
|
},
|
$type() {
|
return this.originColumn.$type
|
},
|
rows() {
|
return this.params.data
|
},
|
fullDataLength() {
|
return this.params.$table.tableFullData.length
|
},
|
rowIndex() {
|
return this.params.rowIndex
|
},
|
columnIndex() {
|
return this.params.columnIndex
|
},
|
cellProps() {
|
let {originColumn: col, renderOptions} = this
|
|
let props = {}
|
|
// 输入占位符
|
props['placeholder'] = replaceProps(col, col.placeholder)
|
|
// 解析props
|
if (typeof col.props === 'object') {
|
Object.keys(col.props).forEach(key => {
|
props[key] = replaceProps(col, col.props[key])
|
})
|
}
|
|
// 判断是否是禁用的列
|
props['disabled'] = (typeof col['disabled'] === 'boolean' ? col['disabled'] : props['disabled'])
|
|
// TODO 判断是否是禁用的行
|
// if (props['disabled'] !== true) {
|
// props['disabled'] = ((this.disabledRowIds || []).indexOf(row.id) !== -1)
|
// }
|
|
// 判断是否禁用所有组件
|
if (renderOptions.disabled === true) {
|
props['disabled'] = true
|
}
|
|
// update-begin-author:taoyan date:20211011 for: online表单,附表用户选择器{"multiSelect":false}不生效,单表可以生效 #3036
|
let jsonStr = col['fieldExtendJson']
|
if(jsonStr){
|
let fieldExtendJson = JSON.parse(jsonStr)
|
if(fieldExtendJson && fieldExtendJson['multiSelect']==false){
|
props['multi'] = false
|
}
|
}
|
// update-end-author:taoyan date:20211011 for: online表单,附表用户选择器{"multiSelect":false}不生效,单表可以生效 #3036
|
|
return props
|
},
|
},
|
watch: {
|
$type: {
|
immediate: true,
|
handler($type) {
|
this.enhanced = getEnhancedMixins($type)
|
this.listeners = getListeners.call(this)
|
},
|
},
|
value: {
|
immediate: true,
|
handler(val) {
|
let value = val
|
|
// 验证值格式
|
let originValue = this.row[this.column.property]
|
let getValue = this.enhanced.getValue.call(this, originValue)
|
if (originValue !== getValue) {
|
// 值格式不正确,重新赋值
|
value = getValue
|
vModel.call(this, value)
|
}
|
|
this.innerValue = this.enhanced.setValue.call(this, value)
|
|
// 判断是否启用翻译
|
if (this.renderType === JVXERenderType.spaner && this.enhanced.translate.enabled) {
|
let res = this.enhanced.translate.handler.call(this, value)
|
// 异步翻译,目前仅【多级联动】使用
|
if (res instanceof Promise) {
|
res.then(value => this.innerValue = value)
|
} else {
|
this.innerValue = res
|
}
|
}
|
},
|
},
|
},
|
created() {
|
},
|
methods: {
|
|
/** 通用处理change事件 */
|
handleChangeCommon(value) {
|
let handle = this.enhanced.getValue.call(this, value)
|
this.trigger('change', {value: handle})
|
// 触发valueChange事件
|
this.parentTrigger('valueChange', {
|
type: this.$type,
|
value: handle,
|
oldValue: this.value,
|
col: this.originColumn,
|
rowIndex: this.params.rowIndex,
|
columnIndex: this.params.columnIndex,
|
})
|
},
|
/** 通用处理blur事件 */
|
handleBlurCommon(value) {
|
this.trigger('blur', {value})
|
},
|
|
/**
|
* 如果事件存在的话,就触发
|
* @param name 事件名
|
* @param event 事件参数
|
* @param args 其他附带参数
|
*/
|
trigger(name, event, args = []) {
|
let listener = this.listeners[name]
|
if (typeof listener === 'function') {
|
if (typeof event === 'object') {
|
event = this.packageEvent(name, event)
|
}
|
listener(event, ...args)
|
}
|
},
|
parentTrigger(name, event, args = []) {
|
args.unshift(this.packageEvent(name, event))
|
this.trigger('trigger', name, args)
|
},
|
packageEvent(name, event = {}) {
|
event.row = this.row
|
event.column = this.column
|
//online增强参数兼容
|
event.column['key'] = this.column['property']
|
event.cellTarget = this
|
if (!event.type) {
|
event.type = name
|
}
|
if (!event.cellType) {
|
event.cellType = this.$type
|
}
|
// 是否校验表单,默认为true
|
if (typeof event.validate !== 'boolean') {
|
event.validate = true
|
}
|
return event
|
},
|
|
},
|
model: {
|
prop: 'value',
|
event: 'change'
|
},
|
/**
|
* 【自定义增强】用于实现一些增强事件
|
* 【注】这里只是定义接口,具体功能需要到各个组件内实现(也有部分功能实现)
|
* 【注】该属性不是Vue官方属性,是JVxeTable组件自定义的
|
* 所以方法内的 this 指向并不是当前组件,而是方法自身,
|
* 也就是说并不能 this 打点调实例里的任何方法
|
*/
|
enhanced: {
|
// 注册参数(详见:https://xuliangzhan_admin.gitee.io/vxe-table/#/table/renderer/edit)
|
installOptions: {
|
// 自动聚焦的 class 类名
|
autofocus: '',
|
},
|
// 事件拦截器(用于兼容)
|
interceptor: {
|
// 已实现:event.clearActived
|
// 说明:比如点击了某个组件的弹出层面板之后,此时被激活单元格不应该被自动关闭,通过返回 false 可以阻止默认的行为。
|
['event.clearActived'](params, event, target) {
|
return true
|
},
|
// 自定义:event.clearActived.className
|
// 说明:比原生的多了一个参数:className,用于判断点击的元素的样式名(递归到顶层)
|
['event.clearActived.className'](params, event, target) {
|
return true
|
},
|
},
|
// 【功能开关】
|
switches: {
|
// 是否使用 editRender 模式(仅当前组件,并非全局)
|
// 如果设为true,则表头上方会出现一个可编辑的图标
|
editRender: true,
|
// false = 组件触发后可视);true = 组件一直可视
|
visible: false,
|
},
|
// 【切面增强】切面事件处理,一般在某些方法执行后同步执行
|
aopEvents: {
|
// 单元格被激活编辑时会触发该事件
|
editActived() {
|
},
|
// 单元格编辑状态下被关闭时会触发该事件
|
editClosed() {
|
},
|
},
|
// 【翻译增强】可以实现例如select组件保存的value,但是span模式下需要显示成text
|
translate: {
|
// 是否启用翻译
|
enabled: false,
|
/**
|
* 【翻译处理方法】如果handler留空,则使用默认的翻译方法
|
* (this指向当前组件)
|
*
|
* @param value 需要翻译的值
|
* @returns{*} 返回翻译后的数据
|
*/
|
handler(value,) {
|
// 默认翻译方法
|
return filterDictText(this.column.own.options, value)
|
},
|
},
|
/**
|
* 【获取值增强】组件抛出的值
|
* (this指向当前组件)
|
*
|
* @param value 保存到数据库里的值
|
* @returns{*} 返回处理后的值
|
*/
|
getValue(value) {
|
return value
|
},
|
/**
|
* 【设置值增强】设置给组件的值
|
* (this指向当前组件)
|
*
|
* @param value 组件触发的值
|
* @returns{*} 返回处理后的值
|
*/
|
setValue(value) {
|
return value
|
},
|
/**
|
* 【新增行增强】在用户点击新增时触发的事件,返回新行的默认值
|
*
|
* @param row 行数据
|
* @param column 列配置,.own 是用户配置的参数
|
* @param $table vxe 实例
|
* @param renderOptions 渲染选项
|
* @param params 可以在这里获取 $table
|
*
|
* @returns 返回新值
|
*/
|
createValue({row, column, $table, renderOptions, params}) {
|
return column.own.defaultValue
|
},
|
}
|
}
|
|
function getListeners() {
|
let listeners = Object.assign({}, (this.renderOptions.listeners || {}))
|
if (!listeners.change) {
|
listeners.change = async (event) => {
|
vModel.call(this, event.value)
|
await this.$nextTick()
|
// 处理 change 事件相关逻辑(例如校验)
|
this.params.$table.updateStatus(this.params)
|
}
|
}
|
return listeners
|
}
|
|
export function vModel(value, row, property) {
|
if (!row) {
|
row = this.row
|
}
|
if (!property) {
|
property = this.column.property
|
}
|
this.$set(row, property, value)
|
}
|
|
/** 模拟触发事件 */
|
export function dispatchEvent({cell, $event}, className, handler) {
|
// alwaysEdit 下不模拟触发事件,否者会导致触发两次
|
if (this && this.alwaysEdit) {
|
return
|
}
|
window.setTimeout(() => {
|
let element = cell.getElementsByClassName(className)
|
if (element && element.length > 0) {
|
if (typeof handler === 'function') {
|
handler(element[0])
|
} else {
|
// 模拟触发点击事件
|
if($event){
|
element[0].dispatchEvent($event)
|
}
|
}
|
}
|
}, 10)
|
}
|