vue 项目,字符串解析成变量,或者函数执行问题。
1. 现状:当前有一个操作栏,按钮每个都是写死的,每个按钮有多种权限控制显示影藏。
2. 需求:按钮超过3个要折叠显示到更多中,少于3个不显示更多
3. 针对需求引发的问题:
1. 每条数据,每个按钮,每种权限判断该不该显示当前按钮,条件太多太复杂。
2. 动态展示有两种实现方案:
1. 构造动态展示的数据结构 menuList 去渲染操作栏
2. 自定义操作栏组件,先让组件渲染,然后通过 DOM 操作(指令或者生命周期)去移动或者移除DOM (该方式在Vue 中尝试未果,后续再试)
3. 针对实现方案1有两个难点:
1. 在不使用render渲染的情况下,原有代码改动最小的前提下。定义的 menuList 中控制显示隐藏的 v-if 条件和 绑定的函数都是字符串,怎么解析?
2. 绑定函数的参数怎么映射到?
4. 解决:
1. 定义操作列表
2. 构造函数:
// 定义权限管控变量,隐射到 v-if 中的权限
let isCysRole = false
let isYskfRole = false
export const generatorOperateMenuList = function () { JSON.parse(sessionStorage.userInfor).role.forEach(item => { if (item.roleCode === 'CYS') { isCysRole = true } if (item.roleCode === 'YSKF') { isYskfRole = true } }) return (menuList, row) => { const operateObj = { out: [], inner: [] } let menus = menuList.filter(m => eval(m.isShow.valueOf())) // 使用 eval 解决 v-if 字符串解析成变量的问题 let len = menus.length if (len > 0) { if (len > 2) { operateObj.out = [...menus.splice(0, 2)] operateObj.inner = [...menus] } else { operateObj.out = [...menus] operateObj.inner = [] } } // console.log(operateObj) return operateObj } }
3. 操作渲染
4. evil 解析函数的方法定义
evil (func, row) { // 使用eval 函数解析字符串函数定义 // row 参数特别重要,映射到字符串函数中的 row eval(func) // eslint-disable-line }, // 调用 // 入参 row 映射到字符串函数中的 实参 row <a class="btn" @click="() => {evil('this.' + m.func, row)}">{{ m.label }}</a>
5. eval 函数存在 lint 校验和 安全问题,可以注释掉行校验eslint
6. eval 函数的替代函数, // 存在一个问题,无法 映射到 实参 row,后续解决;
evil (fn) { let Fn = Function // 一个变量指向Function,防止有些前端编译工具报错 return new Fn('return ' + fn)() }