项目难点(封装组件难点)

1、已获取当前账号的操作配置权限(arr),在每个页面中有对应的效果

1)可以通过自定义指令,来对相对应的标签进行操作。
2)表单操作部分权限逻辑处理在封装的组件中
1)按钮等(自定义指令):
	// 按钮权限指令必须加在dom元素(例如:span),不能加在<template></template>上
Vue.directive('btnPermission', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function(el, binding, vnode, oldVnode) {
    // console.warn(el)
    // console.warn(binding.value.code)
    // console.log(router.history.current.meta.btn)
    var code = binding.value.code
    var arr = router.history.current.meta.btn
    if (arr && arr.length > 0) {
      var flag = arr.findIndex(function(value, index, arr) {
        return value.componentCode === code
      })
      if (flag === -1) {
        el.parentNode.removeChild(el)
      }
    } else {
      // 当前页面没有按钮,直接删除所有按钮
      el.parentNode.removeChild(el)
    }
  }
})
// 当没有某个按钮权限时,显示的元素
Vue.directive('btnNoPermission', {
  inserted: function(el, binding, vnode, oldVnode) {
    var code = binding.value.code
    var arr = router.history.current.meta.btn
    if (arr && arr.length > 0) {
      var flag = arr.findIndex(function(value, index, arr) {
        return value.componentCode === code
      })
      if (flag !== -1) {
        el.parentNode.removeChild(el)
      }
    }
  }
})

html使用:
        <template slot="dictName" slot-scope="text, record">
          <!-- 判断是没有该权限--》删除操作 -->
          <!-- 有该权限会显示 -->
          <span v-btnPermission="{code: 'DataDictionary_settingItems'}">
            <a v-if="record.validStatus===1" @click="settingData(record)">{{ record.dictName }}</a>
            <span v-else>{{ record.dictName }}</span>
          </span>
          <!-- 判断是有该权限--》删除操作 -->
          <!-- 无权限时所要显示的 -->
          <span v-btnNoPermission="{code: 'DataDictionary_settingItems'}">
            <span>{{ record.dictName }}</span>
          </span>
        </template>
2)封装的组件
<template>
  <span>
    <span v-if="btnList.length > 0">
      <a @click="func(btnList[0].funcName, btnList[0].funcArgs)">{{ btnList[0].name }}</a>
      <a-divider v-if="btnList.length > 1" type="vertical" />
    </span>
    <span v-if="btnList.length > 1">
      <a @click="func(btnList[1].funcName, btnList[1].funcArgs)">{{ btnList[1].name }}</a>
      <a-divider v-if="btnList.length > 2" type="vertical" />
    </span>
    <span v-if="btnList.length === 3">
      <a @click="func(btnList[2].funcName, btnList[2].funcArgs)">{{ btnList[2].name }}</a>
    </span>
    <a-dropdown v-if="btnList.length > 3">
      <a class="ant-dropdown-link">
        更多 <a-icon type="down" />
      </a>
      <a-menu slot="overlay">
        <template v-for="(item, index) in btnList">
          <a-menu-item v-if="index > 1" :key="item.code">
            <a @click="func(item.funcName, item.funcArgs)">{{ item.name }}</a>
          </a-menu-item>
        </template>
      </a-menu>
    </a-dropdown>
  </span>
</template>
<script>
export default {
  name: 'KTableBtn',
  props: {
    // 列表中某一条数据的对象
    record: {
      type: Object,
      default: () => {},
      required: true
    },
    // 列表中所有可能出现的按钮数组
    // 按钮对象示例
    // {
    //   code: 'GoodsList_putOnShelves', // 按钮code
    //   flag: record.saleStatus === 0,  // 按钮是否显示的逻辑(表达式或function返回值)
    //   name: '上架',                   // 按钮名称
    //   funcName: 'handleSaleStatus',   // 点击按钮调用的方法名称
    //   funcArgs: [1, false, record]    // 点击按钮调用的方法所需的参数数组
    // }
    btnArr: {
      type: Function,
      required: true
    }
  },
  data() {
    return {
      metaBtnList: [],
      btnList: []
    }
  },
  watch: {
    'record': {
      deep: true,
      handler(val) {
        this.createBtn()
      }
    }
  },
  created() {
    this.createBtn()
  },
  methods: {
    createBtn() {
      this.btnList = []
      // 从路由中拿到当前页面拥有的按钮权限列表metaBtnList
      this.metaBtnList = this.$route.meta.btn
      // 生成某条数据可以显示的按钮列表btnList
      var arr = this.btnArr(this.record)
      for (const item of arr.values()) {
        var btnPermission = this.metaBtnList.findIndex(e => {
          return e.componentCode === item.code
        })
        if (item.flag && btnPermission !== -1) {
          this.btnList.push(item)
        }
      }
    },
    func(funcName, arr) {
      this.$emit('btnClick', funcName, arr)
    }
  }
}
</script>



父组件使用:
  html:
        <span slot="action" slot-scope="text,record">
          <k-table-btn :btnArr="btnArr" :record="record" @btnClick="btnClick" />
        </span>
  js:
      // 表格操作按钮参数配置
      btnArr: record => {
        return [
          {
            code: 'DataDictionary_settingItems',
            flag: 'record.validStatus===1',
            name: '配置数据项',
            funcName: 'settingData',
            funcArgs: [record]
          },
          {
            code: 'DataDictionary_edit',
            flag: 'true',
            name: '编辑',
            funcName: 'editor',
            funcArgs: [record]
          },
          {
            code: 'DataDictionary_del',
            flag: 'true',
            name: '删除',
            funcName: 'delet',
            funcArgs: [record]
          }
        ]
      },


    // 触发表格操作按钮
    btnClick(funcName, arr) {
      this[funcName](...arr) // 触发对应的方法
    },

总结:通过获取当前账号的全部权限code,和对应的具体的code作比较
2、面包屑导航/:id丢失问题

难点:面包屑导航二级三级,二级携带/:id丢失不存在,解决。三级跳到二级,此时三级路由中如果有二级的id,可以在item.redirect('''''''''/:id)的冒号之后拼接上对应的id(id从当前页面路由中获取);也可以存在localStroage中
      if (redirect) {
        // 是否携带参数(进对/:key有效,页面路由携带query还是会丢失,暂时无解决方法)
        const startPos = redirect.indexOf(':')
        if (startPos !== -1) {
          const key = redirect.substring(startPos + 1,)
          redirect = redirect.replace(':' + key, this.$route.params[key])
        }
        this.$router.push(redirect)
        return
      }

3、key和keep-alive 路由跳转同路由但参数不同是页面刷新问题

// keep-alive 组件缓存
// key 组件key不同会让组件完整触发生命周期钩子(key不同,会强制替换元素而不是复用。会复用元素)
// key不会影响keep-alive
  <div id="app">
    <keep-alive :include="cachedViews">
      <router-view :key="key" />
    </keep-alive>
  </div>

  computed: {
    key() {
      return this.$route.name ? this.$router.name + +new Date() : this.$route + +new Date()
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值