野猪佩琦
野猪佩琦
  • 发布:2023-04-23 15:13
  • 更新:2024-06-05 14:15
  • 阅读:1711

directive 不生效 自定义指令不生效

分类:uni-app

需求

  • 根据权限编码禁用按钮
  • 阻止当前 dom 绑定的点击事件,禁用状态(opacity 半透明?? 或者 display: none?? )

尝试

  • 开发环境用 Chrome 跑,一切正常,构建打包后去真机跑,按钮没控制住
  • (用 HBX -发行-原生应用 app 制作 wgt 包)开发环境: HBX: 3.7.9 系统: MacOS: 13.0.1 (Intel)
  • 通过 directive 绑定一个 v-auth 指令,在标签里 v-auth="’some auth code‘" 或者 v-auth="['code1', 'code2']"
  • directivebindinserted 两个钩子尝试过,最终确定为 el 在真机环境下,与开发环境的el 不是一个玩意

暂用平替方案

  • 全局 mixin 一个方法,判断权限后返回以控制当前 dom 是否可点击

    // path/auth.js  
    function checkAuth(value) {  
        if (  
            value === "" ||  
            (value instanceof Array && value.length === 0) ||  
            !value  
        ) {  
            return true;  
        }  
        const _value = [value].flat(); // 兼容入参为 string 和 array,拍平二维数组  
        const authBtns = uni.getStorageSync("authBtns");  
        if (authBtns === "*") return true;  
        const hasPermission = _value.every((e) => authBtns.includes(e));  
        return hasPermission;  
    }  
    const auth = {  
        install(Vue) {  
            // directive 在 app 下无法正常使用  
            // Vue.directive("auth", {  
            //  bind(el, binding, vnode, oldVnode) {  
            //      if (!checkAuth(binding.value, el)) {  
            //          el.style.opacity = "0.3";  
            //          el.style.pointerEvents = "none";  
            //      }  
            //  },  
            //  inserted(el, binding, vnode, oldVnode) {  
            //      if (!checkAuth(binding.value, el)) {  
            //          el.style.opacity = "0.3";  
            //          el.style.pointerEvents = "none";  
            //      }  
            //  },  
            // });  
            // 平替方案  
            Vue.mixin({  
                methods: {  
                    $auth(val) {  
                        if (!checkAuth(val)) {  
                            return [{ opacity: "0.3", pointerEvents: "none" }];  
                        }  
                        return [];  
                    },  
                },  
            });  
        },  
    };  
    
    // path/main.js  
    Vue.use(auth);  
    /*  (他妈的 DCloud 的 md 还不支持写两段代码语法??? 想分开一个 js 语法一个 html 语法的代码块,发现把我 14 的``` 解析成一对语法??23 的```直接忽略??) */  
    // vue文件中  
    <view :style="$auth('AUTH_CODE')">没有权限 AUTH_CODE 别点我</view>  
    <view :style="$auth(['CODE1', 'CODE2'])">没有权限 CODE1&2 别点我</view>

写在最后

官方 uni 文档写着支持 app 用 directive ,可能是我姿势不对,没用对吧。。

2 关注 分享
朱小 Megasu

要回复文章请先登录注册

野猪佩琦

野猪佩琦 (作者)

回复 w***@cmiot.chinamobile.com :
函数返回结果,不是函数
2024-06-05 14:15
w***@cmiot.chinamobile.com

w***@cmiot.chinamobile.com

这个在模板里面绑定style 的时候会报错,style不支持绑定函数
2023-11-22 16:36
1***@qq.com

1***@qq.com

还有一种办法可以在APP端可以拿取el.attributes.class类名,然后通过自定义指令beforeMount钩子函数里提前绑定自己写好样式的类名就可以了,直接设置el.style是不行的
2023-08-23 15:48
linkttt

linkttt

回复 Megasu :
感谢分享,学到了
2023-08-14 11:40
Megasu

Megasu

模板中使用:

```vue
<script setup lang="ts">
import { auth, checkAuth } from '@/utils/auth'
</script>

<template>
<!-- 用法1 -->
<button :style="auth('AUTH_CODE')" type="primary">没有权限 AUTH_CODE 别点我</button>
<button :style="auth(['CODE1', 'CODE2'])" type="primary">没有权限 CODE1&2 别点我</button>
<!-- 用法2 -->
<button :disabled="!checkAuth('AUTH_CODE')" type="primary">没有权限 AUTH_CODE 别点我</button>
<button :disabled="!checkAuth(['CODE1', 'CODE2'])" type="primary">没有权限 CODE1&2 别点我</button>
</template>
```
2023-05-18 12:34
Megasu

Megasu

提供 vue3 + ts 的解决方案:

```ts
/**
* 鉴权函数
* @param value 权限标识,支持字符串/字符串数组
* @returns 鉴权结果
*/
export function checkAuth(value: string | string[]) {
// 参数为空或长度为0,直接返回 true
if (!value || value.length === 0) return true
// 兼容入参为 string 和 array,拍平二维数组
const _value = [value].flat()
// 获取本地存储中的authBtns,它表示当前用户拥有的权限按钮
const authBtns = uni.getStorageSync('authBtns')
// 如果authBtns为*,代表有全部权限,直接返回 true
if (authBtns === '*') return true
// 使用 every() 方法校验入参的每一个元素是否在 authBtns 中,如果全部存在则返回 true,否则返回false。
const hasPermission = _value.every((e) => authBtns.includes(e))
return hasPermission
}

/**
* 鉴权函数-样式处理
* @param val
*/
export function auth(val: string | string[]) {
// 调用 checkAuth 进行权限校验
if (!checkAuth(val)) {
// 如果没有权限,返回样式,用于禁用按钮
return [{ opacity: '0.3', pointerEvents: 'none' }]
}
return []
}
```
2023-05-18 12:31
野猪佩琦

野猪佩琦 (作者)

回复 朱小 :
这个方案暂且只能用于 uni 支持 `directive ` 的平台。在微信小程序里,貌似就无法使用...
2023-04-28 10:07
朱小

朱小

厉害,刚好有个项目准备用自定义指令,避免踩坑了
2023-04-26 10:03