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)() }