check-button.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <script setup lang="ts">
  2. import { ref, watch } from "vue";
  3. import { message } from "@/utils/message";
  4. import { getKeyList } from "@pureadmin/utils";
  5. defineOptions({
  6. name: "CheckButton"
  7. });
  8. const spaceSize = ref(20);
  9. const size = ref("default");
  10. const dynamicSize = ref();
  11. const checked = ref(true);
  12. const radio = ref("wait");
  13. const radioBox = ref("complete");
  14. const radioCustom = ref("progress");
  15. const checkboxGroup = ref(["apple", "tomato"]);
  16. const checkboxGroupBox = ref(["cucumber", "onion", "blueberry"]);
  17. const checkboxGroupCustom = ref(["tomato", "watermelon", "strawberry"]);
  18. /** 单选(可控制间距的按钮样式) */
  19. const checkTag = ref([
  20. {
  21. title: "等待中",
  22. checked: false
  23. },
  24. {
  25. title: "进行中",
  26. checked: true
  27. },
  28. {
  29. title: "已完成",
  30. checked: false
  31. }
  32. ]);
  33. const curTagMap = ref({});
  34. function onChecked(tag, index) {
  35. if (size.value === "disabled") return;
  36. curTagMap.value[index] = Object.assign({
  37. ...tag,
  38. checked: !tag.checked
  39. });
  40. checkTag.value.map(item => (item.checked = false));
  41. checkTag.value[index].checked = curTagMap.value[index].checked;
  42. const { title, checked } = curTagMap.value[index];
  43. message(checked ? `已选中${title}` : `取消选中${title}`, {
  44. type: "success"
  45. });
  46. }
  47. /** 多选(可控制间距的按钮样式) */
  48. const checkGroupTag = ref([
  49. {
  50. title: "苹果",
  51. checked: true
  52. },
  53. {
  54. title: "西红柿",
  55. checked: true
  56. },
  57. {
  58. title: "香蕉",
  59. checked: false
  60. }
  61. ]);
  62. const curTagGroupMap = ref({});
  63. function onGroupChecked(tag, index) {
  64. if (size.value === "disabled") return;
  65. curTagGroupMap.value[index] = Object.assign({
  66. ...tag,
  67. checked: !tag.checked
  68. });
  69. checkGroupTag.value[index].checked = curTagGroupMap.value[index].checked;
  70. }
  71. function onSingleChecked() {
  72. if (size.value === "disabled") return;
  73. checked.value = !checked.value;
  74. }
  75. watch(size, val =>
  76. val === "disabled"
  77. ? (dynamicSize.value = "default")
  78. : (dynamicSize.value = size.value)
  79. );
  80. </script>
  81. <template>
  82. <el-card shadow="never">
  83. <template #header>
  84. <div class="card-header">
  85. <el-space wrap :size="40">
  86. <span style="font-size: 16px; font-weight: 800"> 可选按钮 </span>
  87. <el-radio-group v-model="size">
  88. <el-radio value="large">大尺寸</el-radio>
  89. <el-radio value="default">默认尺寸</el-radio>
  90. <el-radio value="small">小尺寸</el-radio>
  91. <el-radio value="disabled">禁用</el-radio>
  92. </el-radio-group>
  93. </el-space>
  94. </div>
  95. <el-link
  96. class="mt-2"
  97. href="https://github.com/pure-admin/vue-pure-admin/blob/main/src/views/components/check-button.vue"
  98. target="_blank"
  99. >
  100. 代码位置 src/views/components/check-button.vue
  101. </el-link>
  102. </template>
  103. <div class="mb-2">单选(紧凑风格的按钮样式)</div>
  104. <el-radio-group
  105. v-model="radio"
  106. :size="dynamicSize"
  107. :disabled="size === 'disabled'"
  108. >
  109. <el-radio-button value="wait">等待中</el-radio-button>
  110. <el-radio-button value="progress">进行中</el-radio-button>
  111. <el-radio-button value="complete">已完成</el-radio-button>
  112. </el-radio-group>
  113. <el-divider />
  114. <div class="mb-2">单选(带有边框)</div>
  115. <el-radio-group
  116. v-model="radioBox"
  117. :size="dynamicSize"
  118. :disabled="size === 'disabled'"
  119. >
  120. <el-radio value="wait" border>等待中</el-radio>
  121. <el-radio value="progress" border>进行中</el-radio>
  122. <el-radio value="complete" border>已完成</el-radio>
  123. </el-radio-group>
  124. <el-divider />
  125. <div class="mb-2">单选(自定义内容)</div>
  126. <el-radio-group
  127. v-model="radioCustom"
  128. :size="dynamicSize"
  129. :disabled="size === 'disabled'"
  130. >
  131. <el-radio-button value="wait">
  132. <span class="flex">
  133. <IconifyIconOnline icon="ri:progress-8-fill" class="mr-1" />
  134. 等待中
  135. </span>
  136. </el-radio-button>
  137. <el-radio-button value="progress">
  138. <span class="flex">
  139. <IconifyIconOnline icon="ri:progress-6-line" class="mr-1" />
  140. 进行中
  141. </span>
  142. </el-radio-button>
  143. <el-radio-button value="complete">
  144. <span class="flex">
  145. <IconifyIconOnline icon="ri:progress-8-line" class="mr-1" />
  146. 已完成
  147. </span>
  148. </el-radio-button>
  149. </el-radio-group>
  150. <el-divider />
  151. <div class="mb-2">多选(紧凑风格的按钮样式)</div>
  152. <el-checkbox-group
  153. v-model="checkboxGroup"
  154. :size="dynamicSize"
  155. :disabled="size === 'disabled'"
  156. >
  157. <el-checkbox-button value="apple">苹果</el-checkbox-button>
  158. <el-checkbox-button value="tomato">西红柿</el-checkbox-button>
  159. <el-checkbox-button value="banana">香蕉</el-checkbox-button>
  160. </el-checkbox-group>
  161. <el-divider />
  162. <div class="mb-2">多选(带有边框)</div>
  163. <el-checkbox-group
  164. v-model="checkboxGroupBox"
  165. :size="dynamicSize"
  166. :disabled="size === 'disabled'"
  167. >
  168. <el-checkbox value="cucumber" border>黄瓜</el-checkbox>
  169. <el-checkbox value="onion" border>洋葱</el-checkbox>
  170. <el-checkbox value="blueberry" border>蓝莓</el-checkbox>
  171. </el-checkbox-group>
  172. <el-divider />
  173. <div class="mb-2">多选(来点不一样的体验)</div>
  174. <el-checkbox-group
  175. v-model="checkboxGroupCustom"
  176. class="pure-checkbox"
  177. :size="dynamicSize"
  178. :disabled="size === 'disabled'"
  179. >
  180. <el-checkbox-button value="tomato">
  181. <span class="flex">
  182. <IconifyIconOnline icon="streamline-emojis:tomato" class="mr-1" />
  183. 番茄
  184. </span>
  185. </el-checkbox-button>
  186. <el-checkbox-button value="watermelon">
  187. <span class="flex">
  188. <IconifyIconOnline
  189. icon="streamline-emojis:watermelon-1"
  190. class="mr-1"
  191. />
  192. 西瓜
  193. </span>
  194. </el-checkbox-button>
  195. <el-checkbox-button value="strawberry">
  196. <span class="flex">
  197. <IconifyIconOnline
  198. icon="streamline-emojis:strawberry-1"
  199. class="mr-1"
  200. />
  201. 草莓
  202. </span>
  203. </el-checkbox-button>
  204. </el-checkbox-group>
  205. <el-divider />
  206. <div>可控制间距的按钮样式</div>
  207. <el-slider
  208. v-model="spaceSize"
  209. class="mb-2 w-[300px]!"
  210. :show-tooltip="false"
  211. :disabled="size === 'disabled'"
  212. />
  213. <div class="mb-2">单选</div>
  214. <el-space wrap :size="spaceSize">
  215. <el-check-tag
  216. v-for="(tag, index) in checkTag"
  217. :key="index"
  218. :class="[
  219. 'select-none',
  220. size === 'disabled' && 'tag-disabled',
  221. tag.checked && 'is-active'
  222. ]"
  223. :checked="tag.checked"
  224. @change="onChecked(tag, index)"
  225. >
  226. {{ tag.title }}
  227. </el-check-tag>
  228. </el-space>
  229. <div class="mb-2 mt-4">
  230. 多选
  231. {{
  232. getKeyList(
  233. checkGroupTag.filter(tag => tag.checked),
  234. "title"
  235. )
  236. }}
  237. </div>
  238. <el-space wrap :size="spaceSize">
  239. <el-check-tag
  240. v-for="(tag, index) in checkGroupTag"
  241. :key="index"
  242. :class="[
  243. 'select-none',
  244. size === 'disabled' && 'tag-disabled',
  245. tag.checked && 'is-active'
  246. ]"
  247. :checked="tag.checked"
  248. @change="onGroupChecked(tag, index)"
  249. >
  250. {{ tag.title }}
  251. </el-check-tag>
  252. </el-space>
  253. <el-divider />
  254. <div class="mb-2">单个可选按钮</div>
  255. <el-check-tag
  256. :class="[
  257. 'select-none',
  258. size === 'disabled' && 'tag-disabled',
  259. checked && 'is-active'
  260. ]"
  261. :checked="checked"
  262. @change="onSingleChecked"
  263. >
  264. 一个人也要努力 😊
  265. </el-check-tag>
  266. </el-card>
  267. </template>
  268. <style lang="scss" scoped>
  269. :deep(.el-divider--horizontal) {
  270. margin: 17px 0;
  271. }
  272. :deep(.pure-checkbox) {
  273. .el-checkbox-button {
  274. /* 选中时的自定义样式 */
  275. &.is-checked {
  276. .el-checkbox-button__inner {
  277. color: var(--el-color-primary);
  278. background-color: var(--el-color-primary-light-8);
  279. border-color: transparent;
  280. border-left-color: #fff;
  281. }
  282. }
  283. /* 禁用时的自定义样式 */
  284. &.is-disabled {
  285. .el-checkbox-button__inner {
  286. color: var(--el-disabled-text-color);
  287. background-color: var(
  288. --el-button-disabled-bg-color,
  289. var(--el-fill-color-blank)
  290. );
  291. border-color: var(
  292. --el-button-disabled-border-color,
  293. var(--el-border-color-light)
  294. );
  295. }
  296. }
  297. }
  298. }
  299. /** 可控制间距的按钮禁用样式 */
  300. .tag-disabled {
  301. color: var(--el-disabled-text-color);
  302. cursor: not-allowed;
  303. background-color: var(--el-color-info-light-9);
  304. &:hover {
  305. background-color: var(--el-color-info-light-9);
  306. }
  307. &.is-active {
  308. background-color: var(--el-color-primary-light-9);
  309. }
  310. }
  311. </style>