vue3+ts+uniapp小程序封装获取授权hook函数

文章介绍了如何在Vue3和TypeScript的UniApp小程序中封装一个全局的授权提示函数,解决用户拒绝授权后不再弹出的问题,通过uni-appAPI实现授权请求和引导用户手动设置授权。

vue3+ts+uniapp小程序封装获取授权hook函数

小程序授权的时候,如果点击拒绝授权,然后就再也不会出现授权了,除非用户手动去右上角…设置打开

通过uni官方api自己封装一个全局的提示:
uni.getSetting :http://uniapp.dcloud.io/api/other/setting?id=getsetting
uni.authorize:http://uniapp.dcloud.io/api/other/authorize?id=authorize
uni.openSetting:https://uniapp.dcloud.net.cn/api/other/setting.html#opensetting

具体代码
src\composable\index.ts

/**
 * 授权综合逻辑
 * @param {*} scope 权限代表
 */
export const useShowPullAuth = () => {
   
   
  const pullAuth = (scope: keyof UniApp.AuthSetting): void => {
   
   
    const map: Record<string, string> = {
   
   
      'scope.userInfo': '用户信息',
      'scope.userLocation': '地理位置',
      'scope.userLocationBackground': '后台定位',
      's
非常好,你使用的是 **Vue 3 + TypeScript**,我们可以用更现代、类型安全的方式来实现:父组件点击图标时,通知动态子组件执行各自的方法。由于每个子组件方法不同,推荐使用 **`mitt` 事件总线 + TS 类型定义** 的方式,保证类型安全和开发体验。 --- ## ✅ 最佳实践:Vue 3 + TS 中通过 `mitt` 实现父子解耦通信 ### ✅ 场景回顾: - 父组件有一个图标按钮。 - 当前显示的是一个动态组件(`<component :is="comp">`)。 - 每个子组件有自己的逻辑方法(名称不一致)。 - 点击图标时,希望当前激活的子组件能“自己执行自己的方法”。 --- ### 第一步:安装 `mitt` 并创建类型安全的事件总线 ```bash npm install mitt ``` #### 创建 `eventBus.ts`(带类型提示) ```ts // utils/eventBus.ts import mitt from &#39;mitt&#39; // 定义所有可能的事件类型 type Events = { &#39;trigger-action&#39;: void &#39;form-submit&#39;: { valid: boolean } // 可扩展其他事件 } export default mitt<Events>() ``` 这样你在监听或触发事件时会有完整的 TypeScript 提示和校验。 --- ### 第二步:父组件点击时 emit 事件 ```vue <!-- ParentComponent.vue --> <script setup lang="ts"> import { ref } from &#39;vue&#39; import eventBus from &#39;@/utils/eventBus&#39; // 动态组件导入 import ChildA from &#39;./ChildA.vue&#39; import ChildB from &#39;./ChildB.vue&#39; const currentComponent = ref(ChildA) // 点击图标 → 触发全局事件 const onIconClick = () => { eventBus.emit(&#39;trigger-action&#39;) // 类型安全:TS 会检查是否拼错 } </script> <template> <div> <!-- 点击图标触发子组件行为 --> <button @click="onIconClick" class="icon-btn"> 🔔 执行操作 </button> <!-- 动态组件 --> <component :is="currentComponent" /> </div> </template> <style scoped> .icon-btn { font-size: 1.5em; cursor: pointer; background: none; border: none; } </style> ``` --- ### 第三步:子组件监听事件并执行自己的方法(TS 写法) #### 示例:ChildA.vue ```vue <!-- ChildA.vue --> <script setup lang="ts"> import { onMounted, onBeforeUnmount } from &#39;vue&#39; import eventBus from &#39;@/utils/eventBus&#39; // 子组件独有的方法 const childAMethod = () => { alert(&#39;Child A 自定义逻辑执行!&#39;) } // 组件挂载后监听事件 onMounted(() => { eventBus.on(&#39;trigger-action&#39;, childAMethod) }) // 卸载前移除监听(防止内存泄漏) onBeforeUnmount(() => { eventBus.off(&#39;trigger-action&#39;, childAMethod) }) </script> <template> <div style="color: blue;"> 我是 Child A </div> </template> ``` #### 示例:ChildB.vue ```vue <!-- ChildB.vue --> <script setup lang="ts"> import { onMounted, onBeforeUnmount } from &#39;vue&#39; import eventBus from &#39;@/utils/eventBus&#39; const childBMethod = () => { console.log(&#39;Child B 开始同步数据...&#39;) // 执行一些业务逻辑 } onMounted(() => { eventBus.on(&#39;trigger-action&#39;, childBMethod) }) onBeforeUnmount(() => { eventBus.off(&#39;trigger-action&#39;, childBMethod) }) </script> <template> <div style="color: green;"> 我是 Child B </div> </template> ``` --- ### ✅ 优势总结(Vue 3 + TS + mitt): | 特性 | 是否支持 | 说明 | |------|----------|------| | 类型安全 | ✅ | 使用泛型 `<Events>` 避免拼写错误 | | 解耦清晰 | ✅ | 父组件无需知道子组件结构 | | 支持多个动态组件 | ✅ | 每个组件可自由响应或忽略事件 | | TS 提示友好 | ✅ | VSCode 自动补全事件名和参数 | | 资源释放可控 | ✅ | 使用 `onBeforeUnmount` 清理监听 | --- ### ⚠️ 注意事项: 1. **必须在 `onMounted` 中注册事件监听**,避免组件未加载就监听。 2. **务必调用 `off` 移除监听**,否则切换组件可能导致多个实例同时响应。 3. 如果有多个事件类型,可以在 `Events` 接口中添加参数类型,如 `&#39;save-data&#39;: { id: string }`。 --- ### 🆚 替代方案对比 | 方式 | 是否适合 Vue 3 + TS | 说明 | |------|---------------------|------| | `ref` 调用方法 | ✅ 但有限制 | 要求统一方法名,不适合异构组件 | | `$emit`(子→父) | ❌ 方向不对 | 无法用于“父触发子逻辑” | | `provide/inject` 函数 | ✅ 可行 | 也可以传一个 trigger 函数下去 | | `mitt` 事件总线 | ✅✅✅ 强烈推荐 | 最灵活、最解耦 | --- ### 💡 扩展建议:封装一个 `useEventBus` Hook 你可以封装一个可复用的 Hook: ```ts // composables/useEventBus.ts import { onMounted, onBeforeUnmount } from &#39;vue&#39; import eventBus from &#39;@/utils/eventBus&#39; export function useEventBus(event: &#39;trigger-action&#39;, handler: () => void) { onMounted(() => { eventBus.on(event, handler) }) onBeforeUnmount(() => { eventBus.off(event, handler) }) } ``` 然后在子组件中使用: ```ts import { useEventBus } from &#39;@/composables/useEventBus&#39; const myAction = () => { ... } useEventBus(&#39;trigger-action&#39;, myAction) ``` 进一步简化代码。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值