介绍
本文用作个人学习记录
核心作用: 能让vue组件通过api方式调用的插件; 用法介绍:
源码理解
这里主要是基于cube-ui和vue-create-api源码进行create-api原理的解析
首先cube-ui中使用create-api的方式:
export default function createAPI (Vue, Component, events, single) {
Vue.use(createAPIComponent, {componentPrefix: 'cube-'})
const api = Vue.createAPI(Component, events, single)
return api
}
然后会在cube-ui组件(modules文件夹下)中使用:
export default function addDialog (Vue, Dialog) {
createAPI(Vue, Dialog, ['confirm', 'cancel', 'close', 'btn-click', 'link-click'], true)
}
接下来我们解释下上面代码的含义,在Vue.use中会执行vue-create-api中导出的install方法,代码如下:
function install(Vue, options = {}) {
const {componentPrefix = '', apiPrefix = '$create-'} = options
Vue.createAPI = function (Component, events, single) {
if (isBoolean(events)) {
single = events
events = []
}
const api = apiCreator.call(this, Component, events, single)
const createName = processComponentName(Component, {
componentPrefix,
apiPrefix,
})
Vue.prototype[createName] = Component.$create = api.create
return api
}
}
这里会在 Vue 构造器下添加一个 createAPI 方法。提供三个参数,Component 组件、 events 事件数组、 single 是否采用单例模式实例化组件。最后将api.create赋给Component.$create和Vue.prototype[createName],这也是为什么调用组件有两种方式的原因。
function processComponentName(Component, options) {
const {componentPrefix, apiPrefix} = options
const name = Component.name
assert(name, 'Component must have name while using create-api!')
const prefixReg = new RegExp(`^${escapeReg(componentPrefix)}`, 'i')
const pureName = name.replace(prefixReg, '')
let camelizeName = `${camelize(`${apiPrefix}${pureName}`)}`
return camelizeName
}
这是processComponentName方法源码,所以使用create-api的组件一定要声明name属性,要不然会报错。
然后我们看下install返回的的api到底是什么,看下apiCreator方法也就是creator.js文件。这也是最核心的部分,接下来解析整体的处理流程:
首先我们看最基本方法内容:
可以看到这个方法输出的是一个api,那么这个api是什么呢,我们可以看下:
里面定义了两个方法before和create方法,before方法是一个钩子函数会在组件创建的时候被调用,create方法则是被调用的方法。
下面看create方法的实现:
这里是判断是否是使用this.create调用。
然后看核心执行部分:
解析数据
先是处理了用户传入的config,parseRenderData将用户传入的配置遍历分类,分离出props和on对象(源码如下)。
events是调用createAPI是传入的config是使用组件时传入的。
这里遍历选出传入的配置中是否有events中定义的事件名,然后加到on对象中,events会被parseEvents处理加上on前缀和驼峰命名。
监听参数
使用vue原型的方式调用的话,如果依赖了实例的响应数据则使用vue的实例方法$watch监听,指定对应回调函数onChange。同时也把数据给到renderData(渲染数据)中。
监听事件
如果传入的是string则寻找vue实例上定义的方法,给到renderData。
自定义组件配置
可以使用$开头的自定义配置,同样会加到renderData中,后续会给到createElement方法的第二个参数创建组件。
创建组件实例
主要做了几件事:
- 判断是否需要使用单例
- 创建组件实例
- 给组件添加方法,控制展示(show hide remove)
最后看下如何创建组件实例:
创建一个Vue实例,使用createElement传入处理完的配置创建Vnode,更新渲染数据,执行$mount和init挂载真实DOM到body上。
最后回到creator.js文件,监听’hook:beforeDestroy‘销毁监听事件和实例。
参考文档
介绍文档:didi.github.io/cube-ui/#/z…
create-api:juejin.cn/post/684490…