fs-button.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <template>
  2. <button
  3. hover-class="fs-hover"
  4. class="fs-button"
  5. :class="[
  6. type,
  7. size,
  8. plain ? 'plain' : '',
  9. radius ? 'radius' : '',
  10. round ? 'round' : '',
  11. disabled ? 'disabled' : '',
  12. block ? 'block' : '',
  13. full ? 'block full' : ''
  14. ]"
  15. :style="[{ width: width }, customStyle]"
  16. :open-type="openType"
  17. :form-type="formType"
  18. @getuserinfo="getuserinfo"
  19. @contact="contact"
  20. @getphonenumber="getphonenumber"
  21. @opensetting="opensetting"
  22. @error="error"
  23. @click="handleClick"
  24. >
  25. <view class="fs-loader" v-if="loading"></view>
  26. <template v-else>
  27. <slot></slot>
  28. </template>
  29. </button>
  30. </template>
  31. <script>
  32. /**
  33. * 按钮组件
  34. * @description 按钮组件
  35. * @property {String} openType 参考小程序
  36. * @property {String} formType 参考小程序
  37. * @property {String} size = [mini | small | medium] 按钮大小
  38. * @property {Boolean} plain 是否镂空
  39. * @property {Boolean} radius 是否圆角
  40. * @property {Boolean} round 是否半圆
  41. * @property {Boolean} loading 加载效果
  42. * @property {Boolean} disabled disabled
  43. * @property {Boolean} full 通屏按钮
  44. * @property {Boolean} block 块状按钮
  45. * @property {String} link 跳转地址
  46. * @property {String} linkType 跳转类型
  47. * @property {String} width 按钮宽度
  48. * @property {Object} customStyle 按钮自定义样式
  49. * @property {String} type = [primary | danger | warning | info | success | default] 按钮颜色类型
  50. */
  51. export default {
  52. name: 'fs-button'
  53. }
  54. </script>
  55. <script setup>
  56. import { computed, useAttrs } from 'vue'
  57. const props = defineProps({
  58. openType: String,
  59. formType: String,
  60. size: {
  61. type: String,
  62. validator(value) {
  63. return ['mini', 'small', 'medium'].includes(value)
  64. }
  65. },
  66. type: {
  67. type: String,
  68. default: 'primary',
  69. validator(value) {
  70. return ['primary', 'success', 'info', 'warning', 'danger', 'default'].includes(value)
  71. }
  72. },
  73. plain: Boolean,
  74. radius: Boolean,
  75. round: Boolean,
  76. disabled: Boolean,
  77. full: Boolean,
  78. block: Boolean,
  79. link: String,
  80. linkType: {
  81. type: String,
  82. default: 'navigateTo'
  83. },
  84. width: String,
  85. customStyle: {
  86. type: Object,
  87. default() {
  88. return {}
  89. }
  90. },
  91. loading: Boolean
  92. })
  93. const emits = defineEmits(['click', 'getuserinfo', 'contact', 'getphonenumber', 'opensetting', 'error'])
  94. const handleClick = e => {
  95. if (props.link && !props.disabled) {
  96. uni[props.linkType]({
  97. url: props.link
  98. })
  99. }
  100. !props.disabled && emits('click')
  101. }
  102. const getuserinfo = event => {
  103. emits('getuserinfo', event.detail)
  104. }
  105. const contact = event => {
  106. emits('contact', event.detail)
  107. }
  108. const getphonenumber = event => {
  109. emits('getphonenumber', event.detail)
  110. }
  111. const opensetting = event => {
  112. emits('opensetting', event.detail)
  113. }
  114. const error = event => {
  115. emits('error', event.detail)
  116. }
  117. </script>
  118. <style lang="scss" scoped>
  119. .fs-button {
  120. font-weight: normal;
  121. font-size: 14px;
  122. color: #fff;
  123. padding: 0 40rpx;
  124. line-height: 1;
  125. text-align: center;
  126. border-radius: 0;
  127. display: inline-block;
  128. vertical-align: bottom;
  129. background-color: #cfcfcf;
  130. margin: 0;
  131. border: 0;
  132. height: 70rpx;
  133. line-height: 70rpx;
  134. &.primary,
  135. &.primary.selected,
  136. &.selected {
  137. background-color: var(--primary);
  138. }
  139. &.success {
  140. background-color: var(--success);
  141. }
  142. &.info {
  143. background-color: var(--info);
  144. }
  145. &.warning {
  146. background-color: var(--warning);
  147. }
  148. &.danger {
  149. background-color: var(--danger);
  150. }
  151. &.plain,
  152. &.plain.selected {
  153. background-color: transparent;
  154. box-shadow: inset 0 0 0 1px currentColor;
  155. color: #999999;
  156. }
  157. &.medium {
  158. // width: auto !important;
  159. height: 60rpx;
  160. line-height: 60rpx;
  161. font-size: 13px;
  162. padding: 0 30rpx;
  163. }
  164. &.small {
  165. width: auto !important;
  166. height: 50rpx;
  167. line-height: 50rpx;
  168. font-size: 12px;
  169. padding: 0 20rpx;
  170. }
  171. &.mini {
  172. width: auto !important;
  173. height: 40rpx;
  174. line-height: 40rpx;
  175. font-size: 12px;
  176. padding: 0 20rpx;
  177. }
  178. &.block {
  179. display: block;
  180. height: 100rpx;
  181. line-height: 100rpx;
  182. margin-left: var(--gutter) !important;
  183. margin-right: var(--gutter) !important;
  184. font-size: 18px;
  185. width: auto;
  186. &.radius {
  187. border-radius: 16rpx;
  188. }
  189. }
  190. &.full {
  191. margin-left: 0 !important;
  192. margin-right: 0 !important;
  193. }
  194. &::after {
  195. border: none;
  196. }
  197. &.radius {
  198. border-radius: 8rpx;
  199. }
  200. &.round {
  201. border-radius: 30px;
  202. }
  203. &.plain.primary,
  204. &.plain.selected {
  205. color: var(--primary);
  206. }
  207. &.plain.success {
  208. color: var(--success);
  209. }
  210. &.plain.warning {
  211. color: var(--warning);
  212. }
  213. &.plain.danger {
  214. color: var(--danger);
  215. }
  216. &.plain.info {
  217. color: var(--info);
  218. }
  219. &.disabled {
  220. opacity: 0.5;
  221. }
  222. }
  223. .fs-hover {
  224. opacity: 0.5;
  225. }
  226. .fs-loader {
  227. display: inline-block;
  228. width: 40rpx;
  229. height: 40rpx;
  230. color: inherit;
  231. vertical-align: middle;
  232. border: 4rpx solid currentcolor;
  233. border-bottom-color: transparent;
  234. border-radius: 50%;
  235. animation: 1s loader linear infinite;
  236. position: relative;
  237. }
  238. @keyframes loader {
  239. 0% {
  240. transform: rotate(0deg);
  241. }
  242. 100% {
  243. transform: rotate(360deg);
  244. }
  245. }
  246. </style>