import * as vue from 'vue'; /** 该文件以Vue3版本的适配器为依据,编写了本声明,本文涉及以下术语: * instance : 即一个Vue3组件实例, conext, attrs,emit等很多属性 * vm,parentVm : 适配器封装的一个数据结构,具有大量$属性,以及组件上其它属性 * emitter : 适配器中,自己封装的一个EventBus对象,和instance.emit没关系。 vm.$emit 会同时触发 instance.emit和instance.$emitter。 * subTree : instance.subTree 是组件当前的vnode描述 */ /** hooks 变量: renderless的第二个参数 */ type ISharedRenderlessParamHooks = typeof vue; /** utils变量: renderless的第三个参数 */ interface ISharedRenderlessParamUtils { /** 当前使用的框架 */ framework: 'vue3' | 'vue2' | 'vue2.7'; /** 组件前缀,默认为 Tiny */ $prefix: string; /** 所有规范的配置 */ globalDesignConfig: { components?: IComponentDesignConfig; name?: string; version?: string; }; /** 当前组件的规范配置 */ designConfig: IComponentDesignConfig; /** app的root上的i18n对象,renderless基本没有使用它 */ i18n: any; /** 组件内国际化,常用函数 */ t: (path: string, options?: any) => string; /** 组件模式。 * @mark 等同于 vm.$mode, 取值为:pc mobile mobile-first */ mode: 'pc' | 'mobile' | 'mobile-first'; /** 是否为 mobile */ isMobileMode: boolean; /** 是否为 pc */ isPCMode: boolean; /** 是否为mobile-first */ isMobileFirstMode: boolean; /** vue组件实例的context.attrs */ attrs: any; /** 返回组件props._constants */ constants: CT; /** vue的内置nextTick, 其实可以从第二参 hooks中获取, 还可以通过当前vm.$nextTick来获取 */ nextTick: typeof vue.nextTick; /** parentVm */ parent: ITinyVm; /** 当前vm */ vm: ITinyVm; /** 第一次mount加载后的所有refs,不会更新! ⭐要避免使用 */ refs: Record; /** 组件初化时的页面路由,不会更新! * @mark ⭐要避免使用, 请使用vm.$refs */ route: any; /** 当前的router实例。 从app的根上读取 */ router: any; /** 从app的根上读取: root?.$service, 用户必须引用服务适配器的包, 并传入app后,才有该变量 */ service: any; /** 调用从app的根上$getService: root?.$getService(vm) */ getService: any; /** 返回 instance.slots。 vue2,vue3的这2个属性是同一个引用: scopedSlots===slots。 */ slots: Record; /** 返回 instance.slots */ scopedSlots: Record; /** 向实例的 subTree.children 深度遍历发送广播消息。 如果component找到了触发component.emit(eventName, params) * @param componentName 组件名 */ broadcast: (componentName: string, eventName: string, params?: any) => void; /** 向实例的 parent开始查找componentName, 找到匹配第一个组件, 触发component.emit(eventName, params) */ dispatch: (componentName: string, eventName: string, params?: any) => void; /** 向实例的subTree 遍历。 * 1、handler 是函数: handler入参{level,vm,el,options,isLevel1}. 给每个子节点遍历调用函数。 * 2、handler 是非函数: 直接通过 instance.subTree 来生成一个同等树状的vm数据。 * @mark ⭐全局有4个组件使用到`handler是函数`的用法 ,用于遍历子节点,将符合条件的信息收集到一个数组中。 */ childrenHandler: (handler?: (node: { level: number; vm: ITinyVm; el: any; options: any; isLevel1: any; }) => void) => void | any[]; /** 向实例的 parent 遍历。 * 1、handler 是函数: handler入参{level,vm,el,options}. 遍历父节点。若handler处理某个节点时,返回true,则停止! * 2、handler 是非函数: 直接返回{level,vm,el,options} 的数据体。 * @mark ⭐全局未有使用该函数 */ parentHandler: (handler?: () => boolean) => void | any; /** 给 instance.parent 的ctx 赋值,同时给parentVm 赋值。 适配器的内部方法⭐要避免使用 */ setParentAttribute: ({ name, value }: { name: any; value: any; }) => void; /** 给 vm 和 instance.ctx 同时添加属性。 * @param props Object.defineProperties的第2参, 格式:{ property1: {value: 42,writable: true},property2: {...} } */ defineInstanceProperties: (props: PropertyDescriptorMap & ThisType) => void; /** 给parentVm 添加属性。 */ defineParentInstanceProperties: (props: PropertyDescriptorMap & ThisType) => void; /** 返回 context.emit */ emit: (event: any, ...args: any[]) => void; /** Tiny 适配器中,自行封装的一个 EventBus模型的工厂函数。⭐每次调用才返回一个新的模型对象。 * @mark vm中,会给instance添加一个$emitter=emitter() ,就是该函数返回的模型。 vm中的$on, $off,$once 都是该模型的方法。 * @mark ⭐所以不要直接使用该函数。 */ emitter: () => { emit: (eventname: string) => void; on: (eventname: string, callback: Function, once?: boolean) => void; off: (eventname: string, callback: Function) => void; once: (eventname: string, callback: Function) => void; }; /** 合并 tailwind 类 */ mergeClass: (...cssClasses: any[]) => string; } /** vue.ts的一个混合上下文,也是index.ts 文件中二层函数的入参混合体。 */ type ISharedRenderlessFunctionParams = { api: object; props: object; state: object; } & ISharedRenderlessParamHooks & ISharedRenderlessParamUtils; /** 单个组件的规范的配置 */ interface IComponentDesignConfig { icons?: Record; renderless?: (props: any, hooks: ISharedRenderlessParamHooks, utils: ISharedRenderlessParamUtils, sdk: any) => any; [otherKey: string]: any; } /** Tiny-Vue的Adapter 内部为组件创建的Vm */ interface ITinyVm { /** 从instance.attrs上, 过滤出所有的非函数的attrs */ $attrs: Record; /** 从instance.attrs上, 过滤出所有的函数的attrs, 并对大驼峰属性名转化为下划线名 */ $listeners: Record; /** 返回instance.subTree的同等树状的vm数据 */ $children: any[]; /** 返回 instance.props._constants */ $constants: CT; /** 返回 instance.vnode.el */ $el: HTMLElement; /** 返回 instance._tiny_mode */ $mode: 'pc' | 'mobile' | 'mobile-first'; /** 即 hooks.nextTick */ $nextTick: typeof vue.nextTick; /** 自动触发 instance.emit 和 instance.$emitter 两处地方 */ $emit: (...args: any[]) => void; /** instance.$emitter.off, 不传任何参数则是移除所有事件 */ $off: (eventname?: string, callback?: Function) => void; /** instance.$emitter.on */ $on: (eventname: string, callback: Function) => void; /** instance.$emitter.once */ $once: (eventname: string, callback: Function) => void; /** 返回 instance.type.componentName。 * @mark instance.type 可能是字符串,也可能是组件类,所以只有组件类的时候,才能返回组件的真实名字 */ $options: { componentName: string | undefined; }; /** 返回 instance.parent */ $parent: vue.ComponentPublicInstance; /** 返回 instance.refs, * @mark ⭐ 尽量使用这个,每次都会是最新的refs */ $refs: Record; /** 返回 instance.slots */ $slots: Record; /** 返回 instance.slots */ $scopedSlots: Record; /** 给target赋值。 vue2是调用instance.$set * @mark vue3是响应数据,直接转为 target[propertyName] = value。 * @mark vue2 可能有数据修改不触发响应,就要调用$set去修改值。 * @whenUse ⭐ Vue2组件中修改数据不触发响应时,要使用该$set. instance.$set */ $set: (target: any, propertyName: any, value: any) => void; /** 返回 props.tiny_renderless */ $renderless: Function; /** 返回 props.tiny_template */ $template: any; /** 适配器或组件内,可能会赋值很多其它属性 */ [otherProps: string]: any; } export { ISharedRenderlessFunctionParams, ISharedRenderlessParamHooks, ISharedRenderlessParamUtils, ITinyVm };