Access control (vue)

Access control (vue)

Often you encounter, the role of access control problem, if the page control, said the booing, but if the current page is partly visible the invisible, which is some trouble, if it is coupled with more stringent conditions. Before simply v-ifcontrolled, and now want to try the command (these operations have been online mode)

reference

Reference vue-element-admin - Instruction

Scenarios

  • Access control
    • dom hidden (not recommended)
    • Deleted directly from the dom node
  • Make changes based on incoming data dynamically

Code

Needs: the need to achieve a modification of the module based on dynamic parameters

  • test.vue

    template

    <div class="test-height">
      <!-- 指令调用,status是动态参数 -->
      <h1 v-permission="{ role: ['so'], status }">test</h1>
    </div>

    js

      import permission from '@/directives/permission'
      export default {
        ...
        directives: { permission },
        data () {
          return {
            status: false
          }
        },
        mounted () {
          // 动态修改参数
          setTimeout(() => {
            this.status = !this.status
          }, 1000)
        }
      }
  • permission.js

      import store from '@/store'
      const permission = (el, binding, vnode, oldVnode) => {
        const { value, oldValue } = binding
        if (!value || (value.role && !Array.isArray(value.role))) {
          throw new Error(`need roles! Like v-permission="{ role: ['admin','editor'], [status 可传 boolean]}"`)
        }
        // 绑定的参数
        const status = value.hasOwnProperty('status') ? value.status : false
        const roles = store.getters && store.getters.roles
        const permissionRoles = value.role || []
    
        const hasPermission = roles.some(role => {
          return permissionRoles.includes(role)
        })
    
        if (!hasPermission || (hasPermission && status)) {
          /**
          * TODO:
          * 1. 给父元素添加唯一id
          * 2. 同时找到子元素当前父元素的第几个位置
          */
          const rid = getRandomId()
          const index = getChildInParentPosition(el)
          el.parentNode.setAttribute('id', rid)
          el.dataset.id = rid
          el.dataset.index = index
          el.parentNode && el.parentNode.removeChild(el)
        }
        // 判断条件
        if (oldValue && oldValue && oldValue.status === true && value.status === false) {
          // 此处会在 update时触发
          const { index, id } = el.dataset
          const parent = document.getElementById(id)
          // 根据index找到需要插入父节点的位置
          parent.insertBefore(el, Array.from(parent.children)[index])
        }
      }
      export default {
        // 此处父元素存在
        inserted: permission,
        // 此处数据更新
        update: permission
      }
    • Randomly generated id

        function getRandomId () {
          var randomId = 'yxyxyxxyxyy'.replace(/[xy]/g, function (item) {
            var n = Math.random() * 12 | 0
            var v = item === 'x' ? n : (n & 0x3 | 0x8)
            v = item === 'y' ? 'abcdefghijklmnopqrstuvwsyz'.substr(Math.random() * 26 | 0, 1) : v
            return v.toString(16)
          })
          return randomId
        }
    • Find the position of the child node in the parent node

        function getChildInParentPosition (node) {
          // 用来保留子元素 【cloneNode(true) 深度克隆】
          const Parent = node.parentNode.cloneNode(true)
          let key = -1
          Array.from(Parent.children).filter((item, index) => {
            // 判断子节点是否相同 【isEqualNode】
            if (item.isEqualNode(node)) {
              key = index
            }
          })
          return key
        }

Renderings

  • Not displayed by default, the data show back
    • Individual elements

    • Multiple elements

  • The default display, the data do not show back
    • Individual elements

    • Multiple elements

to sum up

  • Although it is possible to solve the basic needs, but there are still problems, if siblings are access control, I am afraid that when the echo, be displaced
  • Therefore recommend or usev-if
  • Above, can only deal with simple, some complex still struggling
  • When instruction is executed, the corresponding relationship in advance to get the parent node and child nodes, and then update, the acquired globally, thus generated idmust be unique
  • If you want to use for other scenes, we need to add a parent element need access control, while ensuring the child elements unique to

Knowledge Point

  • cloneNode(true) Use the depth of cloning due to the changes in real time because the parent element is used, you can keep the child nodes
  • isEqualNode It used to determine whether the same two child nodes (long knowledge)
  • update, The need to add a node to the parent node, this time vnode, oldVnodeis parentnot the value of

Guess you like

Origin www.cnblogs.com/sinosaurus/p/11468806.html