navieUI源码学习 发表于 2023-12-15 更新于 2024-02-01
宁波
IT Vue 源码 navieUI源码学习 观默 2023-12-15 2024-02-01 前置知识
从 Message 组件开始 首先我们来看一下 NavieUI 文档中对 Message 组件的使用:
1 2 3 <n-message-provider> <content /> </n-message-provider>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import { useMessage } from "naive-ui" ;import { defineComponent } from "vue" ;export default defineComponent ({ setup ( ) { const message = useMessage (); return { warning ( ) { message.warning ("..." ); }, }; }, });
Message 组件中有这样一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const api : MessageApiInjection = { info (content: string , options: MessageOptions ) { return create (content, { ...options, type : "info" }); }, success (content: string , options: MessageOptions ) { return create (content, { ...options, type : "success" }); }, warning (content: string , options: MessageOptions ) { return create (content, { ...options, type : "warning" }); }, error (content: string , options: MessageOptions ) { return create (content, { ...options, type : "error" }); }, loading (content: string , options: MessageOptions ) { return create (content, { ...options, type : "loading" }); }, }; provide<MessageApiInjection >("message" , api);
上面代码中的provide在官方文档 中的描述为:提供一个值,可以被后代组件注入。 provide 作为值的提供者,需要使用inject来使用值。 所以外层的MessageProvider组件就是provide的提供者,里面包含了Message组件的api属性。
1 2 3 4 5 6 7 export function useMessage ( ): MessageApiInjection { const api = inject<MessageApiInjection >("message" ); if (api === undefined ) { throwError ("use-message" , "No out <n-message-provider /> founded." ); } return api; }
create函数则是在MessageProvider内部追加了 message 消息:messageListRef.value.push(messageReactive),然后由render函数对消息列表进行遍历渲染。
表单组件 表单验证 1 2 3 4 5 6 7 8 9 10 11 const formItemValidationPromises = [];for (const key of keysOf (formItems)) { const formItemInstances = formItems[key]; for (const formItemInstance of formItemInstances) { if (formItemInstance.path ) { formItemValidationPromises.push ( formItemInstance.internalValidate (null , shouldRuleBeApplied) ); } } }
上述代码中formItems是又是通过provide提供给子组件,然后子组件通过inject注入,然后子组件通过useFormItem来使用FormItem的实例。 如果深挖获取获取实例的方式,会看到如下这段代码:const vm = getCurrentInstance()?.proxy;,正如方法名所示,getCurrentInstance获取当前实例。
internalValidate方法则是基于async-validator库来实现的,具体不做展开。