segmented.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <script setup lang="tsx">
  2. import { h, ref, watch } from "vue";
  3. import { message } from "@/utils/message";
  4. import HomeFilled from "~icons/ep/home-filled";
  5. import { useRenderIcon } from "@/components/ReIcon/src/hooks";
  6. import Segmented, { type OptionsType } from "@/components/ReSegmented";
  7. defineOptions({
  8. name: "Segmented"
  9. });
  10. /** 基础用法 */
  11. const value = ref(4); // 必须为number类型
  12. const size = ref("default");
  13. const dynamicSize = ref();
  14. const optionsBasis: Array<OptionsType> = [
  15. {
  16. label: "周一"
  17. },
  18. {
  19. label: "周二"
  20. },
  21. {
  22. label: "周三"
  23. },
  24. {
  25. label: "周四"
  26. },
  27. {
  28. label: "周五"
  29. }
  30. ];
  31. /** tooltip 提示 */
  32. const optionsTooltip: Array<OptionsType> = [
  33. {
  34. label: "周一",
  35. tip: "周一启航,新的篇章"
  36. },
  37. {
  38. label: "周二",
  39. tip: "周二律动,携手共进"
  40. },
  41. {
  42. label: "周三",
  43. tip: "周三昂扬,激情不减"
  44. },
  45. {
  46. label: "周四",
  47. tip: "周四精进,事半功倍"
  48. },
  49. {
  50. label: "周五",
  51. tip: "周五喜悦,收尾归档"
  52. }
  53. ];
  54. /** 禁用 */
  55. const optionsDisabled: Array<OptionsType> = [
  56. {
  57. label: "周一"
  58. },
  59. {
  60. label: "周二"
  61. },
  62. {
  63. label: "周三",
  64. disabled: true
  65. },
  66. {
  67. label: "周四"
  68. },
  69. {
  70. label: "周五",
  71. disabled: true
  72. }
  73. ];
  74. /** block */
  75. const optionsBlock: Array<OptionsType> = [
  76. {
  77. label: "周一"
  78. },
  79. {
  80. label: "周二"
  81. },
  82. {
  83. label: "周三"
  84. },
  85. {
  86. label: "周四"
  87. },
  88. {
  89. label: "周五喜悦,收尾归档,周末倒计时",
  90. tip: "周五喜悦,收尾归档,周末倒计时"
  91. }
  92. ];
  93. /** 可设置图标 */
  94. const optionsIcon: Array<OptionsType> = [
  95. {
  96. label: "周一",
  97. icon: HomeFilled
  98. },
  99. {
  100. label: "周二"
  101. },
  102. {
  103. label: "周三",
  104. icon: "ri:terminal-window-line"
  105. },
  106. {
  107. label: "周四"
  108. },
  109. {
  110. label: "周五",
  111. icon: "streamline-emojis:2"
  112. }
  113. ];
  114. /** 只设置图标 */
  115. const optionsOnlyIcon: Array<OptionsType> = [
  116. {
  117. icon: HomeFilled
  118. },
  119. {
  120. icon: "ri:terminal-window-line"
  121. },
  122. {
  123. icon: "streamline-emojis:cow-face"
  124. },
  125. {
  126. icon: "streamline-emojis:airplane"
  127. },
  128. {
  129. icon: "streamline-emojis:2"
  130. }
  131. ];
  132. /** 自定义渲染 */
  133. const optionsLabel: Array<OptionsType> = [
  134. {
  135. label: () => (
  136. <div>
  137. {h(useRenderIcon(HomeFilled), {
  138. class: "m-auto mt-1 w-[18px] h-[18px]"
  139. })}
  140. <p>周一</p>
  141. </div>
  142. )
  143. },
  144. {
  145. label: () => (
  146. <div>
  147. {h(useRenderIcon("ri:terminal-window-line"), {
  148. class: "m-auto mt-1 w-[18px] h-[18px]"
  149. })}
  150. <p>周二</p>
  151. </div>
  152. )
  153. },
  154. {
  155. label: () => (
  156. <div>
  157. {h(useRenderIcon("streamline-emojis:cow-face"), {
  158. class: "m-auto mt-1 w-[18px] h-[18px]"
  159. })}
  160. <p>周三</p>
  161. </div>
  162. )
  163. }
  164. ];
  165. const optionsChange: Array<OptionsType> = [
  166. {
  167. label: "周一",
  168. value: 1
  169. },
  170. {
  171. label: "周二",
  172. value: 2
  173. },
  174. {
  175. label: "周三",
  176. value: 3
  177. }
  178. ];
  179. /** change 事件 */
  180. function onChange({ index, option }) {
  181. const { label, value } = option;
  182. message(`当前选中项索引为:${index},名字为${label},值为${value}`, {
  183. type: "success"
  184. });
  185. }
  186. watch(size, val => (dynamicSize.value = size.value));
  187. </script>
  188. <template>
  189. <el-card shadow="never">
  190. <template #header>
  191. <div class="card-header">
  192. <el-space wrap :size="40">
  193. <span style="font-size: 16px; font-weight: 800"> 分段控制器 </span>
  194. <el-radio-group v-model="size">
  195. <el-radio value="large">大尺寸</el-radio>
  196. <el-radio value="default">默认尺寸</el-radio>
  197. <el-radio value="small">小尺寸</el-radio>
  198. </el-radio-group>
  199. </el-space>
  200. </div>
  201. <el-link
  202. class="mt-2"
  203. href="https://github.com/pure-admin/vue-pure-admin/blob/main/src/views/components/segmented.vue"
  204. target="_blank"
  205. >
  206. 代码位置 src/views/components/segmented.vue
  207. </el-link>
  208. </template>
  209. <el-scrollbar>
  210. <div class="mb-2">
  211. 基础用法(v-model)<span class="text-primary">
  212. {{ optionsBasis[value].label }}
  213. </span>
  214. </div>
  215. <Segmented v-model="value" :options="optionsBasis" :size="dynamicSize" />
  216. <el-divider />
  217. <div class="mb-2">tooltip 提示</div>
  218. <Segmented :options="optionsTooltip" :size="dynamicSize" />
  219. <el-divider />
  220. <div class="mb-2">change 事件</div>
  221. <Segmented
  222. :options="optionsChange"
  223. :size="dynamicSize"
  224. @change="onChange"
  225. />
  226. <el-divider />
  227. <div class="mb-2">禁用</div>
  228. <Segmented :options="optionsDisabled" :size="dynamicSize" />
  229. <el-divider />
  230. <div class="mb-2">全局禁用</div>
  231. <Segmented :options="optionsBasis" :size="dynamicSize" disabled />
  232. <el-divider />
  233. <div class="mb-2">block 属性(将宽度调整为父元素宽度)</div>
  234. <Segmented :options="optionsBlock" block :size="dynamicSize" />
  235. <el-divider />
  236. <div class="mb-2">可设置图标</div>
  237. <Segmented :options="optionsIcon" :size="dynamicSize" />
  238. <el-divider />
  239. <div class="mb-2">只设置图标</div>
  240. <Segmented :options="optionsOnlyIcon" :size="dynamicSize" />
  241. <el-divider />
  242. <div class="mb-2">自定义渲染</div>
  243. <Segmented :options="optionsLabel" :size="dynamicSize" />
  244. </el-scrollbar>
  245. </el-card>
  246. </template>
  247. <style scoped>
  248. :deep(.el-divider--horizontal) {
  249. margin: 17px 0;
  250. }
  251. </style>