Skip to content

feat: ✨ 优化Toast、Message和Notify组件的函数式调用方案#696

Merged
Moonofweisheng merged 1 commit intomasterfrom
feat/improve-functional-calls
Nov 6, 2024
Merged

feat: ✨ 优化Toast、Message和Notify组件的函数式调用方案#696
Moonofweisheng merged 1 commit intomasterfrom
feat/improve-functional-calls

Conversation

@Moonofweisheng
Copy link
Owner

@Moonofweisheng Moonofweisheng commented Nov 5, 2024

解决当前页面存在多次使用useXX时仅最后一次生效的问题

🤔 这个 PR 的性质是?(至少选择一个)

  • 日常 bug 修复
  • 新特性提交
  • 站点、文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • TypeScript 定义更新
  • CI/CD 改进
  • 包体积优化
  • 性能优化
  • 功能增强
  • 国际化改进
  • 代码重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 其他改动(是关于什么的改动?)

🔗 相关 Issue

解决当前页面存在多次使用useXX时仅最后一次生效的问题

💡 需求背景和解决方案

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充

Summary by CodeRabbit

  • 新功能

    • 引入了新的消息和通知选项处理机制,增强了组件的灵活性和反应能力。
    • 新增了获取默认选项键的功能,以便更好地管理消息和通知。
  • 修复

    • 改进了消息框和通知组件的状态管理,确保在不同情况下正确处理选项。
  • 文档

    • 更新了相关组件的导入和导出声明,以反映最新的功能和结构变化。

解决当前页面存在多次使用useXX时仅最后一次生效的问题
@vercel
Copy link

vercel bot commented Nov 5, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
wot-design-uni ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 5, 2024 3:25pm

@coderabbitai
Copy link

coderabbitai bot commented Nov 5, 2024

Walkthrough

该拉取请求对wd-message-boxwd-notifywd-toast组件进行了多项修改,主要集中在消息和通知选项的处理逻辑上。messageDefaultOptionKeytoastDefaultOptionKey的导出常量被更改为局部常量,并引入了表示不存在选项的None符号。新增的getMessageDefaultOptionKeygetToastOptionKey函数用于生成默认选项键。此外,多个组件的逻辑经过调整,以便更好地利用Vue的响应式特性,确保选项的正确管理。最后,一些导出声明被移除。

Changes

文件路径 变更摘要
src/uni_modules/wot-design-uni/components/wd-message-box/index.ts 修改messageDefaultOptionKey为局部常量,引入None符号,更新useMessage逻辑,添加getMessageDefaultOptionKey函数。
src/uni_modules/wot-design-uni/components/wd-message-box/types.ts 更新messageBoxProps中的selector属性,使用makeStringProp('')替代原有的String类型。
src/uni_modules/wot-design-uni/components/wd-message-box/wd-message-box.vue 更新导入语句,使用getMessageDefaultOptionKey替代messageDefaultOptionKey,调整messageOptionKey的生成方式。
src/uni_modules/wot-design-uni/components/wd-notify/index.ts 引入injectref,更新useNotify逻辑,添加None符号。
src/uni_modules/wot-design-uni/components/wd-notify/wd-notify.vue state对象包装为ref,更新对其属性的访问方式以支持响应式。
src/uni_modules/wot-design-uni/components/wd-toast/index.ts 修改toastDefaultOptionKey为局部常量,引入None符号,更新useToast逻辑,添加getToastOptionKey函数。
src/uni_modules/wot-design-uni/components/wd-toast/wd-toast.vue 更新导入语句,使用getToastOptionKey替代toastDefaultOptionKey,调整reset函数逻辑。
src/uni_modules/wot-design-uni/index.ts 移除useToastuseMessageuseQueue的导出声明。

Possibly related PRs

Poem

🐇 在兔子洞中我欢跳,
消息盒子新变化,
选项处理更灵巧,
逻辑清晰如春晓。
兔子祝福齐欢笑,
代码更新乐逍遥! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@netlify
Copy link

netlify bot commented Nov 5, 2024

Deploy Preview for wot-design-uni ready!

Name Link
🔨 Latest commit d603f12
🔍 Latest deploy log https://app.netlify.com/sites/wot-design-uni/deploys/672a38d1bf6b130009193d87
😎 Deploy Preview https://deploy-preview-696--wot-design-uni.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@cloudflare-workers-and-pages
Copy link

Deploying wot-design-uni with  Cloudflare Pages  Cloudflare Pages

Latest commit: d603f12
Status: ✅  Deploy successful!
Preview URL: https://4ba5d71b.wot-design-uni.pages.dev
Branch Preview URL: https://feat-improve-functional-call.wot-design-uni.pages.dev

View logs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (13)
src/uni_modules/wot-design-uni/components/wd-notify/wd-notify.vue (3)

30-30: 建议增强类型安全性

虽然当前的状态注入实现是可行的,但建议添加默认值以增强类型安全性。

建议如下修改:

-const state = inject(getNotifyOptionKey(props.selector), ref<NotifyProps>(props))
+const state = inject(getNotifyOptionKey(props.selector), ref<NotifyProps>(props), true) // 添加 `true` 作为第三个参数确保非空

Also applies to: 42-42


61-71: 建议优化事件处理器实现

当前的事件处理实现有重复模式,建议提取共同逻辑以提高代码复用性。

建议重构如下:

+const emitEvent = (handler: Function | undefined, eventName: string, ...args: any[]) => {
+  if (isFunction(handler)) {
+    return handler(...args)
+  }
+  emits(eventName, ...args)
+}

-const onClick = (event: MouseEvent) => {
-  if (isFunction(state.value.onClick)) return state.value.onClick(event)
-  emits('click', event)
-}
+const onClick = (event: MouseEvent) => emitEvent(state.value.onClick, 'click', event)

-const onClosed = () => {
-  if (isFunction(state.value.onClosed)) return state.value.onClosed()
-  emits('closed')
-}
+const onClosed = () => emitEvent(state.value.onClosed, 'closed')

-const onOpened = () => {
-  if (isFunction(state.value.onOpened)) return state.value.onOpened()
-  emits('opened')
-}
+const onOpened = () => emitEvent(state.value.onOpened, 'opened')

74-78: 优化 watch 配置

当前的 watch 配置对布尔值使用了深度监听,这可能会带来不必要的性能开销。

建议修改如下:

watch(
  () => state.value.visible,
  (visible) => {
    emits('update:visible', visible as boolean)
  },
-  { deep: true }
+  { immediate: true }
)

这样可以:

  1. 移除对原始类型不必要的深度监听
  2. 添加 immediate 选项确保初始同步
src/uni_modules/wot-design-uni/components/wd-message-box/types.ts (1)

116-119: 优化 selector 属性的类型定义和文档

使用 makeStringProp('') 替代原有的类型定义是一个很好的改进:

  • 提供了默认空字符串值
  • 确保了类型安全
  • 添加了清晰的文档注释说明其用途

这个改动将有助于解决多个 useXX 函数调用时只有最后一个生效的问题,因为现在可以通过 selector 来区分不同的实例。

建议在文档中补充说明:

  1. selector 的具体使用方式
  2. 如何确保 selector 的唯一性
  3. 在多实例场景下的最佳实践
src/uni_modules/wot-design-uni/components/wd-message-box/index.ts (2)

10-10: 优化了选项管理的基础结构

  • 引入了 injectprovide 用于状态管理
  • messageDefaultOptionKey 改为局部常量增强了封装性
  • 新增 None 符号用于表示未初始化状态,这是一个很好的实践

建议:考虑为 None 添加类型声明以增强类型安全性。

-const None = Symbol('None')
+const None = Symbol('None') as const
+type NoneType = typeof None

Also applies to: 14-16


93-95: 新增了选项键生成工具函数

getMessageDefaultOptionKey 函数的实现简洁明了,支持了选择器的动态配置。建议添加函数文档说明其用途和参数含义。

+/**
+ * 根据选择器生成消息选项的键
+ * @param selector 选择器字符串
+ * @returns 消息选项键
+ */
export const getMessageDefaultOptionKey = (selector: string) => {
  return selector ? `${messageDefaultOptionKey}${selector}` : messageDefaultOptionKey
}
src/uni_modules/wot-design-uni/components/wd-toast/wd-toast.vue (1)

64-64: 选项键生成逻辑的改进

使用 getToastOptionKey 函数基于 selector 生成选项键,这个改动解决了多个 useXX 函数在同一页面上只有最后一次调用生效的问题。建议添加注释说明这个改动的目的。

建议添加如下注释:

+// 根据selector生成唯一的选项键,以支持同一页面多次调用
const toastOptionKey = getToastOptionKey(props.selector)
src/uni_modules/wot-design-uni/components/wd-message-box/wd-message-box.vue (2)

Line range hint 81-85: 建议优化类型定义和错误处理

当前实现可以考虑以下几点改进:

  1. 建议为 messageOption 的默认值添加更明确的类型断言
  2. 可以考虑添加运行时类型检查,确保注入的选项符合预期格式

建议修改如下:

-const messageOption = inject(messageOptionKey, ref<MessageOptions>(defaultOptions))
+const messageOption = inject<Ref<MessageOptions>>(
+  messageOptionKey,
+  ref<MessageOptions>(defaultOptions),
+  true // 确保值始终存在
+)

Line range hint 208-227: 建议增强输入验证的错误处理机制

当前的验证函数实现可以考虑以下优化:

  1. 建议为不同类型的验证失败提供更具体的错误信息
  2. 可以考虑添加错误信息的国际化支持
  3. 建议添加防抖处理,优化用户输入体验

建议修改如下:

 function validate() {
+  const getErrorMessage = (type: 'pattern' | 'custom') => {
+    return type === 'pattern'
+      ? translate('patternError')
+      : translate('validateError')
+  }
+
   if (inputPattern.value && !inputPattern.value.test(String(inputValue.value))) {
     showErr.value = true
+    inputError.value = getErrorMessage('pattern')
     return false
   }
   if (typeof inputValidate === 'function') {
     const validateResult = inputValidate(inputValue.value)
     if (!validateResult) {
       showErr.value = true
+      inputError.value = getErrorMessage('custom')
       return false
     }
   }
   showErr.value = false
+  inputError.value = ''
   return true
 }
src/uni_modules/wot-design-uni/components/wd-toast/index.ts (2)

25-30: 建议增强错误处理机制

当前实现解决了多次调用的问题,但建议考虑以下改进:

  1. 添加运行时类型检查,确保注入的值类型正确
  2. 考虑添加错误边界处理,防止在极端情况下的潜在问题

建议参考以下实现:

 const toastOptionKey = getToastOptionKey(selector)
 const toastOption = inject(toastOptionKey, ref<ToastOptions | typeof None>(None)) // toast选项
+if (!toastOption || typeof toastOption.value === 'undefined') {
+  console.warn(`[wot-design-uni] useToast 注入值异常,将使用默认配置`)
+}
 if (toastOption.value === None) {
   toastOption.value = defaultOptions
   provide(toastOptionKey, toastOption)
 }

82-84: 建议添加参数验证

getToastOptionKey 函数实现简洁明了,但建议添加参数验证以提高健壮性。

建议参考以下实现:

 export const getToastOptionKey = (selector: string) => {
+  if (selector && typeof selector !== 'string') {
+    console.warn(`[wot-design-uni] getToastOptionKey 的 selector 参数必须是字符串`)
+    return toastDefaultOptionKey
+  }
   return selector ? `${toastDefaultOptionKey}${selector}` : toastDefaultOptionKey
 }
src/uni_modules/wot-design-uni/components/wd-notify/index.ts (2)

18-22: 优化注入和提供 notifyOption 的逻辑

当前使用 ref<NotifyProps | typeof None>(None) 作为默认值,可能增加了逻辑复杂性。建议在无法注入到 notifyOption 时,直接创建新的 ref,以简化代码。

您可以考虑以下修改:

-  const notifyOption = inject(notifyOptionKey, ref<NotifyProps | typeof None>(None))
-  if (notifyOption.value === None) {
+  let notifyOption = inject<Ref<NotifyProps>>(notifyOptionKey)
+  if (!notifyOption) {
     notifyOption = ref(currentOptions)
     provide(notifyOptionKey, notifyOption)
   }

这样可以避免使用 None 符号,直接判断 notifyOption 是否存在,提高代码可读性。


33-35: 简化关闭通知时的条件判断

在关闭通知时,直接检查 notifyOption.value 是否存在,而不是与 None 进行比较,代码会更简洁明了。

建议修改为:

-  if (notifyOption.value !== None) {
+  if (notifyOption.value) {
     notifyOption.value.visible = false
   }

这样可以提高代码的可读性,避免不必要的符号比较。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between deeb45d and d603f12.

📒 Files selected for processing (8)
  • src/uni_modules/wot-design-uni/components/wd-message-box/index.ts (4 hunks)
  • src/uni_modules/wot-design-uni/components/wd-message-box/types.ts (2 hunks)
  • src/uni_modules/wot-design-uni/components/wd-message-box/wd-message-box.vue (2 hunks)
  • src/uni_modules/wot-design-uni/components/wd-notify/index.ts (1 hunks)
  • src/uni_modules/wot-design-uni/components/wd-notify/wd-notify.vue (3 hunks)
  • src/uni_modules/wot-design-uni/components/wd-toast/index.ts (3 hunks)
  • src/uni_modules/wot-design-uni/components/wd-toast/wd-toast.vue (2 hunks)
  • src/uni_modules/wot-design-uni/index.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • src/uni_modules/wot-design-uni/index.ts
🔇 Additional comments (12)
src/uni_modules/wot-design-uni/components/wd-notify/wd-notify.vue (1)

20-24: 组件配置设置合理!

组件选项配置符合最佳实践,virtualHost 优化性能,样式隔离策略选择恰当。

src/uni_modules/wot-design-uni/components/wd-message-box/types.ts (1)

10-10: 导入 makeStringProp 用于属性类型定义

引入 makeStringProp 函数来创建带有默认值的字符串类型属性,这是一个很好的做法,可以确保类型安全性和默认值的处理。

src/uni_modules/wot-design-uni/components/wd-message-box/index.ts (3)

4-4: 更新了文件元数据信息

文件的最后编辑时间和路径信息已更新,保持了良好的文件维护记录。

Also applies to: 7-7


37-41: 改进了消息选项的注入逻辑

这个改动很好地解决了多次调用 useXX 函数时只有最后一次生效的问题:

  • 使用 inject 获取已存在的选项
  • 当选项不存在时才创建新的选项
  • 通过 provide 确保选项在组件树中可用

这种实现方式符合 Vue 的组件通信最佳实践。


80-82: 增强了关闭方法的健壮性

通过添加 None 检查,避免了在选项未初始化时可能出现的运行时错误。

src/uni_modules/wot-design-uni/components/wd-toast/wd-toast.vue (1)

41-41: 导入语句的优化调整

导入声明的更改反映了更模块化的设计方案,通过引入 getToastOptionKey 函数来替代直接使用常量。这种改进使得选项键的生成更加灵活和可维护。

src/uni_modules/wot-design-uni/components/wd-message-box/wd-message-box.vue (1)

64-64: 导入更改和键生成逻辑优化!

通过使用 getMessageDefaultOptionKey 函数来生成基于选择器的唯一键,这个改动很好地解决了同一页面多次使用 useXX 函数时只有最后一次生效的问题。这种方式可以确保每个选择器都有其独特的标识符。

Also applies to: 81-81

src/uni_modules/wot-design-uni/components/wd-toast/index.ts (3)

1-1: 导入变更看起来不错!

新增的 inject 导入与组件的新架构保持一致,这是一个合理的改动。


8-8: 很好的封装性改进!

toastDefaultOptionKey 改为模块内部常量提高了封装性,减少了不必要的公共 API 暴露。


22-22: 优雅的空值处理方案!

使用 Symbol 作为空值标记是一个很好的做法,比使用 undefined 或 null 更加类型安全。

src/uni_modules/wot-design-uni/components/wd-notify/index.ts (2)

8-8: 引入用于表示空状态的 Symbol 'None'

使用 Symbol('None') 作为唯一标识来表示不存在的选项是合理且有效的做法。


25-26: 确保 notifyOption.value 的反应性

在赋值给 notifyOption.value 时,确保使用响应式数据,以保持 Vue 的响应式特性。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant