vue-formulate
-
解决了什么?
快速创建表单,上手成本低只需要了解两个基本表单类型(fomrmulateInput和formulateForm) vue-formulate -
实现原理清晰,插件包的形式生成实例
原理图

vue所需知识前置
- 实例加载顺序
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
- vue插件包如何编写
vue通过Vue.use把包注册使用
install (Vue, options) {
Vue.prototype.$formulate = this
this.options = this.defaults
var plugins = this.defaults.plugins
if (options && Array.isArray(options.plugins) && options.plugins.length) {
plugins = plugins.concat(options.plugins)
}
plugins.forEach(plugin => (typeof plugin === 'function') ? plugin(this) : null)
this.extend(options || {})
for (var componentName in this.options.components) {
Vue.component(componentName, this.options.components[componentName])
}
}
- provide & inject 父级抛出方法,子级或更低级想使用可以自己inject,
// formulatform
provide () {
return {
formulateFormSetter: this.setFieldValue,
formulateFormRegister: this.register,
getFormValues: this.getFormValues,
observeErrors: this.addErrorObserver,
removeErrorObserver: this.removeErrorObserver
}
},
// formulateInput
inject: {
formulateFormSetter: { default: undefined },
formulateFormRegister: { default: undefined },
getFormValues: { default: () => () => ({}) }
},
-
inheritAttrs设置成false
组件将不会把未被注册的props呈现为普通的HTML属性,$attrs 将所有传入的prop都拿到 -
model自定义
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:
6 $emit
触发当前实例上的事件。附加参数都会传给监听器回调
总结
- 维护一份实例如何做到子级实例注册到父级身上,还能做到解耦,通过provide & inject去实现。
- 如何快速复用共享方法,通过注册到vue实例。
- 如何复用基础方法类型,通过组件的computed 把当前实例this通过function.call的方式快速实现模板复用。
- 通过promise.all使多次校验进行后再统一修改状态,避免多次渲染
performValidation () {
// 把校验函数和参数处理好
const rules = parseRules(this.validation, this.$formulate.rules(this.parsedValidationRules))
// 通过promise的all把所有该校验的都一次过校验完后再触发渲染
this.pendingValidation = Promise.all(
rules.map(([rule, args]) => {
var res = rule({
value: this.context.model,
getFormValues: this.getFormValues.bind(this),
name: this.context.name
}, ...args)
res = (res instanceof Promise) ? res : Promise.resolve(res)
return res.then(res => res ? false : this.getValidationMessage(rule, args))
})
)
.then(result => result.filter(result => result))
.then(errorMessages => { this.validationErrors = errorMessages })
return this.pendingValidation
},
感谢以及参考链接
第一次写作,肯定有很多不足的地方,希望海涵。如果你有不清楚的地方或者认为我有写错的地方,欢迎评论区交流。