checkBoxGroup.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <style lang="scss">
  2. .ul-radio-group {
  3. border-radius: 5px;
  4. height: 32px;
  5. padding: 0;
  6. margin: 0;
  7. border: none;
  8. background: transparent;
  9. .btn {
  10. background: transparent;
  11. padding: 0;
  12. margin: 0;
  13. border: none;
  14. }
  15. .item {
  16. min-width: 80px;
  17. padding: 0px 15px;
  18. text-align: center;
  19. display: inline-block;
  20. border: 1px solid #ccc;
  21. border-left: 0;
  22. height: 32px;
  23. line-height: 32px;
  24. cursor: pointer;
  25. .checkbox-button-input {
  26. width: 0;
  27. height: 0;
  28. opacity: 0;
  29. }
  30. .ant-checkbox {
  31. display: none;
  32. }
  33. }
  34. .bgcolor {
  35. color: rgba(0, 0, 0, 0.25);
  36. background-color: #f5f5f5;
  37. border-color: #d9d9d9;
  38. cursor: not-allowed;
  39. }
  40. .item::after {
  41. content: '';
  42. position: absolute;
  43. right: 1px;
  44. top: -2px;
  45. width: 0;
  46. height: 0;
  47. border-top: 6px solid transparent;
  48. border-bottom: 6px solid transparent;
  49. border-left: 6px solid;
  50. border-left-color: #e0e0e0;
  51. -webkit-transform: rotate(-45deg);
  52. -ms-transform: rotate(-45deg);
  53. transform: rotate(-45deg);
  54. border-radius: 2px;
  55. }
  56. .item:hover {
  57. color: #1890ff;
  58. }
  59. .selection {
  60. color: #fff;
  61. background: #1890ff;
  62. // border-color: #1890ff;
  63. }
  64. .item.selection:hover {
  65. color: #fff;
  66. background: #40a9ff;
  67. }
  68. .item.selection:after {
  69. border-left: 6px solid #1890ff;
  70. }
  71. .item:hover::after {
  72. // border-color: #40a9ff;
  73. border-left: 6px solid #40a9ff;
  74. }
  75. .bgcolor:hover {
  76. color: rgba(0, 0, 0, 0.25);
  77. background-color: #f5f5f5;
  78. border-color: #d9d9d9;
  79. cursor: not-allowed;
  80. }
  81. .bgcolor:hover::after {
  82. // border-color: #40a9ff;
  83. border-left: 6px solid #e0e0e0;
  84. }
  85. .bgcolor.selection:after {
  86. border-left: 6px solid #e0e0e0;
  87. }
  88. .bgcolor.selection {
  89. color: rgba(0, 0, 0, 0.25);
  90. background-color: #f5f5f5;
  91. border-color: #d9d9d9;
  92. cursor: not-allowed;
  93. }
  94. .bgcolor.selection:hover {
  95. // color: #1890ff;
  96. color: rgba(0, 0, 0, 0.25);
  97. background-color: #f5f5f5;
  98. border-color: #d9d9d9;
  99. cursor: not-allowed;
  100. }
  101. .bgcolor.selection:after {
  102. border-left: 6px solid #e0e0e0;
  103. }
  104. .ant-checkbox-wrapper + .ant-checkbox-wrapper {
  105. margin-left: 0;
  106. }
  107. }
  108. .ul-radio-group .item:first-child {
  109. border-radius: 5px 0 0 5px;
  110. border-left: 1px solid #ccc;
  111. }
  112. .ul-radio-group .item.selection:first-child {
  113. border-radius: 5px 0 0 5px;
  114. border-left: 1px solid #1890ff;
  115. }
  116. .ul-radio-group .item.selection:nth-child(2) {
  117. border-left: 1px solid #1890ff;
  118. }
  119. .ul-radio-group .item:first-child:after {
  120. border-left: 0;
  121. }
  122. .ul-radio-group .item:last-child {
  123. border-radius: 0px 5px 5px 0px;
  124. }
  125. </style>
  126. <template>
  127. <div class="ul-radio-group">
  128. <a-checkbox-group v-model="selectedVal" :disabled="disabled" style="width: 100%">
  129. <a-checkbox
  130. v-for="item of selectOption"
  131. :label="item.label"
  132. :key="item.value"
  133. :value="item.value"
  134. :class="{
  135. item: true && userButton,
  136. selection: selectedVal && selectedVal.indexOf(item.value) > -1 && userButton,
  137. bgcolor: item.disabled,
  138. }"
  139. >{{ item.label }}</a-checkbox
  140. >
  141. </a-checkbox-group>
  142. </div>
  143. </template>
  144. <script>
  145. // import { dictionary } from '@/components/service/core/dictionary'
  146. import { isArray } from '@/utils/Tools'
  147. import { httpAction, getAction } from '@/api/manage'
  148. export default {
  149. name: 'CheckboxGroup', // checkbox组件二次封装
  150. props: {
  151. userButton: {
  152. type: Boolean,
  153. default() {
  154. return true
  155. },
  156. },
  157. code: {
  158. // 参数code
  159. type: String,
  160. default: '',
  161. },
  162. allValue: {
  163. type: Boolean,
  164. default() {
  165. return false
  166. },
  167. },
  168. options: {
  169. // 外部传入的option 可替代请求项
  170. type: Array,
  171. default() {
  172. return []
  173. },
  174. },
  175. value: {
  176. // v-model绑定值
  177. type: [Number, Array, String],
  178. default() {
  179. return []
  180. },
  181. },
  182. label: {
  183. // label 绑定值
  184. type: [Array, String],
  185. default: '',
  186. },
  187. radioStyle: {
  188. // 是否复选框模拟单选效果
  189. type: Boolean,
  190. default: false,
  191. },
  192. disabled: {
  193. // 是否禁用
  194. type: Boolean,
  195. default: false,
  196. },
  197. },
  198. components: {},
  199. data() {
  200. return {
  201. selectOption: [],
  202. }
  203. },
  204. watch: {
  205. options(val) {
  206. if (isArray(val)) {
  207. this.selectOption.splice(0, this.selectOption.length)
  208. this.selectOption.push(...val)
  209. }
  210. },
  211. selectedVal(n, o) {
  212. if (this.radioStyle && !this.allValue) {
  213. if (n.length == 0) {
  214. this.selectedVal = o
  215. }
  216. }
  217. },
  218. },
  219. computed: {
  220. selectedVal: {
  221. get: function () {
  222. return this.value
  223. },
  224. set: function (val) {
  225. this.selectChange(val)
  226. },
  227. },
  228. },
  229. mounted() {
  230. this.$nextTick(() => {
  231. if (this.code && this.options.length == 0) {
  232. // 如果code值不为空且options.lengt==0, 则去请求字典项
  233. this.getOptions()
  234. } else {
  235. // 否则直接获取外部传入的options
  236. this.selectOption.splice(0, this.selectOption.length)
  237. this.selectOption.push(...this.options)
  238. }
  239. })
  240. },
  241. methods: {
  242. getOptions() {
  243. // 获取字典项
  244. getAction('/sys/dictItem/list', { dictId: this.code, pageSize: 1000, pageNo: 1 }).then((res) => {
  245. if (res.success && isArray(res.result.records)) {
  246. var data = res.result.records
  247. data = data.map((item) => {
  248. return {
  249. label: item.itemText,
  250. value: item.itemValue,
  251. ...item,
  252. }
  253. })
  254. if (this.allValue) {
  255. data.unshift({ label: '不检查', value: 'unlimited' })
  256. if (this.value == '' || this.value == '' || this.value == null || this.value.length == 0) {
  257. this.selectedVal = ['unlimited']
  258. }
  259. } else {
  260. if (this.value == '' || this.value == '' || this.value == null || this.value.length == 0) {
  261. this.selectedVal = []
  262. }
  263. }
  264. this.selectOption.push(...data)
  265. }
  266. })
  267. },
  268. selectChange(val) {
  269. // 选择事件
  270. if (!this.radioStyle) {
  271. // 多选
  272. var retrunData = []
  273. let label = this.selectOption.filter((v) => val.findIndex((item) => item == v.value) > -1).map((v) => v.label)
  274. if (this.allValue) {
  275. if (val.findIndex((item) => item == 'unlimited') == 0) {
  276. retrunData = val.slice(-1)
  277. } else if (val.findIndex((item) => item == 'unlimited') == val.length - 1) {
  278. retrunData = ['unlimited']
  279. } else {
  280. retrunData = val
  281. }
  282. } else {
  283. retrunData = val
  284. }
  285. this.$emit('input', retrunData)
  286. this.$emit('update:label', label)
  287. this.$emit('change', val)
  288. // this.consoleFun('VALUE: ', val, 'LABEL:', label)
  289. } else {
  290. // 模拟单选radio效果
  291. let selectVal = []
  292. if (this.allValue) {
  293. if (val.length == 0) {
  294. selectVal = ['unlimited']
  295. }
  296. } else {
  297. if (val.length == 0) {
  298. selectVal = []
  299. }
  300. }
  301. if (val.length > 0) {
  302. selectVal = val.slice(-1)
  303. }
  304. let label = this.selectOption
  305. .filter((v) => selectVal.findIndex((item) => item == v.value) > -1)
  306. .map((v) => v.label)
  307. this.$emit('input', selectVal)
  308. this.$emit('update:label', label)
  309. this.$emit('change', selectVal)
  310. // this.consoleFun('VALUE: ', selectVal, 'LABEL:', label)
  311. }
  312. },
  313. emitChange(...args) {
  314. // emit change事件
  315. this.$emit('change', ...args)
  316. },
  317. consoleFun(...args) {
  318. // 打印信息
  319. if (process.env.NODE_ENV == 'development') {
  320. console.log(...args)
  321. }
  322. },
  323. },
  324. }
  325. </script>