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"
|
||||
ref="form"
|
||||
>
|
||||
<n-form-item label="Name" path="name">
|
||||
<n-input v-model="formValue.name" placeholder="Input Name" />
|
||||
<n-form-item label="Name" path="user.name" required>
|
||||
<n-input v-model="formValue.user.name" placeholder="Input Name" />
|
||||
</n-form-item>
|
||||
<n-form-item label="Age" path="age">
|
||||
<n-input placeholder="Input Age" v-model="formValue.age"/>
|
||||
<n-form-item label="Age" path="user.age" required>
|
||||
<n-input placeholder="Input Age" v-model="formValue.user.age"/>
|
||||
</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-form-item>
|
||||
<n-form-item v-model="formValue.phone">
|
||||
@ -29,8 +29,10 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
formValue: {
|
||||
user: {
|
||||
name: '',
|
||||
age: '',
|
||||
age: ''
|
||||
},
|
||||
phone: ''
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,12 @@
|
||||
>
|
||||
<slot />
|
||||
<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>
|
||||
@ -131,10 +136,17 @@ export default {
|
||||
},
|
||||
synthesizedRules () {
|
||||
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) {
|
||||
rules.push({
|
||||
trigger: 'blur',
|
||||
required: true
|
||||
trigger: ['blur', 'change', 'input'],
|
||||
required: true,
|
||||
validator
|
||||
})
|
||||
}
|
||||
if (this.rule) {
|
||||
@ -156,6 +168,11 @@ export default {
|
||||
}
|
||||
},
|
||||
created () {
|
||||
/**
|
||||
* This is buggy!
|
||||
* Because if it's child change, rules is not updated
|
||||
* However I need to make it work first
|
||||
*/
|
||||
this.addValidationEventListeners()
|
||||
},
|
||||
methods: {
|
||||
@ -165,6 +182,12 @@ export default {
|
||||
handleContentChange () {
|
||||
this.validate('change')
|
||||
},
|
||||
handleContentFocus () {
|
||||
this.validate('focus')
|
||||
},
|
||||
handleContentInput () {
|
||||
this.validate('input')
|
||||
},
|
||||
validate (trigger = null, callback = null) {
|
||||
if (!this.path) {
|
||||
return
|
||||
@ -172,10 +195,17 @@ export default {
|
||||
const rules = this.synthesizedRules
|
||||
const path = this.path
|
||||
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
|
||||
const asyncValidator = new AsyncValidator({ [path]: activeRules })
|
||||
asyncValidator.validate({ [path]: value }, (errors, fields) => {
|
||||
console.log('validate', errors, fields)
|
||||
if (errors) {
|
||||
this.explain = errors[0].message
|
||||
this.validated = true
|
||||
@ -192,8 +222,10 @@ export default {
|
||||
addValidationEventListeners () {
|
||||
const rules = this.synthesizedRules
|
||||
if (rules.length >= 0) {
|
||||
this.$on('form-item-blur', this.handleContentBlur)
|
||||
this.$on('form-item-change', this.handleContentChange)
|
||||
this.$on('blur', this.handleContentBlur)
|
||||
this.$on('input', this.handleContentInput)
|
||||
this.$on('focus', this.handleContentFocus)
|
||||
this.$on('change', this.handleContentChange)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ export default {
|
||||
},
|
||||
labelPosition: {
|
||||
type: String,
|
||||
default: 'top' // ['top', 'right', 'left', 'center']
|
||||
default: 'top'
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
|
@ -124,22 +124,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Emitter from '../../../mixins/emitter'
|
||||
import NCancelMark from '../../../base/CancelMark'
|
||||
import withapp from '../../../mixins/withapp'
|
||||
import themeable from '../../../mixins/themeable'
|
||||
import asformitem from '../../../mixins/asformitem'
|
||||
|
||||
export default {
|
||||
name: 'NInput',
|
||||
components: {
|
||||
NCancelMark
|
||||
},
|
||||
mixins: [ withapp, themeable, Emitter ],
|
||||
inject: {
|
||||
NFormItem: {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
mixins: [ withapp, themeable, asformitem() ],
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
@ -322,9 +317,6 @@ export default {
|
||||
this.focus = false
|
||||
this.triggerBlur(e)
|
||||
}
|
||||
if (this.NFormItem) {
|
||||
this.dispatch('NFormItem', 'form-item-blur', e.target.value)
|
||||
}
|
||||
},
|
||||
handleInputFocus (e) {
|
||||
this.$emit('input-focus')
|
||||
@ -347,9 +339,6 @@ export default {
|
||||
this.$emit('keyup', e)
|
||||
},
|
||||
handleChange (e) {
|
||||
if (this.NFormItem) {
|
||||
this.dispatch('NFormItem', 'form-item-change', e.target.value)
|
||||
}
|
||||
this.$emit('change', e.target.value)
|
||||
},
|
||||
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;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
@include m(inline) {
|
||||
width: auto;
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
align-items: flex-end;
|
||||
align-content: space-around;
|
||||
flex-wrap: nowrap;
|
||||
.n-form-item:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
@include b(form-item) {
|
||||
width: auto;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.n-form-item__label--top {
|
||||
@ -71,21 +73,25 @@
|
||||
height: 22px;
|
||||
box-sizing: border-box;
|
||||
font-size: 13px;
|
||||
flex-grow: 0;
|
||||
overflow-wrap: break-word;
|
||||
@include e(span) {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
@include b(form-item-content) {
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
}
|
||||
@include b(form-item-explain) {
|
||||
min-height: 22px;
|
||||
box-sizing: border-box;
|
||||
margin-top: 4px;
|
||||
min-height: 20px;
|
||||
line-height: 1.5;
|
||||
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__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) {
|
||||
.#{$namespace}-#{$block}--transition-enter, .#{$namespace}-#{$block}--transition-leave-to {
|
||||
&.#{$namespace}-#{$block}--transition-enter, .#{$namespace}-#{$block}--transition-leave-to {
|
||||
opacity: 0;
|
||||
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;
|
||||
}
|
||||
.#{$namespace}-#{$block}--transition-enter-active {
|
||||
&.#{$namespace}-#{$block}--transition-enter-active {
|
||||
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 {
|
||||
transform-origin: $origin;
|
||||
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 {
|
||||
opacity: 0;
|
||||
transform: scale(.9);
|
||||
transform: scale($start-scale);
|
||||
}
|
||||
&.#{$namespace}-#{$block}--transition-leave, &.#{$namespace}-#{$block}--transition-enter-to {
|
||||
opacity: 1;
|
||||
|
Loading…
Reference in New Issue
Block a user