From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期三, 28 五月 2025 16:48:52 +0800 Subject: [PATCH] 初始化项目 --- uview-ui/components/u-button/u-button.vue | 596 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 596 insertions(+), 0 deletions(-) diff --git a/uview-ui/components/u-button/u-button.vue b/uview-ui/components/u-button/u-button.vue new file mode 100644 index 0000000..82c3a6f --- /dev/null +++ b/uview-ui/components/u-button/u-button.vue @@ -0,0 +1,596 @@ +<template> + <button + id="u-wave-btn" + class="u-btn u-line-1 u-fix-ios-appearance" + :class="[ + 'u-size-' + size, + plain ? 'u-btn--' + type + '--plain' : '', + loading ? 'u-loading' : '', + shape == 'circle' ? 'u-round-circle' : '', + hairLine ? showHairLineBorder : 'u-btn--bold-border', + 'u-btn--' + type, + disabled ? `u-btn--${type}--disabled` : '', + ]" + :hover-start-time="Number(hoverStartTime)" + :hover-stay-time="Number(hoverStayTime)" + :disabled="disabled" + :form-type="formType" + :open-type="openType" + :app-parameter="appParameter" + :hover-stop-propagation="hoverStopPropagation" + :send-message-title="sendMessageTitle" + send-message-path="sendMessagePath" + :lang="lang" + :data-name="dataName" + :session-from="sessionFrom" + :send-message-img="sendMessageImg" + :show-message-card="showMessageCard" + @getphonenumber="getphonenumber" + @getuserinfo="getuserinfo" + @error="error" + @opensetting="opensetting" + @launchapp="launchapp" + :style="[customStyle, { + overflow: ripple ? 'hidden' : 'visible' + }]" + @tap.stop="click($event)" + :hover-class="getHoverClass" + :loading="loading" + > + <slot></slot> + <view + v-if="ripple" + class="u-wave-ripple" + :class="[waveActive ? 'u-wave-active' : '']" + :style="{ + top: rippleTop + 'px', + left: rippleLeft + 'px', + width: fields.targetWidth + 'px', + height: fields.targetWidth + 'px', + 'background-color': rippleBgColor || 'rgba(0, 0, 0, 0.15)' + }" + ></view> + </button> +</template> + +<script> +/** + * button 鎸夐挳 + * @description Button 鎸夐挳 + * @tutorial https://www.uviewui.com/components/button.html + * @property {String} size 鎸夐挳鐨勫ぇ灏� + * @property {Boolean} ripple 鏄惁寮�鍚偣鍑绘按娉㈢汗鏁堟灉 + * @property {String} ripple-bg-color 姘存尝绾圭殑鑳屾櫙鑹诧紝ripple涓簍rue鏃舵湁鏁� + * @property {String} type 鎸夐挳鐨勬牱寮忕被鍨� + * @property {Boolean} plain 鎸夐挳鏄惁闀傜┖锛岃儗鏅壊閫忔槑 + * @property {Boolean} disabled 鏄惁绂佺敤 + * @property {Boolean} hair-line 鏄惁鏄剧ず鎸夐挳鐨勭粏杈规(榛樿true) + * @property {Boolean} shape 鎸夐挳澶栬褰㈢姸锛岃鏂囨。璇存槑 + * @property {Boolean} loading 鎸夐挳鍚嶇О鍓嶆槸鍚﹀甫 loading 鍥炬爣(App-nvue 骞冲彴锛屽湪 ios 涓婁负闆姳锛孉ndroid涓婁负鍦嗗湀) + * @property {String} form-type 鐢ㄤ簬 <form> 缁勪欢锛岀偣鍑诲垎鍒細瑙﹀彂 <form> 缁勪欢鐨� submit/reset 浜嬩欢 + * @property {String} open-type 寮�鏀捐兘鍔� + * @property {String} data-name 棰濆浼犲弬鍙傛暟锛岀敤浜庡皬绋嬪簭鐨刣ata-xxx灞炴�э紝閫氳繃target.dataset.name鑾峰彇 + * @property {String} hover-class 鎸囧畾鎸夐挳鎸変笅鍘荤殑鏍峰紡绫汇�傚綋 hover-class="none" 鏃讹紝娌℃湁鐐瑰嚮鎬佹晥鏋�(App-nvue 骞冲彴鏆備笉鏀寔) + * @property {Number} hover-start-time 鎸変綇鍚庡涔呭嚭鐜扮偣鍑绘�侊紝鍗曚綅姣 + * @property {Number} hover-stay-time 鎵嬫寚鏉惧紑鍚庣偣鍑绘�佷繚鐣欐椂闂达紝鍗曚綅姣 + * @property {Object} custom-style 瀵规寜閽殑鑷畾涔夋牱寮忥紝瀵硅薄褰㈠紡锛岃鏂囨。璇存槑 + * @event {Function} click 鎸夐挳鐐瑰嚮 + * @event {Function} getphonenumber open-type="getPhoneNumber"鏃舵湁鏁� + * @event {Function} getuserinfo 鐢ㄦ埛鐐瑰嚮璇ユ寜閽椂锛屼細杩斿洖鑾峰彇鍒扮殑鐢ㄦ埛淇℃伅锛屼粠杩斿洖鍙傛暟鐨刣etail涓幏鍙栧埌鐨勫�煎悓uni.getUserInfo + * @event {Function} error 褰撲娇鐢ㄥ紑鏀捐兘鍔涙椂锛屽彂鐢熼敊璇殑鍥炶皟 + * @event {Function} opensetting 鍦ㄦ墦寮�鎺堟潈璁剧疆椤靛苟鍏抽棴鍚庡洖璋� + * @event {Function} launchapp 鎵撳紑 APP 鎴愬姛鐨勫洖璋� + * @example <u-button>鏈堣惤</u-button> + */ +export default { + name: 'u-button', + props: { + // 鏄惁缁嗚竟妗� + hairLine: { + type: Boolean, + default: true + }, + // 鎸夐挳鐨勯缃牱寮忥紝default锛宲rimary锛宔rror锛寃arning锛宻uccess + type: { + type: String, + default: 'default' + }, + // 鎸夐挳灏哄锛宒efault锛宮edium锛宮ini + size: { + type: String, + default: 'default' + }, + // 鎸夐挳褰㈢姸锛宑ircle锛堜袱杈逛负鍗婂渾锛夛紝square锛堝甫鍦嗚锛� + shape: { + type: String, + default: 'square' + }, + // 鎸夐挳鏄惁闀傜┖ + plain: { + type: Boolean, + default: false + }, + // 鏄惁绂佹鐘舵�� + disabled: { + type: Boolean, + default: false + }, + // 鏄惁鍔犺浇涓� + loading: { + type: Boolean, + default: false + }, + // 寮�鏀捐兘鍔涳紝鍏蜂綋璇风湅uniapp绋冲畾鍏充簬button缁勪欢閮ㄥ垎璇存槑 + // https://uniapp.dcloud.io/component/button + openType: { + type: String, + default: '' + }, + // 鐢ㄤ簬 <form> 缁勪欢锛岀偣鍑诲垎鍒細瑙﹀彂 <form> 缁勪欢鐨� submit/reset 浜嬩欢 + // 鍙栧�间负submit锛堟彁浜よ〃鍗曪級锛宺eset锛堥噸缃〃鍗曪級 + formType: { + type: String, + default: '' + }, + // 鎵撳紑 APP 鏃讹紝鍚� APP 浼犻�掔殑鍙傛暟锛宱pen-type=launchApp鏃舵湁鏁� + // 鍙井淇″皬绋嬪簭銆丵Q灏忕▼搴忔湁鏁� + appParameter: { + type: String, + default: '' + }, + // 鎸囧畾鏄惁闃绘鏈妭鐐圭殑绁栧厛鑺傜偣鍑虹幇鐐瑰嚮鎬侊紝寰俊灏忕▼搴忔湁鏁� + hoverStopPropagation: { + type: Boolean, + default: false + }, + // 鎸囧畾杩斿洖鐢ㄦ埛淇℃伅鐨勮瑷�锛寊h_CN 绠�浣撲腑鏂囷紝zh_TW 绻佷綋涓枃锛宔n 鑻辨枃銆傚彧寰俊灏忕▼搴忔湁鏁� + lang: { + type: String, + default: 'en' + }, + // 浼氳瘽鏉ユ簮锛宱pen-type="contact"鏃舵湁鏁堛�傚彧寰俊灏忕▼搴忔湁鏁� + sessionFrom: { + type: String, + default: '' + }, + // 浼氳瘽鍐呮秷鎭崱鐗囨爣棰橈紝open-type="contact"鏃舵湁鏁� + // 榛樿褰撳墠鏍囬锛屽彧寰俊灏忕▼搴忔湁鏁� + sendMessageTitle: { + type: String, + default: '' + }, + // 浼氳瘽鍐呮秷鎭崱鐗囩偣鍑昏烦杞皬绋嬪簭璺緞锛宱pen-type="contact"鏃舵湁鏁� + // 榛樿褰撳墠鍒嗕韩璺緞锛屽彧寰俊灏忕▼搴忔湁鏁� + sendMessagePath: { + type: String, + default: '' + }, + // 浼氳瘽鍐呮秷鎭崱鐗囧浘鐗囷紝open-type="contact"鏃舵湁鏁� + // 榛樿褰撳墠椤甸潰鎴浘锛屽彧寰俊灏忕▼搴忔湁鏁� + sendMessageImg: { + type: String, + default: '' + }, + // 鏄惁鏄剧ず浼氳瘽鍐呮秷鎭崱鐗囷紝璁剧疆姝ゅ弬鏁颁负 true锛岀敤鎴疯繘鍏ュ鏈嶄細璇濅細鍦ㄥ彸涓嬭鏄剧ず"鍙兘瑕佸彂閫佺殑灏忕▼搴�"鎻愮ず锛� + // 鐢ㄦ埛鐐瑰嚮鍚庡彲浠ュ揩閫熷彂閫佸皬绋嬪簭娑堟伅锛宱pen-type="contact"鏃舵湁鏁� + showMessageCard: { + type: Boolean, + default: false + }, + // 鎵嬫寚鎸夛紙瑙︽懜锛夋寜閽椂鎸夐挳鏃剁殑鑳屾櫙棰滆壊 + hoverBgColor: { + type: String, + default: '' + }, + // 姘存尝绾圭殑鑳屾櫙棰滆壊 + rippleBgColor: { + type: String, + default: '' + }, + // 鏄惁寮�鍚按娉㈢汗鏁堟灉 + ripple: { + type: Boolean, + default: false + }, + // 鎸変笅鐨勭被鍚� + hoverClass: { + type: String, + default: '' + }, + // 鑷畾涔夋牱寮忥紝瀵硅薄褰㈠紡 + customStyle: { + type: Object, + default() { + return {}; + } + }, + // 棰濆浼犲弬鍙傛暟锛岀敤浜庡皬绋嬪簭鐨刣ata-xxx灞炴�э紝閫氳繃target.dataset.name鑾峰彇 + dataName: { + type: String, + default: '' + }, + // 鑺傛祦锛屼竴瀹氭椂闂村唴鍙兘瑙﹀彂涓�娆� + throttleTime: { + type: [String, Number], + default: 1000 + }, + // 鎸変綇鍚庡涔呭嚭鐜扮偣鍑绘�侊紝鍗曚綅姣 + hoverStartTime: { + type: [String, Number], + default: 20 + }, + // 鎵嬫寚鏉惧紑鍚庣偣鍑绘�佷繚鐣欐椂闂达紝鍗曚綅姣 + hoverStayTime: { + type: [String, Number], + default: 150 + }, + }, + computed: { + // 褰撴病鏈変紶bgColor鍙橀噺鏃讹紝鎸夐挳鎸変笅鍘荤殑棰滆壊绫诲悕 + getHoverClass() { + // 濡傛灉寮�鍚按娉㈢汗鏁堟灉锛屽垯涓嶅惎鐢╤over-class鏁堟灉 + if (this.loading || this.disabled || this.ripple || this.hoverClass) return ''; + let hoverClass = ''; + hoverClass = this.plain ? 'u-' + this.type + '-plain-hover' : 'u-' + this.type + '-hover'; + return hoverClass; + }, + // 鍦�'primary', 'success', 'error', 'warning'绫诲瀷涓嬶紝涓嶆樉绀鸿竟妗嗭紝鍚﹀垯浼氶�犳垚鍥涜鏈夋瘺鍒虹幇璞� + showHairLineBorder() { + if (['primary', 'success', 'error', 'warning'].indexOf(this.type) >= 0 && !this.plain) { + return ''; + } else { + return 'u-hairline-border'; + } + } + }, + data() { + return { + rippleTop: 0, // 姘存尝绾圭殑璧风偣Y鍧愭爣鍒版寜閽笂杈圭晫鐨勮窛绂� + rippleLeft: 0, // 姘存尝绾硅捣鐐筙鍧愭爣鍒版寜閽乏杈圭晫鐨勮窛绂� + fields: {}, // 娉㈢汗鎸夐挳鑺傜偣淇℃伅 + waveActive: false // 婵�娲绘按娉㈢汗 + }; + }, + methods: { + // 鎸夐挳鐐瑰嚮 + click(e) { + // 杩涜鑺傛祦鎺у埗锛屾瘡this.throttle姣鍐咃紝鍙湪寮�濮嬪鎵ц + this.$u.throttle(() => { + // 濡傛灉鎸夐挳鏃禿isabled鍜宭oading鐘舵�侊紝涓嶈Е鍙戞按娉㈢汗鏁堟灉 + if (this.loading === true || this.disabled === true) return; + // 鏄惁寮�鍚按娉㈢汗鏁堟灉 + if (this.ripple) { + // 姣忔鐐瑰嚮鏃讹紝绉婚櫎涓婁竴娆$殑绫伙紝鍐嶆娣诲姞锛屾墠鑳借Е鍙戝姩鐢绘晥鏋� + this.waveActive = false; + this.$nextTick(function() { + this.getWaveQuery(e); + }); + } + this.$emit('click', e); + }, this.throttleTime); + }, + // 鏌ヨ鎸夐挳鐨勮妭鐐逛俊鎭� + getWaveQuery(e) { + this.getElQuery().then(res => { + // 鏌ヨ杩斿洖鐨勬槸涓�涓暟缁勮妭鐐� + let data = res[0]; + // 鏌ヨ涓嶅埌鑺傜偣淇℃伅锛屼笉鎿嶄綔 + if (!data.width || !data.width) return; + // 姘存尝绾圭殑鏈�缁堝舰鎬佹槸涓�涓鏂瑰舰(閫氳繃border-radius璁╁叾鍙樹负涓�涓渾褰�)锛岃繖閲岃淇濊瘉姝f柟褰㈢殑杈归暱绛変簬鎸夐挳鐨勬渶闀胯竟 + // 鏈�缁堢殑鏂瑰舰锛堝彉鎹㈠悗鐨勫渾褰級鎵嶈兘瑕嗙洊鏁翠釜鎸夐挳 + data.targetWidth = data.height > data.width ? data.height : data.width; + if (!data.targetWidth) return; + this.fields = data; + let touchesX = '', + touchesY = ''; + // #ifdef MP-BAIDU + touchesX = e.changedTouches[0].clientX; + touchesY = e.changedTouches[0].clientY; + // #endif + // #ifdef MP-ALIPAY + touchesX = e.detail.clientX; + touchesY = e.detail.clientY; + // #endif + // #ifndef MP-BAIDU || MP-ALIPAY + touchesX = e.touches[0].clientX; + touchesY = e.touches[0].clientY; + // #endif + // 鑾峰彇瑙︽懜鐐圭浉瀵逛簬鎸夐挳涓婅竟鍜屽乏杈圭殑x鍜寉鍧愭爣锛屽師鐞嗘槸閫氳繃灞忓箷鐨勮Е鎽哥偣锛坱ouchesY锛夛紝鍑忓幓鎸夐挳鐨勪笂杈圭晫data.top + // 浣嗘槸鐢变簬`transform-origin`榛樿鏄痗enter锛屾墍浠ヨ繖閲屽啀鍑忓幓鍗婂緞鎵嶆槸姘存尝绾箆iew搴旇鐨勪綅缃� + // 鎬荤殑鏉ヨ锛屽氨鏄妸姘存尝绾圭殑鐭╁舰锛堝彉鎹㈠悗鐨勫渾褰級鐨勪腑蹇冪偣锛岀Щ鍔ㄥ埌鎴戜滑鐨勮Е鎽哥偣浣嶇疆 + this.rippleTop = touchesY - data.top - data.targetWidth / 2; + this.rippleLeft = touchesX - data.left - data.targetWidth / 2; + this.$nextTick(() => { + this.waveActive = true; + }); + }); + }, + // 鑾峰彇鑺傜偣淇℃伅 + getElQuery() { + return new Promise(resolve => { + let queryInfo = ''; + // 鑾峰彇鍏冪礌鑺傜偣淇℃伅锛岃鏌ョ湅uniapp鐩稿叧鏂囨。 + // https://uniapp.dcloud.io/api/ui/nodes-info?id=nodesrefboundingclientrect + queryInfo = uni.createSelectorQuery().in(this); + //#ifdef MP-ALIPAY + queryInfo = uni.createSelectorQuery(); + //#endif + queryInfo.select('.u-btn').boundingClientRect(); + queryInfo.exec(data => { + resolve(data); + }); + }); + }, + // 涓嬮潰涓哄鎺niapp瀹樻柟鎸夐挳寮�鏀捐兘鍔涗簨浠跺洖璋冪殑瀵规帴 + getphonenumber(res) { + this.$emit('getphonenumber', res); + }, + getuserinfo(res) { + this.$emit('getuserinfo', res); + }, + error(res) { + this.$emit('error', res); + }, + opensetting(res) { + this.$emit('opensetting', res); + }, + launchapp(res) { + this.$emit('launchapp', res); + } + } +}; +</script> + +<style scoped lang="scss"> +@import '../../libs/css/style.components.scss'; +.u-btn::after { + border: none; +} + +.u-btn { + position: relative; + border: 0; + //border-radius: 10rpx; + /* #ifndef APP-NVUE */ + display: inline-flex; + /* #endif */ + // 閬垮厤杈规鏌愪簺鍦烘櫙鍙兘琚�滆鍓�濓紝涓嶈兘璁剧疆涓篽idden + overflow: visible; + line-height: 1; + @include vue-flex; + align-items: center; + justify-content: center; + cursor: pointer; + padding: 0 40rpx; + z-index: 1; + box-sizing: border-box; + transition: all 0.15s; + + &--bold-border { + border: 1px solid #ffffff; + } + + &--default { + color: $u-content-color; + border-color: #c0c4cc; + background-color: #ffffff; + } + + &--primary { + color: #ffffff; + border-color: $u-type-primary; + background-color: $u-type-primary; + } + + &--success { + color: #ffffff; + border-color: $u-type-success; + background-color: $u-type-success; + } + + &--error { + color: #ffffff; + border-color: $u-type-error; + background-color: $u-type-error; + } + + &--warning { + color: #ffffff; + border-color: $u-type-warning; + background-color: $u-type-warning; + } + + &--default--disabled { + color: #ffffff; + border-color: #e4e7ed; + background-color: #ffffff; + } + + &--primary--disabled { + color: #ffffff!important; + border-color: $u-type-primary-disabled!important; + background-color: $u-type-primary-disabled!important; + } + + &--success--disabled { + color: #ffffff!important; + border-color: $u-type-success-disabled!important; + background-color: $u-type-success-disabled!important; + } + + &--error--disabled { + color: #ffffff!important; + border-color: $u-type-error-disabled!important; + background-color: $u-type-error-disabled!important; + } + + &--warning--disabled { + color: #ffffff!important; + border-color: $u-type-warning-disabled!important; + background-color: $u-type-warning-disabled!important; + } + + &--primary--plain { + color: $u-type-primary!important; + border-color: $u-type-primary-disabled!important; + background-color: $u-type-primary-light!important; + } + + &--success--plain { + color: $u-type-success!important; + border-color: $u-type-success-disabled!important; + background-color: $u-type-success-light!important; + } + + &--error--plain { + color: $u-type-error!important; + border-color: $u-type-error-disabled!important; + background-color: $u-type-error-light!important; + } + + &--warning--plain { + color: $u-type-warning!important; + border-color: $u-type-warning-disabled!important; + background-color: $u-type-warning-light!important; + } +} + +.u-hairline-border:after { + content: ' '; + position: absolute; + pointer-events: none; + // 璁剧疆涓篵order-box锛屾剰鍛崇潃涓嬮潰鐨剆cale缂╁皬涓�0.5锛屽疄闄呬笂缂╁皬鐨勬槸浼厓绱犵殑鍐呭锛坆order-box鎰忓懗鐫�鍐呭涓嶅惈border锛� + box-sizing: border-box; + // 涓績鐐逛綔涓哄彉褰�(scale())鐨勫師鐐� + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + left: 0; + top: 0; + width: 199.8%; + height: 199.7%; + -webkit-transform: scale(0.5, 0.5); + transform: scale(0.5, 0.5); + border: 1px solid currentColor; + z-index: 1; +} + +.u-wave-ripple { + z-index: 0; + position: absolute; + border-radius: 100%; + background-clip: padding-box; + pointer-events: none; + user-select: none; + transform: scale(0); + opacity: 1; + transform-origin: center; +} + +.u-wave-ripple.u-wave-active { + opacity: 0; + transform: scale(2); + transition: opacity 1s linear, transform 0.4s linear; +} + +.u-round-circle { + border-radius: 100rpx; +} + +.u-round-circle::after { + border-radius: 100rpx; +} + +.u-loading::after { + background-color: hsla(0, 0%, 100%, 0.35); +} + +.u-size-default { + font-size: 30rpx; + height: 80rpx; + line-height: 80rpx; +} + +.u-size-medium { + /* #ifndef APP-NVUE */ + display: inline-flex; + /* #endif */ + width: auto; + font-size: 26rpx; + height: 70rpx; + line-height: 70rpx; + padding: 0 80rpx; +} + +.u-size-mini { + /* #ifndef APP-NVUE */ + display: inline-flex; + /* #endif */ + width: auto; + font-size: 22rpx; + padding-top: 1px; + height: 50rpx; + line-height: 50rpx; + padding: 0 20rpx; +} + +.u-primary-plain-hover { + color: #ffffff !important; + background: $u-type-primary-dark !important; +} + +.u-default-plain-hover { + color: $u-type-primary-dark !important; + background: $u-type-primary-light !important; +} + +.u-success-plain-hover { + color: #ffffff !important; + background: $u-type-success-dark !important; +} + +.u-warning-plain-hover { + color: #ffffff !important; + background: $u-type-warning-dark !important; +} + +.u-error-plain-hover { + color: #ffffff !important; + background: $u-type-error-dark !important; +} + +.u-info-plain-hover { + color: #ffffff !important; + background: $u-type-info-dark !important; +} + +.u-default-hover { + color: $u-type-primary-dark !important; + border-color: $u-type-primary-dark !important; + background-color: $u-type-primary-light !important; +} + +.u-primary-hover { + background: $u-type-primary-dark !important; + color: #fff; +} + +.u-success-hover { + background: $u-type-success-dark !important; + color: #fff; +} + +.u-info-hover { + background: $u-type-info-dark !important; + color: #fff; +} + +.u-warning-hover { + background: $u-type-warning-dark !important; + color: #fff; +} + +.u-error-hover { + background: $u-type-error-dark !important; + color: #fff; +} +</style> -- Gitblit v1.9.3