فهرست منبع

feat: 新增业务范围选择行组件

cuiyalong 4 سال پیش
والد
کامیت
c03b15c2ee

+ 63 - 0
src/components/selector/BusinessScopeSelector.vue

@@ -0,0 +1,63 @@
+<template>
+  <selector-card
+    class="business-scope-selector"
+    :cardType="selectorType"
+    @onConfirm="onConfirm"
+    @onCancel="onCancel"
+  >
+    <div slot="header" v-if="selectorType === 'card'" key="header">业务范围</div>
+    <div slot="header" class="s-header" v-if="selectorType === 'line'" key="header">业务范围:</div>
+    <BusinessScopeSelectorContent
+      ref="businessScopeSelectorContent"
+      :selectorType="selectorType"
+      :initList="initList"
+      @onChange="onChange"
+    />
+  </selector-card>
+</template>
+
+<script>
+import SelectorCard from '@/components/selector/SelectorCard.vue'
+import BusinessScopeSelectorContent from '@/components/selector/BusinessScopeSelectorContent.vue'
+export default {
+  name: 'business-scope-selector',
+  components: {
+    SelectorCard,
+    BusinessScopeSelectorContent
+  },
+  props: {
+    selectorType: {
+      type: String,
+      default: 'line'
+    },
+    initList: {
+      type: Array,
+      default () {
+        return []
+      }
+    }
+  },
+  data () {
+    return {}
+  },
+  created () {},
+  methods: {
+    setState (data) {
+      return this.$refs.businessScopeSelectorContent.setState(data)
+    },
+    getState () {
+      return this.$refs.businessScopeSelectorContent.getState()
+    },
+    onCancel () {
+      this.$emit('onCancel')
+    },
+    onConfirm () {
+      const state = this.getState()
+      this.$emit('onConfirm', state)
+    },
+    onChange (state) {
+      this.$emit('onChange', state)
+    }
+  }
+}
+</script>

+ 159 - 0
src/components/selector/BusinessScopeSelectorContent.vue

@@ -0,0 +1,159 @@
+<template>
+  <div class="selector-content" v-if="selectorType === 'card'" key="s-content">
+    暂不提供业务范围的card组件
+  </div>
+  <div class="selector-content" :class="{ 'no-more': !showMore }" v-else-if="selectorType === 'line'" key="s-content">
+    <span class="action-button show-more" @click="showMore = !showMore" v-if="needShowMore">
+      <span class="action-text">{{ showMore ? '收起' : '更多' }}</span>
+      <span class="el-icon-arrow-down" :class="showMore ? 'rotate180' : ''"></span>
+    </span>
+    <div class="select-group-container">
+      <div
+        v-for="(item, index) in bScopeList"
+        :key="index"
+        class="j-button-item bgc"
+        :class="{
+          active: item.selected
+        }"
+        @click="buttonClick(item)"
+      >{{ item.name }}</div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'business-scope-selector-content',
+  props: {
+    selectorType: {
+      type: String,
+      default: 'card' // card/line
+    },
+    initList: {
+      type: Array,
+      default () {
+        return []
+      }
+    }
+  },
+  data () {
+    return {
+      needShowMore: false,
+      showMore: false,
+      bScopeList: [],
+      bScopeItemExp: {
+        name: '全部',
+        value: '',
+        selected: true
+      }
+    }
+  },
+  created () {
+    this.init()
+  },
+  mounted () {
+    this.calcNeedShowMoreOrNot()
+  },
+  methods: {
+    init () {
+      const list = [JSON.parse(JSON.stringify(this.bScopeItemExp))]
+      this.initList.forEach(item => {
+        list.push({
+          name: item,
+          value: item,
+          selected: false
+        })
+      })
+      this.bScopeList = list
+    },
+    setState (data = []) {
+      if (!Array.isArray) return
+      if (data.length === 0) {
+        this.bScopeList.forEach(item => (item.selected = false))
+        this.bScopeList[0].selected = true
+      } else {
+        this.bScopeList.forEach(item => {
+          if (data.includes(item.name)) {
+            item.selected = true
+          }
+        })
+      }
+    },
+    getState () {
+      const arr = []
+      if (this.bScopeList[0].selected) {
+        return arr
+      }
+      return this.bScopeList.filter(item => item.selected).map(item => item.name)
+    },
+    onChange () {
+      const state = this.getState()
+      this.$emit('onChange', state)
+    },
+    buttonClick (item) {
+      if (item.name === this.bScopeItemExp.name) {
+        this.setState()
+      } else {
+        this.bScopeList[0].selected = false
+        item.selected = !item.selected
+
+        const { allSelected, allNotSelected } = this.checkAllSelectedState()
+        if (allSelected || allNotSelected) {
+          this.setState()
+        }
+      }
+    },
+    // 除了全部按钮之外的按钮的状态
+    checkAllSelectedState () {
+      const stateArr = []
+
+      this.bScopeList.forEach(item => {
+        if (item.name !== this.bScopeItemExp.name) {
+          stateArr.push(item.selected)
+        }
+      })
+
+      return {
+        // 找不到false,就说明全部被选中
+        allSelected: stateArr.indexOf(false) === -1,
+        // 找不到true,就说明没有一个被选中
+        allNotSelected: stateArr.indexOf(true) === -1
+      }
+    },
+    // 计算需不需要进行展开等操作
+    calcNeedShowMoreOrNot () {
+      let buttonListTop = []
+      const wrapper = document.querySelector('.business-scope-selector.s-line')
+      const container = wrapper.querySelector('.select-group-container')
+      const buttonDOMList = container.querySelectorAll('.j-button-item')
+      buttonDOMList.forEach(item => {
+        buttonListTop.push(item.getBoundingClientRect().top)
+      })
+      // 数组去重
+      buttonListTop = Array.from(new Set(buttonListTop))
+      this.needShowMore = buttonListTop.length > 1
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  .s-card {}
+
+  .s-line {
+    .selector-content {
+      position: relative;
+      display: flex;
+      width: 100%;
+      &.no-more {
+        height: 38px;
+        overflow: hidden;
+      }
+    }
+    .select-group-container {
+      display: flex;
+      padding-right: 40px;
+      flex-wrap: wrap;
+    }
+  }
+</style>

+ 1 - 1
src/components/selector/TimeSelector.vue

@@ -35,7 +35,7 @@ export default {
   },
   created () {},
   methods: {
-    setInfoTypeState (data) {
+    setState (data) {
       return this.$refs.timeSelectorContent.setState(data)
     },
     getState () {