mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-18 12:34:25 +08:00
refactor(form-item): refactor event mechanism
This commit is contained in:
parent
fdad44af2b
commit
2621d152f9
@ -6,13 +6,13 @@
|
|||||||
:value="formValue"
|
:value="formValue"
|
||||||
ref="form"
|
ref="form"
|
||||||
>
|
>
|
||||||
<n-form-item label="Name" path="name">
|
<n-form-item label="Name" path="user.name" required>
|
||||||
<n-input v-model="formValue.name" placeholder="Input Name" />
|
<n-input v-model="formValue.user.name" placeholder="Input Name" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="Age" path="age">
|
<n-form-item label="Age" path="user.age" required>
|
||||||
<n-input placeholder="Input Age" v-model="formValue.age"/>
|
<n-input placeholder="Input Age" v-model="formValue.user.age"/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="Phone" path="phone">
|
<n-form-item label="Phone" path="phone" required>
|
||||||
<n-input placeholder="Phone Number" v-model="formValue.phone"/>
|
<n-input placeholder="Phone Number" v-model="formValue.phone"/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item v-model="formValue.phone">
|
<n-form-item v-model="formValue.phone">
|
||||||
@ -29,8 +29,10 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
formValue: {
|
formValue: {
|
||||||
name: '',
|
user: {
|
||||||
age: '',
|
name: '',
|
||||||
|
age: ''
|
||||||
|
},
|
||||||
phone: ''
|
phone: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,12 @@
|
|||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
<div :class="`n-form-item-explain`">
|
<div :class="`n-form-item-explain`">
|
||||||
{{ explain }}
|
<transition name="n-fade-down">
|
||||||
|
<span
|
||||||
|
v-if="explain"
|
||||||
|
class="n-form-item-explain__content"
|
||||||
|
>{{ explain }}</span>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -131,10 +136,17 @@ export default {
|
|||||||
},
|
},
|
||||||
synthesizedRules () {
|
synthesizedRules () {
|
||||||
let rules = []
|
let rules = []
|
||||||
|
const validator = (rule, value) => {
|
||||||
|
if (value !== undefined && value !== null && value !== '') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return Error(`${this.label || this.path} is required!`)
|
||||||
|
}
|
||||||
if (this.required) {
|
if (this.required) {
|
||||||
rules.push({
|
rules.push({
|
||||||
trigger: 'blur',
|
trigger: ['blur', 'change', 'input'],
|
||||||
required: true
|
required: true,
|
||||||
|
validator
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.rule) {
|
if (this.rule) {
|
||||||
@ -156,6 +168,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
/**
|
||||||
|
* This is buggy!
|
||||||
|
* Because if it's child change, rules is not updated
|
||||||
|
* However I need to make it work first
|
||||||
|
*/
|
||||||
this.addValidationEventListeners()
|
this.addValidationEventListeners()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -165,6 +182,12 @@ export default {
|
|||||||
handleContentChange () {
|
handleContentChange () {
|
||||||
this.validate('change')
|
this.validate('change')
|
||||||
},
|
},
|
||||||
|
handleContentFocus () {
|
||||||
|
this.validate('focus')
|
||||||
|
},
|
||||||
|
handleContentInput () {
|
||||||
|
this.validate('input')
|
||||||
|
},
|
||||||
validate (trigger = null, callback = null) {
|
validate (trigger = null, callback = null) {
|
||||||
if (!this.path) {
|
if (!this.path) {
|
||||||
return
|
return
|
||||||
@ -172,10 +195,17 @@ export default {
|
|||||||
const rules = this.synthesizedRules
|
const rules = this.synthesizedRules
|
||||||
const path = this.path
|
const path = this.path
|
||||||
const value = get(this.NForm.value, this.path, null)
|
const value = get(this.NForm.value, this.path, null)
|
||||||
const activeRules = !trigger ? rules : rules.filter(rule => rule.trigger === trigger)
|
const activeRules = !trigger ? rules : rules.filter(rule => {
|
||||||
|
if (Array.isArray(rule.trigger)) {
|
||||||
|
return rule.trigger.includes(trigger)
|
||||||
|
} else {
|
||||||
|
return rule.trigger === trigger
|
||||||
|
}
|
||||||
|
})
|
||||||
if (!activeRules.length) return
|
if (!activeRules.length) return
|
||||||
const asyncValidator = new AsyncValidator({ [path]: activeRules })
|
const asyncValidator = new AsyncValidator({ [path]: activeRules })
|
||||||
asyncValidator.validate({ [path]: value }, (errors, fields) => {
|
asyncValidator.validate({ [path]: value }, (errors, fields) => {
|
||||||
|
console.log('validate', errors, fields)
|
||||||
if (errors) {
|
if (errors) {
|
||||||
this.explain = errors[0].message
|
this.explain = errors[0].message
|
||||||
this.validated = true
|
this.validated = true
|
||||||
@ -192,8 +222,10 @@ export default {
|
|||||||
addValidationEventListeners () {
|
addValidationEventListeners () {
|
||||||
const rules = this.synthesizedRules
|
const rules = this.synthesizedRules
|
||||||
if (rules.length >= 0) {
|
if (rules.length >= 0) {
|
||||||
this.$on('form-item-blur', this.handleContentBlur)
|
this.$on('blur', this.handleContentBlur)
|
||||||
this.$on('form-item-change', this.handleContentChange)
|
this.$on('input', this.handleContentInput)
|
||||||
|
this.$on('focus', this.handleContentFocus)
|
||||||
|
this.$on('change', this.handleContentChange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ export default {
|
|||||||
},
|
},
|
||||||
labelPosition: {
|
labelPosition: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'top' // ['top', 'right', 'left', 'center']
|
default: 'top'
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -124,22 +124,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Emitter from '../../../mixins/emitter'
|
|
||||||
import NCancelMark from '../../../base/CancelMark'
|
import NCancelMark from '../../../base/CancelMark'
|
||||||
import withapp from '../../../mixins/withapp'
|
import withapp from '../../../mixins/withapp'
|
||||||
import themeable from '../../../mixins/themeable'
|
import themeable from '../../../mixins/themeable'
|
||||||
|
import asformitem from '../../../mixins/asformitem'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NInput',
|
name: 'NInput',
|
||||||
components: {
|
components: {
|
||||||
NCancelMark
|
NCancelMark
|
||||||
},
|
},
|
||||||
mixins: [ withapp, themeable, Emitter ],
|
mixins: [ withapp, themeable, asformitem() ],
|
||||||
inject: {
|
|
||||||
NFormItem: {
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -322,9 +317,6 @@ export default {
|
|||||||
this.focus = false
|
this.focus = false
|
||||||
this.triggerBlur(e)
|
this.triggerBlur(e)
|
||||||
}
|
}
|
||||||
if (this.NFormItem) {
|
|
||||||
this.dispatch('NFormItem', 'form-item-blur', e.target.value)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
handleInputFocus (e) {
|
handleInputFocus (e) {
|
||||||
this.$emit('input-focus')
|
this.$emit('input-focus')
|
||||||
@ -347,9 +339,6 @@ export default {
|
|||||||
this.$emit('keyup', e)
|
this.$emit('keyup', e)
|
||||||
},
|
},
|
||||||
handleChange (e) {
|
handleChange (e) {
|
||||||
if (this.NFormItem) {
|
|
||||||
this.dispatch('NFormItem', 'form-item-change', e.target.value)
|
|
||||||
}
|
|
||||||
this.$emit('change', e.target.value)
|
this.$emit('change', e.target.value)
|
||||||
},
|
},
|
||||||
handleClick (e) {
|
handleClick (e) {
|
||||||
|
24
packages/mixins/asformitem.js
Normal file
24
packages/mixins/asformitem.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export default function (events = {
|
||||||
|
change: 'change',
|
||||||
|
blur: 'blur',
|
||||||
|
focus: 'focus',
|
||||||
|
input: 'input'
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
inject: {
|
||||||
|
NFormItem: {
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
Object.keys(events).forEach(event => {
|
||||||
|
const asEvent = events[event]
|
||||||
|
this.$on(event, function (value) {
|
||||||
|
if (this.NFormItem) {
|
||||||
|
this.NFormItem.$emit(asEvent, value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,13 +6,15 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: rgba(255, 255, 255, 1);
|
color: rgba(255, 255, 255, 1);
|
||||||
@include m(inline) {
|
@include m(inline) {
|
||||||
width: auto;
|
width: 100%;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
align-content: space-around;
|
align-content: space-around;
|
||||||
flex-wrap: nowrap;
|
@include b(form-item) {
|
||||||
.n-form-item:not(:last-child) {
|
width: auto;
|
||||||
margin-right: 10px;
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.n-form-item__label--top {
|
.n-form-item__label--top {
|
||||||
@ -71,21 +73,25 @@
|
|||||||
height: 22px;
|
height: 22px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
flex-grow: 0;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
@include e(span) {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@include b(form-item-content) {
|
@include b(form-item-content) {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
@include b(form-item-explain) {
|
@include b(form-item-explain) {
|
||||||
min-height: 22px;
|
box-sizing: border-box;
|
||||||
|
margin-top: 4px;
|
||||||
|
min-height: 20px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: rgba(255, 146, 164, 1);
|
color: rgba(255, 146, 164, 1);
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
|
padding-left: 2px;
|
||||||
|
transform-origin: top left;
|
||||||
|
@include e(content) {
|
||||||
|
display: inline-block;
|
||||||
|
@include fade-down-transition($from-offset: -3px);
|
||||||
|
// @include fade-in-scale-up-transition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.n-form-item__content--pass {
|
.n-form-item__content--pass {
|
||||||
.n-form-item__validate {
|
.n-form-item__validate {
|
||||||
|
@ -220,20 +220,37 @@ $default-cubic-bezier: cubic-bezier(.4, 0, .2, 1);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin fade-down-transition ($name: 'fade-down', $from-offset: -4px) {
|
||||||
|
&.#{$namespace}-#{$name}-enter, &.#{$namespace}-#{$name}-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY($from-offset);
|
||||||
|
}
|
||||||
|
&.#{$namespace}-#{$name}-enter-to, &.#{$namespace}-#{$name}-leave {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
&.#{$namespace}-#{$name}-leave-active {
|
||||||
|
transition: opacity .3s $default-cubic-bezier, transform .3s $default-cubic-bezier;
|
||||||
|
}
|
||||||
|
&.#{$namespace}-#{$name}-enter-active {
|
||||||
|
transition: opacity .3s $default-cubic-bezier, transform .3s $default-cubic-bezier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@mixin fade-up-transition($block) {
|
@mixin fade-up-transition($block) {
|
||||||
.#{$namespace}-#{$block}--transition-enter, .#{$namespace}-#{$block}--transition-leave-to {
|
&.#{$namespace}-#{$block}--transition-enter, .#{$namespace}-#{$block}--transition-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(4px);
|
transform: translateY(4px);
|
||||||
}
|
}
|
||||||
.#{$namespace}-#{$block}--transition-leave-active {
|
&.#{$namespace}-#{$block}--transition-leave-active {
|
||||||
transition: opacity .3s $slow-out-cubic-bezier, transform .3s $slow-out-cubic-bezier;
|
transition: opacity .3s $slow-out-cubic-bezier, transform .3s $slow-out-cubic-bezier;
|
||||||
}
|
}
|
||||||
.#{$namespace}-#{$block}--transition-enter-active {
|
&.#{$namespace}-#{$block}--transition-enter-active {
|
||||||
transition: opacity .3s $fast-in-cubic-bezier, transform .3s $fast-in-cubic-bezier;
|
transition: opacity .3s $fast-in-cubic-bezier, transform .3s $fast-in-cubic-bezier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin fade-in-scale-up-transition($block: 'fade-in-scale-up', $origin: inherit, $duration: .2s) {
|
@mixin fade-in-scale-up-transition($block: 'fade-in-scale-up', $origin: inherit, $duration: .2s, $start-scale: 0.9) {
|
||||||
&.#{$namespace}-#{$block}--transition-leave-active {
|
&.#{$namespace}-#{$block}--transition-leave-active {
|
||||||
transform-origin: $origin;
|
transform-origin: $origin;
|
||||||
transition: opacity $duration $slow-out-cubic-bezier, transform $duration $slow-out-cubic-bezier;
|
transition: opacity $duration $slow-out-cubic-bezier, transform $duration $slow-out-cubic-bezier;
|
||||||
@ -244,7 +261,7 @@ $default-cubic-bezier: cubic-bezier(.4, 0, .2, 1);
|
|||||||
}
|
}
|
||||||
&.#{$namespace}-#{$block}--transition-enter, &.#{$namespace}-#{$block}--transition-leave-to {
|
&.#{$namespace}-#{$block}--transition-enter, &.#{$namespace}-#{$block}--transition-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: scale(.9);
|
transform: scale($start-scale);
|
||||||
}
|
}
|
||||||
&.#{$namespace}-#{$block}--transition-leave, &.#{$namespace}-#{$block}--transition-enter-to {
|
&.#{$namespace}-#{$block}--transition-leave, &.#{$namespace}-#{$block}--transition-enter-to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user