BorderRadius.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <div>
  3. <RadioGroup v-model:value="radius.type">
  4. <RadioButton value="all">整体</RadioButton>
  5. <RadioButton value="custom">单个</RadioButton>
  6. </RadioGroup>
  7. <div class="all" v-if="radius.type === 'all'">
  8. <InputNumber v-model:value="radius.value as number" />
  9. <Select v-model:value="radius.unit" :options="unitOptions" />
  10. </div>
  11. <div class="custom" v-else>
  12. <InputNumber v-model:value="radius.topLeft" >
  13. <template #addonBefore><RadiusUpleftOutlined/></template>
  14. </InputNumber>
  15. <InputNumber v-model:value="radius.topRight" >
  16. <template #addonBefore><RadiusUprightOutlined/></template>
  17. </InputNumber>
  18. <InputNumber v-model:value="radius.bottomLeft" >
  19. <template #addonBefore><RadiusBottomleftOutlined/></template>
  20. </InputNumber>
  21. <InputNumber v-model:value="radius.bottomRight" >
  22. <template #addonBefore><RadiusBottomrightOutlined/></template>
  23. </InputNumber>
  24. <Select v-model:value="radius.unit" :options="unitOptions" />
  25. </div>
  26. </div>
  27. </template>
  28. <script lang="ts">
  29. import { defineComponent, PropType, reactive, watch } from "vue";
  30. import { RadioGroup, RadioButton, InputNumber, Select } from "ant-design-vue";
  31. import {
  32. RadiusUpleftOutlined,
  33. RadiusUprightOutlined,
  34. RadiusBottomleftOutlined,
  35. RadiusBottomrightOutlined,
  36. } from "@ant-design/icons-vue";
  37. type BorderRadius = {
  38. type: "all" | "custom";
  39. value:
  40. | number
  41. | {
  42. topLeft: number;
  43. topRight: number;
  44. bottomLeft: number;
  45. bottomRight: number;
  46. };
  47. unit: "px" | "%";
  48. };
  49. export default defineComponent({
  50. name: "FmBorderRadius",
  51. components: {
  52. RadioGroup,
  53. RadioButton,
  54. InputNumber,
  55. Select,
  56. RadiusUpleftOutlined,
  57. RadiusUprightOutlined,
  58. RadiusBottomleftOutlined,
  59. RadiusBottomrightOutlined,
  60. },
  61. props: {
  62. value: {
  63. type: Object as PropType<BorderRadius>,
  64. default: () => ({}),
  65. },
  66. },
  67. emits: ["update:value"],
  68. setup(props, { emit }) {
  69. const radius = reactive({
  70. type: props.value.type || "all",
  71. value: props.value.type === "all" ? props.value.value : 0,
  72. unit: props.value.unit || "px",
  73. topLeft:
  74. typeof props.value.value === "object" ? props.value.value?.topLeft : 0,
  75. topRight:
  76. typeof props.value.value === "object" ? props.value.value?.topRight : 0,
  77. bottomLeft:
  78. typeof props.value.value === "object"
  79. ? props.value.value?.bottomLeft
  80. : 0,
  81. bottomRight:
  82. typeof props.value.value === "object"
  83. ? props.value.value?.bottomRight
  84. : 0,
  85. });
  86. watch(
  87. () => radius,
  88. (value) => {
  89. emit("update:value", {
  90. type: value.type,
  91. value:
  92. value.type === "all"
  93. ? value.value
  94. : {
  95. topLeft: value.topLeft,
  96. topRight: value.topRight,
  97. bottomLeft: value.bottomLeft,
  98. bottomRight: value.bottomRight,
  99. },
  100. unit: value.unit,
  101. });
  102. },
  103. {
  104. deep: true
  105. }
  106. )
  107. return {
  108. radius,
  109. unitOptions: [
  110. { label: "px", value: "px" },
  111. { label: "%", value: "%" },
  112. ],
  113. };
  114. },
  115. });
  116. </script>
  117. <style lang="less" scoped>
  118. .all, .custom {
  119. margin-top: 10px;
  120. }
  121. .all {
  122. display: flex;
  123. gap: 10px;
  124. .ant-input-number {
  125. width: 256px;
  126. }
  127. }
  128. .custom {
  129. display: flex;
  130. flex-direction: column;
  131. gap: 10px;
  132. }
  133. </style>