ef586f0f2c99def7afc35c077918ed990249ad95.svn-base 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. import PropTypes from 'ant-design-vue/es/_util/vue-types'
  2. import { filterDictText } from '@/components/dict/JDictSelectUtil'
  3. import { getEnhancedMixins, JVXERenderType, replaceProps } from '@/components/jeecg/JVxeTable/utils/cellUtils'
  4. // noinspection JSUnusedLocalSymbols
  5. export default {
  6. inject: {
  7. getParentContainer: {default: () => ((node) => node.parentNode)},
  8. },
  9. props: {
  10. value: PropTypes.any,
  11. row: PropTypes.object,
  12. column: PropTypes.object,
  13. // 组件参数
  14. params: PropTypes.object,
  15. // 渲染选项
  16. renderOptions: PropTypes.object,
  17. // 渲染类型
  18. renderType: PropTypes.string.def('default'),
  19. },
  20. data() {
  21. return {
  22. innerValue: null,
  23. }
  24. },
  25. computed: {
  26. caseId() {
  27. return this.renderOptions.caseId
  28. },
  29. originColumn() {
  30. return this.column.own
  31. },
  32. $type() {
  33. return this.originColumn.$type
  34. },
  35. rows() {
  36. return this.params.data
  37. },
  38. fullDataLength() {
  39. return this.params.$table.tableFullData.length
  40. },
  41. rowIndex() {
  42. return this.params.rowIndex
  43. },
  44. columnIndex() {
  45. return this.params.columnIndex
  46. },
  47. cellProps() {
  48. let {originColumn: col, renderOptions} = this
  49. let props = {}
  50. // 输入占位符
  51. props['placeholder'] = replaceProps(col, col.placeholder)
  52. // 解析props
  53. if (typeof col.props === 'object') {
  54. Object.keys(col.props).forEach(key => {
  55. props[key] = replaceProps(col, col.props[key])
  56. })
  57. }
  58. // 判断是否是禁用的列
  59. props['disabled'] = (typeof col['disabled'] === 'boolean' ? col['disabled'] : props['disabled'])
  60. // TODO 判断是否是禁用的行
  61. // if (props['disabled'] !== true) {
  62. // props['disabled'] = ((this.disabledRowIds || []).indexOf(row.id) !== -1)
  63. // }
  64. // 判断是否禁用所有组件
  65. if (renderOptions.disabled === true) {
  66. props['disabled'] = true
  67. }
  68. return props
  69. },
  70. },
  71. watch: {
  72. $type: {
  73. immediate: true,
  74. handler($type) {
  75. this.enhanced = getEnhancedMixins($type)
  76. this.listeners = getListeners.call(this)
  77. },
  78. },
  79. value: {
  80. immediate: true,
  81. handler(val) {
  82. let value = val
  83. // 验证值格式
  84. let originValue = this.row[this.column.property]
  85. let getValue = this.enhanced.getValue.call(this, originValue)
  86. if (originValue !== getValue) {
  87. // 值格式不正确,重新赋值
  88. value = getValue
  89. vModel.call(this, value)
  90. }
  91. this.innerValue = this.enhanced.setValue.call(this, value)
  92. // 判断是否启用翻译
  93. if (this.renderType === JVXERenderType.spaner && this.enhanced.translate.enabled) {
  94. let res = this.enhanced.translate.handler.call(this, value)
  95. // 异步翻译,目前仅【多级联动】使用
  96. if (res instanceof Promise) {
  97. res.then(value => this.innerValue = value)
  98. } else {
  99. this.innerValue = res
  100. }
  101. }
  102. },
  103. },
  104. },
  105. created() {
  106. },
  107. methods: {
  108. /** 通用处理change事件 */
  109. handleChangeCommon(value) {
  110. let handle = this.enhanced.getValue.call(this, value)
  111. this.trigger('change', {value: handle})
  112. // 触发valueChange事件
  113. this.parentTrigger('valueChange', {
  114. type: this.$type,
  115. value: handle,
  116. oldValue: this.value,
  117. col: this.originColumn,
  118. rowIndex: this.params.rowIndex,
  119. columnIndex: this.params.columnIndex,
  120. })
  121. },
  122. /** 通用处理blur事件 */
  123. handleBlurCommon(value) {
  124. this.trigger('blur', {value})
  125. },
  126. /**
  127. * 如果事件存在的话,就触发
  128. * @param name 事件名
  129. * @param event 事件参数
  130. * @param args 其他附带参数
  131. */
  132. trigger(name, event, args = []) {
  133. let listener = this.listeners[name]
  134. if (typeof listener === 'function') {
  135. if (typeof event === 'object') {
  136. event = this.packageEvent(name, event)
  137. }
  138. listener(event, ...args)
  139. }
  140. },
  141. parentTrigger(name, event, args = []) {
  142. args.unshift(this.packageEvent(name, event))
  143. this.trigger('trigger', name, args)
  144. },
  145. packageEvent(name, event = {}) {
  146. event.row = this.row
  147. event.column = this.column
  148. //online增强参数兼容
  149. event.column['key'] = this.column['property']
  150. event.cellTarget = this
  151. if (!event.type) {
  152. event.type = name
  153. }
  154. if (!event.cellType) {
  155. event.cellType = this.$type
  156. }
  157. // 是否校验表单,默认为true
  158. if (typeof event.validate !== 'boolean') {
  159. event.validate = true
  160. }
  161. return event
  162. },
  163. },
  164. model: {
  165. prop: 'value',
  166. event: 'change'
  167. },
  168. /**
  169. * 【自定义增强】用于实现一些增强事件
  170. * 【注】这里只是定义接口,具体功能需要到各个组件内实现(也有部分功能实现)
  171. * 【注】该属性不是Vue官方属性,是JVxeTable组件自定义的
  172. * 所以方法内的 this 指向并不是当前组件,而是方法自身,
  173. * 也就是说并不能 this 打点调实例里的任何方法
  174. */
  175. enhanced: {
  176. // 注册参数(详见:https://xuliangzhan_admin.gitee.io/vxe-table/#/table/renderer/edit)
  177. installOptions: {
  178. // 自动聚焦的 class 类名
  179. autofocus: '',
  180. },
  181. // 事件拦截器(用于兼容)
  182. interceptor: {
  183. // 已实现:event.clearActived
  184. // 说明:比如点击了某个组件的弹出层面板之后,此时被激活单元格不应该被自动关闭,通过返回 false 可以阻止默认的行为。
  185. ['event.clearActived'](params, event, target) {
  186. return true
  187. },
  188. // 自定义:event.clearActived.className
  189. // 说明:比原生的多了一个参数:className,用于判断点击的元素的样式名(递归到顶层)
  190. ['event.clearActived.className'](params, event, target) {
  191. return true
  192. },
  193. },
  194. // 【功能开关】
  195. switches: {
  196. // 是否使用 editRender 模式(仅当前组件,并非全局)
  197. // 如果设为true,则表头上方会出现一个可编辑的图标
  198. editRender: true,
  199. // false = 组件触发后可视);true = 组件一直可视
  200. visible: false,
  201. },
  202. // 【切面增强】切面事件处理,一般在某些方法执行后同步执行
  203. aopEvents: {
  204. // 单元格被激活编辑时会触发该事件
  205. editActived() {
  206. },
  207. // 单元格编辑状态下被关闭时会触发该事件
  208. editClosed() {
  209. },
  210. },
  211. // 【翻译增强】可以实现例如select组件保存的value,但是span模式下需要显示成text
  212. translate: {
  213. // 是否启用翻译
  214. enabled: false,
  215. /**
  216. * 【翻译处理方法】如果handler留空,则使用默认的翻译方法
  217. * (this指向当前组件)
  218. *
  219. * @param value 需要翻译的值
  220. * @returns{*} 返回翻译后的数据
  221. */
  222. handler(value,) {
  223. // 默认翻译方法
  224. return filterDictText(this.column.own.options, value)
  225. },
  226. },
  227. /**
  228. * 【获取值增强】组件抛出的值
  229. * (this指向当前组件)
  230. *
  231. * @param value 保存到数据库里的值
  232. * @returns{*} 返回处理后的值
  233. */
  234. getValue(value) {
  235. return value
  236. },
  237. /**
  238. * 【设置值增强】设置给组件的值
  239. * (this指向当前组件)
  240. *
  241. * @param value 组件触发的值
  242. * @returns{*} 返回处理后的值
  243. */
  244. setValue(value) {
  245. return value
  246. },
  247. /**
  248. * 【新增行增强】在用户点击新增时触发的事件,返回新行的默认值
  249. *
  250. * @param row 行数据
  251. * @param column 列配置,.own 是用户配置的参数
  252. * @param $table vxe 实例
  253. * @param renderOptions 渲染选项
  254. * @param params 可以在这里获取 $table
  255. *
  256. * @returns 返回新值
  257. */
  258. createValue({row, column, $table, renderOptions, params}) {
  259. return column.own.defaultValue
  260. },
  261. }
  262. }
  263. function getListeners() {
  264. let listeners = Object.assign({}, (this.renderOptions.listeners || {}))
  265. if (!listeners.change) {
  266. listeners.change = async (event) => {
  267. vModel.call(this, event.value)
  268. await this.$nextTick()
  269. // 处理 change 事件相关逻辑(例如校验)
  270. this.params.$table.updateStatus(this.params)
  271. }
  272. }
  273. return listeners
  274. }
  275. export function vModel(value, row, property) {
  276. if (!row) {
  277. row = this.row
  278. }
  279. if (!property) {
  280. property = this.column.property
  281. }
  282. this.$set(row, property, value)
  283. }
  284. /** 模拟触发事件 */
  285. export function dispatchEvent({cell, $event}, className, handler) {
  286. // alwaysEdit 下不模拟触发事件,否者会导致触发两次
  287. if (this && this.alwaysEdit) {
  288. return
  289. }
  290. window.setTimeout(() => {
  291. let element = cell.getElementsByClassName(className)
  292. if (element && element.length > 0) {
  293. if (typeof handler === 'function') {
  294. handler(element[0])
  295. } else {
  296. // 模拟触发点击事件
  297. if($event){
  298. element[0].dispatchEvent($event)
  299. }
  300. }
  301. }
  302. }, 10)
  303. }