返回顶部
首页 > 资讯 > 前端开发 > JavaScript >uni-app跨端自定义指令实现按钮权限操作
  • 798
分享到

uni-app跨端自定义指令实现按钮权限操作

摘要

目录前言准备目录结构正则npm 包知识点loader 开发和调试定义最简单的LoaderLoader基础操作本地调试 ResolveLoader完整代码loaders/uni-per

前言

初看这个标题可能很迷,uni-app明明不支持自定义指令,这文章是在搞笑吗,本文对于uni-app自定义指令实现按钮权限的方式也有可能是多余,但为了给业务部门更友好的开发体验,还是做了一些可能没意义的操作,让移动端和PC端对于按钮权限是使用方式一致,都是使用自定义指令的书写方式来实现按钮权限,虽然uni-app不支持自定义指令,但是我们有webpack的loader起到代码转换的作用,将自定义指令v-perms:add在编译阶段转换为v-if="$perms('add')",然后去处理$perms方法对于权限的判断,就可以具有自定义指令实现按钮权限的开发体验了。

每个工具的实现都不算简单,本文实现的loader,尽管原理挺简单的,好像可以一蹴而就,但真的去实现的话,发现还是需要很多的知识储备,整体流程也没想象的那么简单,但有个点子就是好的开始,经过些许努力,终将成就一个不错的工具。

准备

实现uni-app自定义指令按钮权限需要涉及到对于Vue.config.js新增loader配置,基础正则知识,WEBpack的loader开发和调试,以及npm本地调试和发布,接下来就从了解这些前置知识开始。

目录结构

chainWebpack 新增loader

vue的loader配置是通过chainWebpack来实现链式配置,vue.config.js新增一个loader配置可以查看vue-cli文档,具体实现:

// vue.config.js
module.exports = {chainWebpack: config => {// GraphQL Loaderconfig.module.rule('graphql').test(/.graphql$/).use('graphql-tag/loader').loader('graphql-tag/loader').end()}
} 

正则

实现自定义指令替换,需要查找所有的v-perms:xxx,并且需要拿到xxx对应的值,将其转换为v-if="$perms('xxx')",所以就有了如下表达式,其作用就是匹配v-perms:xxx表达式,并提取到xxx内容。

/v-perms:([^/<>\s]*)/g 

针对正则基础比较薄弱的同学,我来解释一下上面这个正则表达式

  • 首先,v-perms:用于匹配以v-perms:开头的字符串
  • 接着是(),()称为捕获组,其圈住的内容,就是我们要捕获起来额外存储的东西。
  • []中的匹配符之间是“或”的关系,也就是说只要能匹配上其中一个就行了。
  • ^原本是匹配字符串的开始位置,但是在[]表达式中使用代表着除什么之外
  • *跟在其它表达式后面,意味着“前面这个表达式可以出现0次或多次
  • 最后这个/g表示该表达式将用来查找所有可能的匹配,返回的结果可以是多个,如果不加/g最多只会匹配一个
  • 总结起来这个正则表达式的作用就是匹配以v-perms:开头的所有内容,并提取到v-perms:和空格、< 、>、/之间的内容,可以适应我们常写的多个场景
// 结尾是">"
<button v-perms:add>新增按钮</button>
// 结尾是"/"
<input v-perms:add/>
// 结尾是空格
<button v-perms:add class="btn">新增按钮 v-perms:add</button>
// 结尾是"<"
<button>新增按钮 v-perms:add</button> 

npm 包知识点

关于npm包本地调试以及发布的知识点还是蛮重要的,写一些工具库,组件,脚手架都能用到,也是面试会考察到的点,内容比较多,可以看我之前写的项目脚手架发布为npm包文章进行学习,这边就讲解一下npm的本地调试。

npm link 

执行 npm link,可以将本地npm包链接到全局的 node_modules

一些包没办法使用全局,那么我们可以执行npm link packageName将对应包连接到当前项目的node_modules

npm link packageName 

执行 npm unlink packageName 删除本地连接

npm unlink packageName 

loader 开发和调试

定义

Loader只是一个导出为函数的javascript模块。

最简单的Loader

// source入参就是我们配置的对应规则匹配到文件类型的文件流或者上一个loader处理后的结果。
module.exports = function (source) {return source;
}; 

Loader基础操作

例如我们的.vue文件中包含如下代码:

<u-button type="success" v-perms:edit>编辑</u-button> 

我们需要将模板的v-perms:edit替换成v-if="$perms('edit')",只需要在source返回之前对它进行正则匹配和替换即可。

module.exports = function (source) {// TODO// 这里实现对于source的操作return source;
}; 
module.exports = function (source) {// TODO// 这里实现对于source的操作return source;
}; 

本地调试 ResolveLoader

webpack默认情况下只会去 node_modules 目录下寻找loader,但是我们可以通过ResolveLoader.modules配置loader的加载目录,通过上述的目录结构可以看出我将loader写在根目录的loaders下,所以可以有如下配置。

// vue.config.js
module.exports = {configureWebpack: {resolveLoader: {// 配置loader可以从node_modules和loaders目录下查找modules: ["node_modules", "./loaders/"],},},// 为.vue文件新增一个uni-perms-loader的loaderchainWebpack: (config) => {config.module.rule("vue").test(/\.vue$/).use("uni-perms-loader").loader("uni-perms-loader").end();},
}; 

npm link 在 /loaders/uni-perms-loader目录下执行npm link,将uni-perms-loader连接到全局,执行时需要配置好package.json,具体配置可以查看文章。

{"name": "uni-perms-loader", // 包名"version": "1.0.0", // 版本号"description": "uni-app 自定义权限指令替换", // 介绍"main": "index.js", // 入口"scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keyWords": [ // npm包搜索关键词"uni-app","自定义指令","directive"],"author": "LBINGXIN","license": "MIT" // 开源协议
} 

在当前项目根目录下执行npm link uni-perms-loader,将uni-perms-loader连接到本地node_modules,uni-perms-loader 即使npm包名,我们在package.json配置的名称name。可以在当前项目的node_modules中查到uni-perms-loader

vue.config.js 配置,这边就不需要ResolveLoader了

// vue.config.js
module.exports = {// 为.vue文件新增一个uni-perms-loader的loaderchainWebpack: (config) => {config.module.rule("vue").test(/\.vue$/).use("uni-perms-loader").loader("uni-perms-loader").end();},
}; 

本地调试是用于方便开发时对于loader进行测试,在实际的应用中还是发布为npm包,方便多个项目使用

完整代码

这个loader的代码还是很简单,就是匹配到自定义指令,然后获取对应参数,然后替换成v-if

loaders/uni-perms-loader/index.js

uni-perms-loader具体实现

function replaceDirective(source) {// 正则表达式const reg = /v-perms:([^/<>\s]*)/g;// 使用replace实现字符串替换// 这边的$n就是指捕获组()匹配的内容,索引是从1开始,我们这边只有一个,所以是$1,如果有// 多个,那就是$2,$3source = source.replace(reg, `v-if="$perms('$1')"`);return source;
}
module.exports = function (source) {// 处理替换source = replaceDirective(source);return source;
}; 

loaders/uni-perms-loader/package.json

package.json 配置

// 这边是假数据,不同团队对于权限的数据定义都不大一样,我列举的算是最简单的一种,不大需要
// 去考虑不同页面按钮名称重复,用当前页面路由进行区分
const data = {"/pages/index/index": {add: "新增",edit: "编辑",},"/pages/me/index": {add: "新增",auth: "授权",},
};
const checkPermission = (key) => {// 获取所有路由栈const pages = getCurrentPages();const len = pages.length;// 获取当前页面路由 route的值例如 pages/index/indexconst { route } = pages[len - 1];// 判断当前页面是否包含对应按钮的权限return !!data[`/${route}`][key];
};
export default checkPermission; 

src/utils/index.js

按钮权限判断方式实现

import checkPermission from "./utils/index";
Vue.prototype.$perms = checkPermission; 

main.js

将实现按钮权限判断的函数挂载到全局的$perms上

import checkPermission from "./utils/index";
Vue.prototype.$perms = checkPermission; 

使用

<template><view class="content"><image class="loGo" src="/static/logo.png"></image><view class="buttons"><u-button type="primary" v-perms:add>新增 </u-button><u-button type="success" v-perms:edit>编辑</u-button><u-button type="error" v-perms:delete>删除</u-button><u-button type="warning" v-perms:auth>授权</u-button></view></view>
</template> 

小结

本文对应的uni-app使用uni-perms-loader的demo已经提交到GitHub了, 对应的uni-perms-loader也发布到npm,这个loader算是比较简单,大家可以自己实现,也可以直接使用我发布的npm包。

这个loader可能不是必须的,但是有了它,可以有更好的开发体验,也能和vue项目保持一致性,不算一无是处,具体是否使用,大家根据自己情况,有问题也欢迎探讨。

到此这篇关于uni-app跨端自定义指令实现按钮权限的文章就介绍到这了,更多相关uni-app按钮权限内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: uni-app跨端自定义指令实现按钮权限操作

本文链接: https://lsjlt.com/news/177892.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作