index.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <script lang="ts" setup>
  2. import type { Recordable } from '@vben/types';
  3. import { reactive, ref } from 'vue';
  4. import {
  5. Page,
  6. VbenButton,
  7. VbenButtonGroup,
  8. VbenCheckButtonGroup,
  9. } from '@vben/common-ui';
  10. import { LoaderCircle, Square, SquareCheckBig } from '@vben/icons';
  11. import { Button, Card, message } from 'antdv-next';
  12. import { useVbenForm } from '#/adapter/form';
  13. const radioValue = ref<string | undefined>('a');
  14. const checkValue = ref(['a', 'b']);
  15. const options = [
  16. { label: '选项1', value: 'a' },
  17. { label: '选项2', value: 'b', num: 999 },
  18. { label: '选项3', value: 'c' },
  19. { label: '选项4', value: 'd' },
  20. { label: '选项5', value: 'e' },
  21. { label: '选项6', value: 'f' },
  22. ];
  23. function resetValues() {
  24. radioValue.value = undefined;
  25. checkValue.value = [];
  26. }
  27. function beforeChange(v: any, isChecked: boolean) {
  28. return new Promise((resolve) => {
  29. message.loading({
  30. content: `正在设置${v}为${isChecked ? '选中' : '未选中'}...`,
  31. duration: 0,
  32. key: 'beforeChange',
  33. });
  34. setTimeout(() => {
  35. message.success({ content: `${v} 已设置成功`, key: 'beforeChange' });
  36. resolve(true);
  37. }, 2000);
  38. });
  39. }
  40. const compProps = reactive({
  41. beforeChange: undefined,
  42. disabled: false,
  43. gap: 0,
  44. showIcon: true,
  45. size: 'middle',
  46. allowClear: false,
  47. } as Recordable<any>);
  48. const [Form] = useVbenForm({
  49. handleValuesChange(values) {
  50. Object.keys(values).forEach((k) => {
  51. if (k === 'beforeChange') {
  52. compProps[k] = values[k] ? beforeChange : undefined;
  53. } else {
  54. compProps[k] = values[k];
  55. }
  56. });
  57. },
  58. commonConfig: {
  59. labelWidth: 150,
  60. },
  61. schema: [
  62. {
  63. component: 'RadioGroup',
  64. componentProps: {
  65. options: [
  66. { label: '大', value: 'large' },
  67. { label: '中', value: 'middle' },
  68. { label: '小', value: 'small' },
  69. ],
  70. },
  71. defaultValue: compProps.size,
  72. fieldName: 'size',
  73. label: '尺寸',
  74. },
  75. {
  76. component: 'RadioGroup',
  77. componentProps: {
  78. options: [
  79. { label: '无', value: 0 },
  80. { label: '小', value: 5 },
  81. { label: '中', value: 15 },
  82. { label: '大', value: 30 },
  83. ],
  84. },
  85. defaultValue: compProps.gap,
  86. fieldName: 'gap',
  87. label: '间距',
  88. },
  89. {
  90. component: 'Switch',
  91. defaultValue: compProps.showIcon,
  92. fieldName: 'showIcon',
  93. label: '显示图标',
  94. },
  95. {
  96. component: 'Switch',
  97. defaultValue: compProps.disabled,
  98. fieldName: 'disabled',
  99. label: '禁用',
  100. },
  101. {
  102. component: 'Switch',
  103. defaultValue: false,
  104. fieldName: 'beforeChange',
  105. label: '前置回调',
  106. },
  107. {
  108. component: 'Switch',
  109. defaultValue: false,
  110. fieldName: 'allowClear',
  111. label: '允许清除',
  112. help: '单选时是否允许取消选中(值为undefined)',
  113. },
  114. {
  115. component: 'InputNumber',
  116. defaultValue: 0,
  117. fieldName: 'maxCount',
  118. label: '最大选中数量',
  119. help: '多选时有效,0表示不限制',
  120. },
  121. ],
  122. showDefaultActions: false,
  123. submitOnChange: true,
  124. });
  125. function onBtnClick(value: any) {
  126. const opt = options.find((o) => o.value === value);
  127. if (opt) {
  128. message.success(`点击了按钮${opt.label},value = ${value}`);
  129. }
  130. }
  131. </script>
  132. <template>
  133. <Page
  134. title="VbenButtonGroup 按钮组"
  135. description="VbenButtonGroup是一个按钮容器,用于包裹一组按钮,协调整体样式。VbenCheckButtonGroup则可以作为一个表单组件,提供单选或多选功能"
  136. >
  137. <Card title="基本用法">
  138. <template #extra>
  139. <Button type="primary" @click="resetValues">清空值</Button>
  140. </template>
  141. <p class="mt-4">按钮组:</p>
  142. <div class="mt-2 flex flex-col gap-2">
  143. <VbenButtonGroup v-bind="compProps" border>
  144. <VbenButton
  145. v-for="btn in options"
  146. :key="btn.value"
  147. variant="link"
  148. @click="onBtnClick(btn.value)"
  149. >
  150. {{ btn.label }}
  151. </VbenButton>
  152. </VbenButtonGroup>
  153. <VbenButtonGroup v-bind="compProps" border>
  154. <VbenButton
  155. v-for="btn in options"
  156. :key="btn.value"
  157. variant="outline"
  158. @click="onBtnClick(btn.value)"
  159. >
  160. {{ btn.label }}
  161. </VbenButton>
  162. </VbenButtonGroup>
  163. </div>
  164. <p class="mt-4">单选:{{ radioValue }}</p>
  165. <div class="mt-2 flex flex-col gap-2">
  166. <VbenCheckButtonGroup
  167. v-model="radioValue"
  168. :options="options"
  169. v-bind="compProps"
  170. />
  171. </div>
  172. <p class="mt-4">单选插槽:{{ radioValue }}</p>
  173. <div class="mt-2 flex flex-col gap-2">
  174. <VbenCheckButtonGroup
  175. v-model="radioValue"
  176. :options="options"
  177. v-bind="compProps"
  178. >
  179. <template #option="{ label, value, data }">
  180. <div class="flex items-center">
  181. <span>{{ label }}</span>
  182. <span class="ml-2 text-gray-400">{{ value }}</span>
  183. <span v-if="data.num" class="white ml-2">{{ data.num }}</span>
  184. </div>
  185. </template>
  186. </VbenCheckButtonGroup>
  187. </div>
  188. <p class="mt-4">多选{{ checkValue }}</p>
  189. <div class="mt-2 flex flex-col gap-2">
  190. <VbenCheckButtonGroup
  191. v-model="checkValue"
  192. multiple
  193. :options="options"
  194. v-bind="compProps"
  195. />
  196. </div>
  197. <p class="mt-4">自定义图标{{ checkValue }}</p>
  198. <div class="mt-2 flex flex-col gap-2">
  199. <VbenCheckButtonGroup
  200. v-model="checkValue"
  201. multiple
  202. :options="options"
  203. v-bind="compProps"
  204. >
  205. <template #icon="{ loading, checked }">
  206. <LoaderCircle class="animate-spin" v-if="loading" />
  207. <SquareCheckBig v-else-if="checked" />
  208. <Square v-else />
  209. </template>
  210. </VbenCheckButtonGroup>
  211. </div>
  212. </Card>
  213. <Card title="设置" class="mt-4">
  214. <Form />
  215. </Card>
  216. </Page>
  217. </template>