refactor: use asformitem instead of emitter mixin

This commit is contained in:
07akioni 2019-11-07 21:35:26 +08:00
parent 986ecb3de4
commit 23eda5b40c
13 changed files with 58 additions and 88 deletions

View File

@ -11,14 +11,18 @@
<n-row>
<n-col :span="24">
<n-form-item path="password" label="Password">
<n-input v-model="model.password" @input="handlePasswordInput"/>
<n-input v-model="model.password" @input="handlePasswordInput" type="password"/>
</n-form-item>
</n-col>
</n-row>
<n-row>
<n-col :span="24">
<n-form-item path="reenteredPassword" label="Re-enter Password" ref="reenteredPassword">
<n-input v-model="model.reenteredPassword"/>
<n-form-item
path="reenteredPassword"
label="Re-enter Password"
ref="reenteredPassword"
>
<n-input v-model="model.reenteredPassword" type="password"/>
</n-form-item>
</n-col>
</n-row>
@ -48,16 +52,16 @@ export default {
age: [
{
validator (rule, value) {
return /\d+/.test(value)
return /^\d*$/.test(value)
},
message: 'Age should be an integer',
message: 'Please input an integer',
trigger: 'input'
},
{
validator (rule, value) {
return Number(value) > 18
},
message: 'Age should be greater than 18',
message: 'Age should be above 18',
trigger: 'input'
}
],
@ -70,7 +74,7 @@ export default {
{
validator: this.validatePasswordSame,
message: 'Password is not same as re-entered password!',
trigger: 'blur'
trigger: ['blur', 'password-input']
},
{
required: true,
@ -82,7 +86,9 @@ export default {
},
methods: {
handlePasswordInput () {
this.$refs.reenteredPassword.validate('input')
if (this.model.reenteredPassword) {
this.$refs.reenteredPassword.validate('password-input')
}
},
handleValidateButtonClick (e) {
e.preventDefault()

View File

@ -1,8 +1,12 @@
<script>
import asformitem from '../../../mixins/asformitem'
export default {
name: 'NCheckboxGroup',
mixins: [ asformitem() ],
provide () {
return {
NFormItem: null,
NCheckboxGroup: this
}
},

View File

@ -36,6 +36,7 @@
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
import hollowoutable from '../../../mixins/hollowoutable'
import asformitem from '../../../mixins/asformitem'
import CheckMark from './CheckMark'
import LineMark from './LineMark'
import collectable from '../../../mixins/collectable'
@ -55,6 +56,7 @@ export default {
withapp,
themeable,
hollowoutable,
asformitem(),
collectable('NCheckboxGroup', 'collectedCheckboxValues')
],
model: {

View File

@ -41,7 +41,7 @@
</div>
</template>
<script>
import AsyncValidator from 'async-validator'
import Schema from 'async-validator'
import get from 'lodash/get'
import registerable from '../../../mixins/registerable'
import withapp from '../../../mixins/withapp'
@ -75,6 +75,10 @@ export default {
type: String,
default: null
},
first: {
type: Boolean,
default: false
},
rulePath: {
type: String,
default: null
@ -192,10 +196,15 @@ export default {
handleContentInput () {
this.validate('input')
},
validate (trigger = null) {
validate (trigger = null, options = null) {
if (!this.path) {
return
}
if (!options) {
options = {}
options.first = this.first
options.supressWarning = this.supressWarning
}
const rules = this.synthesizedRules
const path = this.path
const value = get(this.NForm.model, this.path, null)
@ -207,8 +216,8 @@ export default {
}
})
if (!activeRules.length) return
const validator = new AsyncValidator({ [path]: activeRules })
validator.validate({ [path]: value }, {}, (errors, fields) => {
const validator = new Schema({ [path]: activeRules })
validator.validate({ [path]: value }, options, (errors, fields) => {
// console.log('validate', errors, fields)
if (errors && errors.length) {
this.explains = errors.map(error => error.message)

View File

@ -134,7 +134,12 @@ export default {
components: {
NCancelMark
},
mixins: [ withapp, themeable, asformitem() ],
mixins: [ withapp, themeable, asformitem({
change: 'change',
blur: 'blur',
focus: 'focus',
input: 'input'
})],
props: {
type: {
type: String,

View File

@ -49,9 +49,9 @@
<script>
import NIcon from '../../Icon/index'
import Emitter from '../../../mixins/emitter'
import themeable from '../../../mixins/themeable'
import withapp from '../../../mixins/withapp'
import asformitem from '../../../mixins/asformitem'
import mdRemove from '../../../icons/md-remove'
import mdAdd from '../../../icons/md-add'
@ -77,7 +77,7 @@ export default {
mdRemove,
mdAdd
},
mixins: [ withapp, themeable, Emitter ],
mixins: [ withapp, themeable, asformitem() ],
inject: {
NFormItem: {
default: null
@ -161,7 +161,6 @@ export default {
const adjustedValue = this.adjustValue(newValue)
if (adjustedValue === newValue) {
this.$emit('change', newValue, oldValue)
this.formBlur('change', newValue)
} else {
this.$emit('input', adjustedValue)
}
@ -174,11 +173,6 @@ export default {
}
e.preventDefault()
},
formBlur (type, val) {
if (this.NFormItem) {
this.dispatch('NFormItem', 'on-form-' + type, val)
}
},
handleFocus (e) {
this.$emit('focus', e, this.value)
},
@ -234,7 +228,6 @@ export default {
e.target.value = value
this.$emit('input', value)
this.$emit('blur', e, value)
this.formBlur('blur', value)
}
}
}

View File

@ -2,26 +2,12 @@
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
import hollowoutable from '../../../mixins/hollowoutable'
import asformitem from '../../../mixins/asformitem'
function mapSlot (h, defaultSlot, currentComponent) {
/**
* connect current component's v-model to child instance
*/
// const wrapInstance = instance => {
// if (instance.componentOptions.tag === 'n-radio' || instance.componentOptions.tag === 'n-radio-button') {
// instance.componentOptions.propsData.privateValue = currentComponent.value
// instance.componentOptions.listeners = {
// ...instance.componentOptions.listeners,
// input: (v) => {
// currentComponent.$emit('input', v)
// }
// }
// return instance
// } else return null
// }
const mappedSlot = []
for (let i = 0; i < defaultSlot.length; ++i) {
const wrappedInstance = defaultSlot[i] // wrapInstance(defaultSlot[i])
const wrappedInstance = defaultSlot[i]
if (wrappedInstance === null) {
console.error('[naive ui]: Please don\'t use tags other than `n-radio` and `n-radio-button` in `n-radio-group`.')
continue
@ -34,7 +20,6 @@ function mapSlot (h, defaultSlot, currentComponent) {
const lastInstanceDisabled = lastInstanceComponentOptions.propsData.disabled
const currentInstanceChecked = currentComponent.$props.value === wrappedInstance.componentOptions.propsData.value
const currentInstanceDisabled = wrappedInstance.componentOptions.propsData.disabled
let lastInstancePriority
let currentInstancePriority
if (currentComponent.synthesizedTheme === 'dark') {
@ -82,7 +67,7 @@ function mapSlot (h, defaultSlot, currentComponent) {
export default {
name: 'NRadioGroup',
mixins: [withapp, themeable, hollowoutable],
mixins: [withapp, themeable, hollowoutable, asformitem()],
provide () {
return {
NRadioGroup: this

View File

@ -23,13 +23,13 @@
</template>
<script>
import Emitter from '../../../mixins/emitter'
import asformitem from '../../../mixins/asformitem'
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
export default {
name: 'NRadio',
mixins: [ withapp, themeable, Emitter ],
mixins: [ withapp, themeable, asformitem() ],
model: {
prop: 'privateValue',
event: 'input'
@ -37,9 +37,6 @@ export default {
inject: {
NRadioGroup: {
default: null
},
NFormItem: {
default: null
}
},
props: {
@ -65,6 +62,11 @@ export default {
}
}
},
watch: {
value (value, oldValue) {
this.$emit('change', value, oldValue)
}
},
methods: {
handleKeyUpEnter () {
this.toggle()
@ -77,9 +79,6 @@ export default {
if (this.disabled) return
if (this.privateValue !== this.value) {
this.emitValue('input', this.value)
if (this.NFormItem) {
this.dispatch('NFormItem', 'form-item-change', this.value)
}
}
},
emitValue () {

View File

@ -94,6 +94,7 @@ import detachable from '../../../mixins/detachable'
import placeable from '../../../mixins/placeable'
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
import asformitem from '../../../mixins/asformitem'
function handleFirstHandleMouseMove (e) {
const railRect = this.$refs.rail.getBoundingClientRect()
@ -117,7 +118,7 @@ function handleSecondHandleMouseMove (e) {
export default {
name: 'NSlider',
mixins: [withapp, themeable, hollowoutable, detachable, placeable],
mixins: [withapp, themeable, hollowoutable, detachable, placeable, asformitem()],
props: {
marks: {
type: Object,

View File

@ -15,13 +15,13 @@
</template>
<script>
import Emitter from '../../../mixins/emitter'
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
import asformitem from '../../../mixins/asformitem'
export default {
name: 'NSwitch',
mixins: [ withapp, themeable, Emitter ],
mixins: [ withapp, themeable, asformitem() ],
inject: {
NFormItem: {
default: null
@ -46,9 +46,6 @@ export default {
handleClick () {
if (!this.disabled) {
this.$emit('input', !this.value)
if (this.NFormItem) {
this.dispatch('NFormItem', 'form-item-change', !this.value)
}
}
}
}

View File

@ -138,6 +138,7 @@ import clickoutside from '../../../directives/clickoutside'
import zindexable from '../../../mixins/zindexable'
import withapp from '../../../mixins/withapp'
import themeable from '../../../mixins/themeable'
import asformitem from '../../../mixins/asformitem'
import isValid from 'date-fns/isValid'
import startOfSecond from 'date-fns/startOfSecond'
import startOfMinute from 'date-fns/startOfMinute'
@ -194,7 +195,7 @@ export default {
directives: {
clickoutside
},
mixins: [detachable, placeable, zindexable, withapp, themeable],
mixins: [detachable, placeable, zindexable, withapp, themeable, asformitem()],
props: {
placement: {
type: String,

View File

@ -1,8 +1,7 @@
export default function (events = {
change: 'change',
blur: 'blur',
focus: 'focus',
input: 'input'
focus: 'focus'
}) {
return {
inject: {

View File

@ -1,31 +0,0 @@
function broadcast (componentName, eventName, params) {
this.$children.forEach(child => {
let name = child.$options.name
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params))
} else {
broadcast.apply(child, [componentName, eventName].concat([params]))
}
})
}
export default {
methods: {
dispatch (componentName, eventName, params) {
let parent = this.$parent || this.$root
let name = parent.$options.name
while (parent && (!name || name !== componentName)) {
parent = parent.$parent
if (parent) {
name = parent.$options.name
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params))
}
},
broadcast (componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params)
}
}
}