123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- import baseComponent from '../helpers/baseComponent'
- import fieldBehavior from '../helpers/mixins/fieldBehavior'
- import classNames from '../helpers/libs/classNames'
- import warning from '../helpers/libs/warning'
- import { nextTick } from '../helpers/hooks/useNativeAPI'
- import { getDefaultContext } from '../helpers/shared/getDefaultContext'
- import { useRect } from '../helpers/hooks/useDOM'
- import { props as formProps } from '../form/props'
- import { props } from './props'
- const defaultContext = getDefaultContext(formProps, [
- 'layout',
- 'validateMessages',
- 'requiredMarkStyle',
- 'asteriskText',
- 'requiredText',
- 'optionalText',
- 'disabled',
- 'readOnly',
- ])
- const children = [
- 'picker',
- 'date-picker',
- 'popup-select',
- 'radio-group',
- 'checkbox-group',
- 'selectable',
- 'selector-group',
- 'switch',
- 'input',
- 'input-number',
- 'rater',
- 'slider',
- 'textarea',
- ]
- const relations = children.map((name) => `../${name}/index`).reduce((acc, name) => {
- return {
- ...acc,
- [name]: {
- type: 'descendant',
- observer: function() {
- this.callDebounceFn(this.changeValue)
- },
- },
- }
- }, {})
- baseComponent({
- useField: true,
- useExport: true,
- behaviors: [fieldBehavior],
- relations: {
- '../form/index': {
- type: 'ancestor',
- },
- ...relations,
- },
- properties: props,
- data: {
- index: 0,
- isLast: false,
- context: defaultContext,
- popoverVisible: false,
- slotRect: null,
- relativeRect: null,
- },
- observers: {
- initialValue(initialValue) {
- this.changeValue(initialValue)
- },
- ['valuePropName, valueNameFromEvent, trigger, validate, validateTrigger, preserve, rules, validateFirst, hidden']() {
- this.changeValue()
- },
- },
- computed: {
- classes: ['prefixCls, childElementPosition, labelWrap', function(prefixCls, childElementPosition, labelWrap) {
- const wrap = classNames(prefixCls)
- const child = classNames(`${prefixCls}__child`, {
- [`${prefixCls}__child--position-${childElementPosition}`]: childElementPosition,
- })
- const label = classNames(`${prefixCls}__label`, {
- [`${prefixCls}__label--wrap`]: labelWrap,
- })
- const extra = `${prefixCls}__extra`
- const arrow = `${prefixCls}__arrow`
- const asterisk = `${prefixCls}__required-asterisk`
- const text = `${prefixCls}__required-text`
- const feedback = `${prefixCls}__feedback-message`
- const labelHelp = `${prefixCls}__label-help`
- return {
- wrap,
- child,
- label,
- extra,
- arrow,
- asterisk,
- text,
- feedback,
- labelHelp,
- }
- }],
- },
- methods: {
- /**
- * 获取父节点
- */
- getFormContext() {
- return this.getRelationsByName('../form/index')[0]
- },
- /**
- * 获取子节点
- */
- getChildNodes() {
- return this.getRelationsByType('descendant')
- },
- changeContext(index = 0, isLast = false, context = defaultContext) {
- this.setData({
- index,
- isLast,
- context,
- })
- },
- setPopoverVisible() {
- const popoverVisible = !this.data.popoverVisible
- const promise = popoverVisible ? this.getPopoverRects() : Promise.resolve([])
- promise.then(([slotRect, relativeRect]) => {
- if (slotRect && relativeRect) {
- this.setData({
- slotRect,
- relativeRect,
- popoverVisible,
- })
- } else {
- this.setData({
- popoverVisible,
- })
- }
- })
- },
- getPopoverRects() {
- const { prefixCls } = this.data
- const getSlotRect = () => useRect(`.${prefixCls}__label-help`, this)
- const getRelativeRect = () => new Promise((resolve) => {
- const wuxCell = this.querySelector('#wux-cell')
- if (wuxCell) {
- wuxCell.getBoundingClientRect((_height, rect) => {
- resolve(rect)
- })
- }
- })
- return Promise.all([getSlotRect(), getRelativeRect()])
- },
- /**
- * 更新 value 值,同步到子元素
- */
- changeValue(value = this.data.value) {
- // set value
- if (this.data.value !== value) {
- this.setData({ value })
- }
- const elements = this.getChildNodes()
- const registerInputElem = (valuePropName, value, inputElem) => {
- const nextProps = {
- hasFieldDecorator: true,
- }
- if (inputElem.data[valuePropName] !== value) {
- nextProps[valuePropName] = value
- }
- inputElem.setData({
- ...nextProps,
- })
-
- nextTick(() => {
- this.forceUpdate(inputElem)
- })
- }
- if (elements.length > 0) {
- elements.forEach((inputElem) => {
- Object.defineProperty(inputElem, 'hasFieldDecorator', {
- value: true,
- enumerable: false,
- writable: true,
- configurable: true,
- })
- registerInputElem(this.data.valuePropName, value, inputElem)
- })
- }
- },
- /**
- * 强制更新元素
- */
- forceUpdate(inputElem, callback) {
- const formContext = this.getFormContext()
- if (!formContext) {
- warning(
- false,
- `Field<${this.data.name}> instance is not connected to any Form element.Forgot to use <wux-form />?`
- )
- return
- }
- const { getFieldDecorator } = formContext.getInternalHooks('FORM_HOOK_MARK')
- const fieldData = this.data
- const { name } = fieldData
- const inputProps = getFieldDecorator(name, fieldData, this)(inputElem)
- const finallyCb = () => {
- if (callback) {
- callback()
- }
- // field reRender
- this.reRender(this.data)
- }
-
- inputElem.setData(inputProps, finallyCb)
- },
- expose() {
- return {
- changeContext: this.changeContext.bind(this),
- changeValue: this.changeValue.bind(this),
- forceUpdate: this.forceUpdate.bind(this),
- }
- },
- },
- ready() {
- const formContext = this.getFormContext()
- if (formContext) {
- const { registerField } = formContext.getInternalHooks('FORM_HOOK_MARK')
- const { name } = this.data
- this.cancelRegister = registerField(name, this)
- }
- },
- detached() {
- if (this.cancelRegister) {
- this.cancelRegister()
- this.cancelRegister = null
- }
- },
- })
|