青蛙卖大米小程序2024-11-24
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

528 lines
19 KiB

6 months ago
  1. <template>
  2. <view
  3. class="uv-button-wrapper"
  4. :style="[btnWrapperStyle]"
  5. >
  6. <!-- #ifndef APP-NVUE -->
  7. <!-- #ifdef MP -->
  8. <!-- 为了解决微信小程序动态设置hover-class点击态不消失的BUG -->
  9. <view class="uv-button-wrapper--dis" v-if="disabled || loading"></view>
  10. <button
  11. :hover-start-time="Number(hoverStartTime)"
  12. :hover-stay-time="Number(hoverStayTime)"
  13. :form-type="formType"
  14. :open-type="openType"
  15. :app-parameter="appParameter"
  16. :hover-stop-propagation="hoverStopPropagation"
  17. :send-message-title="sendMessageTitle"
  18. :send-message-path="sendMessagePath"
  19. :lang="lang"
  20. :data-name="dataName"
  21. :session-from="sessionFrom"
  22. :send-message-img="sendMessageImg"
  23. :show-message-card="showMessageCard"
  24. @getphonenumber="onGetPhoneNumber"
  25. @getuserinfo="onGetUserInfo"
  26. @error="onError"
  27. @opensetting="onOpenSetting"
  28. @launchapp="onLaunchApp"
  29. @contact="onContact"
  30. @chooseavatar="onChooseavatar"
  31. @agreeprivacyauthorization="onAgreeprivacyauthorization"
  32. @addgroupapp="onAddgroupapp"
  33. @chooseaddress="onChooseaddress"
  34. @subscribe="onSubscribe"
  35. @login="onLogin"
  36. @im="onIm"
  37. hover-class="uv-button--active"
  38. class="uv-button uv-reset-button"
  39. :style="[baseColor, $uv.addStyle(customStyle)]"
  40. @tap="clickHandler"
  41. :class="bemClass"
  42. >
  43. <!-- #endif -->
  44. <!-- #ifndef MP -->
  45. <button
  46. :hover-start-time="Number(hoverStartTime)"
  47. :hover-stay-time="Number(hoverStayTime)"
  48. :form-type="formType"
  49. :open-type="openType"
  50. :app-parameter="appParameter"
  51. :hover-stop-propagation="hoverStopPropagation"
  52. :send-message-title="sendMessageTitle"
  53. :send-message-path="sendMessagePath"
  54. :lang="lang"
  55. :data-name="dataName"
  56. :session-from="sessionFrom"
  57. :send-message-img="sendMessageImg"
  58. :show-message-card="showMessageCard"
  59. :hover-class="!disabled && !loading ? 'uv-button--active' : ''"
  60. class="uv-button uv-reset-button"
  61. :style="[baseColor, $uv.addStyle(customStyle)]"
  62. @tap="clickHandler"
  63. :class="bemClass"
  64. >
  65. <!-- #endif -->
  66. <template v-if="loading">
  67. <uv-loading-icon
  68. :mode="loadingMode"
  69. :size="loadingSize * 1.15"
  70. :color="loadingColor"
  71. ></uv-loading-icon>
  72. <text
  73. class="uv-button__loading-text"
  74. :style="[
  75. { fontSize: textSize + 'px' },
  76. $uv.addStyle(customTextStyle)
  77. ]"
  78. >{{ loadingText || text }}</text>
  79. </template>
  80. <template v-else>
  81. <uv-icon
  82. v-if="icon"
  83. :name="icon"
  84. :color="iconColorCom"
  85. :size="getIconSize"
  86. :customStyle="{ marginRight: '2px' }"
  87. ></uv-icon>
  88. <slot>
  89. <text
  90. class="uv-button__text"
  91. :style="[
  92. { fontSize: textSize + 'px' },
  93. $uv.addStyle(customTextStyle)
  94. ]"
  95. >{{ text }}</text>
  96. </slot>
  97. <slot name="suffix"></slot>
  98. </template>
  99. </button>
  100. <!-- #endif -->
  101. <!-- #ifdef APP-NVUE -->
  102. <view
  103. :hover-start-time="Number(hoverStartTime)"
  104. :hover-stay-time="Number(hoverStayTime)"
  105. class="uv-button"
  106. :hover-class="
  107. !disabled && !loading && !color && (plain || type === 'info')
  108. ? 'uv-button--active--plain'
  109. : !disabled && !loading && !plain
  110. ? 'uv-button--active'
  111. : ''
  112. "
  113. @tap="clickHandler"
  114. :class="bemClass"
  115. :style="[baseColor, $uv.addStyle(customStyle)]"
  116. >
  117. <template v-if="loading">
  118. <uv-loading-icon
  119. :mode="loadingMode"
  120. :size="loadingSize * 1.15"
  121. :color="loadingColor"
  122. ></uv-loading-icon>
  123. <text
  124. class="uv-button__loading-text"
  125. :style="[nvueTextStyle,$uv.addStyle(customTextStyle)]"
  126. :class="[plain && `uv-button__text--plain--${type}`]"
  127. >{{ loadingText || text }}</text>
  128. </template>
  129. <template v-else>
  130. <uv-icon
  131. v-if="icon"
  132. :name="icon"
  133. :color="iconColorCom"
  134. :size="getIconSize"
  135. ></uv-icon>
  136. <text
  137. class="uv-button__text"
  138. :style="[
  139. {
  140. marginLeft: icon ? '2px' : 0,
  141. },
  142. nvueTextStyle,
  143. $uv.addStyle(customTextStyle)
  144. ]"
  145. :class="[plain && `uv-button__text--plain--${type}`]"
  146. >{{ text }}</text>
  147. <slot name="suffix"></slot>
  148. </template>
  149. </view>
  150. <!-- #endif -->
  151. </view>
  152. </template>
  153. <script>
  154. import throttle from '@/uni_modules/uv-ui-tools/libs/function/throttle.js';
  155. import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
  156. import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
  157. import button from '@/uni_modules/uv-ui-tools/libs/mixin/button.js'
  158. import openType from '@/uni_modules/uv-ui-tools/libs/mixin/openType.js'
  159. import props from "./props.js";
  160. /**
  161. * button 按钮
  162. * @description Button 按钮
  163. * @tutorial https://www.uvui.cn/components/button.html
  164. * @property {Boolean} hairline 是否显示按钮的细边框 (默认 true )
  165. * @property {String} type 按钮的预置样式infoprimaryerrorwarningsuccess (默认 'info' )
  166. * @property {String} size 按钮尺寸largenormalmini 默认 normal
  167. * @property {String} shape 按钮形状circle两边为半圆square带圆角 默认 'square'
  168. * @property {Boolean} plain 按钮是否镂空背景色透明 默认 false
  169. * @property {Boolean} disabled 是否禁用 默认 false
  170. * @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台 ios 上为雪花Android上为圆圈) 默认 false
  171. * @property {String | Number} loadingText 加载中提示文字
  172. * @property {String} loadingMode 加载状态图标类型 默认 'spinner'
  173. * @property {String | Number} loadingSize 加载图标大小 默认 15
  174. * @property {String} openType 开放能力具体请看uniapp稳定关于button组件部分说明
  175. * @property {String} formType 用于 <form> 组件点击分别会触发 <form> 组件的 submit/reset 事件
  176. * @property {String} appParameter 打开 APP APP 传递的参数open-type=launchApp时有效 只微信小程序QQ小程序有效
  177. * @property {Boolean} hoverStopPropagation 指定是否阻止本节点的祖先节点出现点击态微信小程序有效默认 true
  178. * @property {String} lang 指定返回用户信息的语言zh_CN 简体中文zh_TW 繁体中文en 英文默认 en
  179. * @property {String} sessionFrom 会话来源openType="contact"时有效
  180. * @property {String} sendMessageTitle 会话内消息卡片标题openType="contact"时有效
  181. * @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径openType="contact"时有效
  182. * @property {String} sendMessageImg 会话内消息卡片图片openType="contact"时有效
  183. * @property {Boolean} showMessageCard 是否显示会话内消息卡片设置此参数为 true用户进入客服会话会在右下角显示"可能要发送的小程序"提示用户点击后可以快速发送小程序消息openType="contact"时有效默认false
  184. * @property {String} dataName 额外传参参数用于小程序的data-xxx属性通过target.dataset.name获取
  185. * @property {String | Number} throttleTime 节流一定时间内只能触发一次 默认 0 )
  186. * @property {String | Number} hoverStartTime 按住后多久出现点击态单位毫秒 默认 0 )
  187. * @property {String | Number} hoverStayTime 手指松开后点击态保留时间单位毫秒 默认 200 )
  188. * @property {String | Number} text 按钮文字之所以通过props传入是因为slot传入的话nvue中无法控制文字的样式
  189. * @property {String} icon 按钮图标
  190. * @property {String} iconColor 按钮图标颜色
  191. * @property {String} color 按钮颜色支持传入linear-gradient渐变色
  192. * @property {Object} customStyle 定义需要用到的外部样式
  193. * @event {Function} click 非禁止并且非加载中才能点击
  194. * @event {Function} getphonenumber open-type="getPhoneNumber"时有效
  195. * @event {Function} getuserinfo 用户点击该按钮时会返回获取到的用户信息从返回参数的detail中获取到的值同uni.getUserInfo
  196. * @event {Function} error 当使用开放能力时发生错误的回调
  197. * @event {Function} opensetting 在打开授权设置页并关闭后回调
  198. * @event {Function} launchapp 打开 APP 成功的回调
  199. * @example <uv-button>月落</uv-button>
  200. */
  201. export default {
  202. name: "uv-button",
  203. // #ifdef MP
  204. mixins: [mpMixin, mixin, button, openType, props],
  205. // #endif
  206. // #ifndef MP
  207. mixins: [mpMixin, mixin, props],
  208. // #endif
  209. emits: ['click'],
  210. data() {
  211. return {};
  212. },
  213. computed: {
  214. // 生成bem风格的类名
  215. bemClass() {
  216. // this.bem为一个computed变量,在mixin中
  217. if (!this.color) {
  218. return this.bem("button",
  219. ["type", "shape", "size"],
  220. ["disabled", "plain", "hairline"]);
  221. } else {
  222. // 由于nvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
  223. return this.bem("button",
  224. ["shape", "size"],
  225. ["disabled", "plain", "hairline"]);
  226. }
  227. },
  228. loadingColor() {
  229. if (this.plain) {
  230. // 如果有设置color值,则用color值,否则使用type主题颜色
  231. return this.color ? this.color : '#3c9cff';
  232. }
  233. if (this.type === "info") {
  234. return "#c9c9c9";
  235. }
  236. return "rgb(200, 200, 200)";
  237. },
  238. iconColorCom() {
  239. // 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
  240. // uv-icon的color能接受一个主题颜色的值
  241. if (this.iconColor) return this.iconColor;
  242. if (this.plain) {
  243. return this.color ? this.color : this.type;
  244. } else {
  245. return this.type === "info" ? "#000000" : "#ffffff";
  246. }
  247. },
  248. baseColor() {
  249. let style = {};
  250. if (this.color) {
  251. // 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
  252. style.color = this.plain ? this.color : "white";
  253. if (!this.plain) {
  254. // 非镂空,背景色使用自定义的颜色
  255. style["background-color"] = this.color;
  256. }
  257. if (this.color.indexOf("gradient") !== -1) {
  258. // 如果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
  259. // weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
  260. // 因为weex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
  261. style.borderTopWidth = 0;
  262. style.borderRightWidth = 0;
  263. style.borderBottomWidth = 0;
  264. style.borderLeftWidth = 0;
  265. if (!this.plain) {
  266. style.backgroundImage = this.color;
  267. }
  268. } else {
  269. // 非渐变色,则设置边框相关的属性
  270. style.borderColor = this.color;
  271. style.borderWidth = "1px";
  272. style.borderStyle = "solid";
  273. }
  274. }
  275. return style;
  276. },
  277. // nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
  278. nvueTextStyle() {
  279. let style = {};
  280. // 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
  281. if (this.type === "info") {
  282. style.color = "#323233";
  283. }
  284. if (this.color) {
  285. style.color = this.plain ? this.color : "white";
  286. }
  287. style.fontSize = this.textSize + "px";
  288. return style;
  289. },
  290. // 字体大小
  291. textSize() {
  292. let fontSize = 14,
  293. { size } = this;
  294. if (size === "large") fontSize = 16;
  295. if (size === "normal") fontSize = 14;
  296. if (size === "small") fontSize = 12;
  297. if (size === "mini") fontSize = 10;
  298. return fontSize;
  299. },
  300. // 设置图标大小
  301. getIconSize() {
  302. const size = this.iconSize ? this.iconSize : this.textSize * 1.35;
  303. return this.$uv.addUnit(size);
  304. },
  305. // 设置外层盒子的宽度,其他样式不需要
  306. btnWrapperStyle() {
  307. const style = {};
  308. const customStyle = this.$uv.addStyle(this.customStyle);
  309. if(customStyle.width) style.width = customStyle.width;
  310. return style;
  311. }
  312. },
  313. methods: {
  314. clickHandler() {
  315. // 非禁止并且非加载中,才能点击
  316. if (!this.disabled && !this.loading) {
  317. // 进行节流控制,每this.throttle毫秒内,只在开始处执行
  318. throttle(() => {
  319. this.$emit("click");
  320. }, this.throttleTime);
  321. }
  322. }
  323. }
  324. }
  325. </script>
  326. <style lang="scss" scoped>
  327. $show-reset-button: 1;
  328. @import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
  329. @import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
  330. @import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
  331. /* #ifndef APP-NVUE */
  332. @import "./vue.scss";
  333. /* #endif */
  334. /* #ifdef APP-NVUE */
  335. @import "./nvue.scss";
  336. /* #endif */
  337. $uv-button-uv-button-height: 40px !default;
  338. $uv-button-text-font-size: 15px !default;
  339. $uv-button-loading-text-font-size: 15px !default;
  340. $uv-button-loading-text-margin-left: 4px !default;
  341. $uv-button-large-width: 100% !default;
  342. $uv-button-large-height: 50px !default;
  343. $uv-button-normal-padding: 0 12px !default;
  344. $uv-button-large-padding: 0 15px !default;
  345. $uv-button-normal-font-size: 14px !default;
  346. $uv-button-small-min-width: 60px !default;
  347. $uv-button-small-height: 30px !default;
  348. $uv-button-small-padding: 0px 8px !default;
  349. $uv-button-mini-padding: 0px 8px !default;
  350. $uv-button-small-font-size: 12px !default;
  351. $uv-button-mini-height: 22px !default;
  352. $uv-button-mini-font-size: 10px !default;
  353. $uv-button-mini-min-width: 50px !default;
  354. $uv-button-disabled-opacity: 0.5 !default;
  355. $uv-button-info-color: #323233 !default;
  356. $uv-button-info-background-color: #fff !default;
  357. $uv-button-info-border-color: #ebedf0 !default;
  358. $uv-button-info-border-width: 1px !default;
  359. $uv-button-info-border-style: solid !default;
  360. $uv-button-success-color: #fff !default;
  361. $uv-button-success-background-color: $uv-success !default;
  362. $uv-button-success-border-color: $uv-button-success-background-color !default;
  363. $uv-button-success-border-width: 1px !default;
  364. $uv-button-success-border-style: solid !default;
  365. $uv-button-primary-color: #fff !default;
  366. $uv-button-primary-background-color: $uv-primary !default;
  367. $uv-button-primary-border-color: $uv-button-primary-background-color !default;
  368. $uv-button-primary-border-width: 1px !default;
  369. $uv-button-primary-border-style: solid !default;
  370. $uv-button-error-color: #fff !default;
  371. $uv-button-error-background-color: $uv-error !default;
  372. $uv-button-error-border-color: $uv-button-error-background-color !default;
  373. $uv-button-error-border-width: 1px !default;
  374. $uv-button-error-border-style: solid !default;
  375. $uv-button-warning-color: #fff !default;
  376. $uv-button-warning-background-color: $uv-warning !default;
  377. $uv-button-warning-border-color: $uv-button-warning-background-color !default;
  378. $uv-button-warning-border-width: 1px !default;
  379. $uv-button-warning-border-style: solid !default;
  380. $uv-button-block-width: 100% !default;
  381. $uv-button-circle-border-top-right-radius: 100px !default;
  382. $uv-button-circle-border-top-left-radius: 100px !default;
  383. $uv-button-circle-border-bottom-left-radius: 100px !default;
  384. $uv-button-circle-border-bottom-right-radius: 100px !default;
  385. $uv-button-square-border-top-right-radius: 3px !default;
  386. $uv-button-square-border-top-left-radius: 3px !default;
  387. $uv-button-square-border-bottom-left-radius: 3px !default;
  388. $uv-button-square-border-bottom-right-radius: 3px !default;
  389. $uv-button-icon-min-width: 1em !default;
  390. $uv-button-plain-background-color: #fff !default;
  391. $uv-button-hairline-border-width: 0.5px !default;
  392. .uv-button {
  393. height: $uv-button-uv-button-height;
  394. position: relative;
  395. align-items: center;
  396. justify-content: center;
  397. @include flex;
  398. /* #ifndef APP-NVUE */
  399. box-sizing: border-box;
  400. /* #endif */
  401. flex-direction: row;
  402. &__text {
  403. font-size: $uv-button-text-font-size;
  404. }
  405. &__loading-text {
  406. font-size: $uv-button-loading-text-font-size;
  407. margin-left: $uv-button-loading-text-margin-left;
  408. }
  409. &--large {
  410. /* #ifndef APP-NVUE */
  411. width: $uv-button-large-width;
  412. /* #endif */
  413. height: $uv-button-large-height;
  414. padding: $uv-button-large-padding;
  415. }
  416. &--normal {
  417. padding: $uv-button-normal-padding;
  418. font-size: $uv-button-normal-font-size;
  419. }
  420. &--small {
  421. /* #ifndef APP-NVUE */
  422. min-width: $uv-button-small-min-width;
  423. /* #endif */
  424. height: $uv-button-small-height;
  425. padding: $uv-button-small-padding;
  426. font-size: $uv-button-small-font-size;
  427. }
  428. &--mini {
  429. height: $uv-button-mini-height;
  430. font-size: $uv-button-mini-font-size;
  431. /* #ifndef APP-NVUE */
  432. min-width: $uv-button-mini-min-width;
  433. /* #endif */
  434. padding: $uv-button-mini-padding;
  435. }
  436. &--disabled {
  437. opacity: $uv-button-disabled-opacity;
  438. }
  439. &--info {
  440. color: $uv-button-info-color;
  441. background-color: $uv-button-info-background-color;
  442. border-color: $uv-button-info-border-color;
  443. border-width: $uv-button-info-border-width;
  444. border-style: $uv-button-info-border-style;
  445. }
  446. &--success {
  447. color: $uv-button-success-color;
  448. background-color: $uv-button-success-background-color;
  449. border-color: $uv-button-success-border-color;
  450. border-width: $uv-button-success-border-width;
  451. border-style: $uv-button-success-border-style;
  452. }
  453. &--primary {
  454. color: $uv-button-primary-color;
  455. background-color: $uv-button-primary-background-color;
  456. border-color: $uv-button-primary-border-color;
  457. border-width: $uv-button-primary-border-width;
  458. border-style: $uv-button-primary-border-style;
  459. }
  460. &--error {
  461. color: $uv-button-error-color;
  462. background-color: $uv-button-error-background-color;
  463. border-color: $uv-button-error-border-color;
  464. border-width: $uv-button-error-border-width;
  465. border-style: $uv-button-error-border-style;
  466. }
  467. &--warning {
  468. color: $uv-button-warning-color;
  469. background-color: $uv-button-warning-background-color;
  470. border-color: $uv-button-warning-border-color;
  471. border-width: $uv-button-warning-border-width;
  472. border-style: $uv-button-warning-border-style;
  473. }
  474. &--block {
  475. @include flex;
  476. width: $uv-button-block-width;
  477. }
  478. &--circle {
  479. border-top-right-radius: $uv-button-circle-border-top-right-radius;
  480. border-top-left-radius: $uv-button-circle-border-top-left-radius;
  481. border-bottom-left-radius: $uv-button-circle-border-bottom-left-radius;
  482. border-bottom-right-radius: $uv-button-circle-border-bottom-right-radius;
  483. }
  484. &--square {
  485. border-bottom-left-radius: $uv-button-square-border-top-right-radius;
  486. border-bottom-right-radius: $uv-button-square-border-top-left-radius;
  487. border-top-left-radius: $uv-button-square-border-bottom-left-radius;
  488. border-top-right-radius: $uv-button-square-border-bottom-right-radius;
  489. }
  490. &__icon {
  491. /* #ifndef APP-NVUE */
  492. min-width: $uv-button-icon-min-width;
  493. line-height: inherit !important;
  494. vertical-align: top;
  495. /* #endif */
  496. }
  497. &--plain {
  498. background-color: $uv-button-plain-background-color;
  499. }
  500. &--hairline {
  501. border-width: $uv-button-hairline-border-width !important;
  502. }
  503. }
  504. </style>