[商城整个模块,及个人中心相应的模块调整]
This commit is contained in:
93
uni_modules/pyh-nv/changelog.md
Normal file
93
uni_modules/pyh-nv/changelog.md
Normal file
@@ -0,0 +1,93 @@
|
||||
## 1.2.8(2021-08-17)
|
||||
1、修复搜索导航栏按钮组位置问题
|
||||
## 1.2.7(2021-08-13)
|
||||
1、h5端自动同步标签标题(如微信标题)<br>
|
||||
2、组件内新增h5AutoTitle,配置后可以h5端自动获取页面标题,详情看描述文件
|
||||
## 1.2.6(2021-08-13)
|
||||
更新说明文档
|
||||
## 1.2.5(2021-08-13)
|
||||
修复按钮组位置偏差问题
|
||||
## 1.2.4(2021-07-21)
|
||||
1、btn的icon添加text,可以带文字<br>
|
||||
2、修复样式(btn右边间距、输入框字体大小改为inherit等)
|
||||
## 1.2.3(2021-07-20)
|
||||
1、开启了model滚动监听<br>
|
||||
2、按钮组添加了badge设置角标
|
||||
## 1.2.2(2021-05-25)
|
||||
1、新增设置样式事件setStyle(),可通过ref来调用
|
||||
2、修改config内style传参格式(改为string类型),兼容小程序
|
||||
3、新增组件内注释
|
||||
4、其它小优化
|
||||
## 1.2.1(2021-03-16)
|
||||
处理了手机从竖屏变横屏后显示错乱问题
|
||||
## 1.2.0(2021-03-05)
|
||||
处理了右按钮样式小程序兼容错误
|
||||
## 1.1.9(2021-03-01)
|
||||
处理nvue兼容性(引入scss失败、css错误)
|
||||
## 1.1.8(2021-02-25)
|
||||
1、兼容nvue
|
||||
2、添加背景图
|
||||
## 1.1.7(2021-02-24)
|
||||
1、兼容uni_modules(官方新推出的插件管理);兼容nv写法,需要在pages.json添加代码:"easycom": {"nv": "@/uni_modules/pyh-nv/components/pyh-nv/pyh-nv.vue"}
|
||||
2、nvRoute函数更名为nv
|
||||
|
||||
## 1.1.6(2021-02-01)
|
||||
1、修复model定位问题
|
||||
|
||||
## 1.1.5(2021-02-01)
|
||||
1、全类型支持设置右方按钮组
|
||||
2、添加h5 document.title等于config的标题
|
||||
3、添加属性model,可在页面内独立使用,常用于不满足右方按钮小程序不显示的兼容方案(使用2个nv)
|
||||
4、优化代码结构
|
||||
|
||||
## 1.1.4(2020-11-18)
|
||||
1、修复微信公众号中input的disabled点击跳转失效问题
|
||||
2、修复右上角纯图片按钮变形问题
|
||||
|
||||
## 1.1.3(2020-09-27)
|
||||
修复config空值有时会报错的bug
|
||||
|
||||
## 1.1.2(2020-09-14)
|
||||
添加通用导航栏渐变色背景功能(渐变色背景会导致transparent背景色渐变失效)
|
||||
|
||||
## 1.1.1(2020-09-01)
|
||||
修复icon原生组件在小程序内高度铺满导致的错误问题
|
||||
|
||||
## 1.1.0(2020-08-27)
|
||||
1、使用icon代替图片图标,完全独立组件
|
||||
2、添加回到顶部的功能
|
||||
|
||||
## 1.0.9(2020-08-18)
|
||||
''' 1、单logo模式,支持全样式设置,可实现全背景图等
|
||||
2、优化了路由跳转判断及多端跳转
|
||||
3、组件内,利用了scss的特性,优化了主色的修改
|
||||
4、示例项目内添加了全局变量globalData,以及全路由封装函数nvRoute,组件也做了兼容处理,可快速设置配置,如需路由做特殊处理(比如history模式等),可使用封装的nvRoute统一处理 '''
|
||||
|
||||
## 1.0.8(2020-08-17)
|
||||
1、修改搜索框动态赋值方式,更加方便,直接修改search.value,需要初始化value,旧的赋值方式已废弃。(重要) 2、注释样式:上版本组件内样式,没有注释uni.scss的部分
|
||||
|
||||
## 1.0.7(2020-08-13)
|
||||
1、修改标题字体的size和weight,等同于uniapp的h5样式 2、补充组件主色覆盖样式的注释,可去除注释快速修改,也可使用uni.scss快速修改主色
|
||||
|
||||
## 1.0.6(2020-07-29)
|
||||
1、补充文档对于搜索框赋值的说明,添加动态赋值功能
|
||||
|
||||
## 1.0.5(2020-07-20)
|
||||
补充单组件文件缺少的文件iconfont.wxss(后续版本已移除该文件)
|
||||
|
||||
## 1.0.4(2020-07-08)
|
||||
1、修复fixed定位,辅助容器高度问题
|
||||
|
||||
2、补充示例项目属性项
|
||||
|
||||
## 1.0.3(2020-07-08)
|
||||
1、添加config.position属性,并且默认为'fixed' 2、添加config.fixedAssist属性———固定定位辅助导航栏,高度与导航栏一致,可设置背景色 3、原home返回键背景取消,如需要,需使用componentBgColor 4、状态栏字体颜色与导航栏字体颜色一致(状态栏字体只支持#000000或#ffffff) 5、config.color 改为导航栏和状态栏字体色,也用于渐变完成时字体色(状态栏字体只支持#000000或#ffffff) 6、transparent.initColor代替之前的状态栏字体颜色设置,该值为导航栏与状态栏初始色(状态栏字体只支持#000000或#ffffff) 7、修改默认字体色为'#000000'
|
||||
|
||||
## 1.0.2(2020-07-07)
|
||||
修改示例配置,更友好上手
|
||||
|
||||
## 1.0.1(2020-07-07)
|
||||
上传初版,更新说明文档
|
||||
|
||||
## 1.0.0(2020-07-07)
|
||||
上传初版
|
||||
BIN
uni_modules/pyh-nv/components/pyh-nv/iconfont.ttf
Normal file
BIN
uni_modules/pyh-nv/components/pyh-nv/iconfont.ttf
Normal file
Binary file not shown.
515
uni_modules/pyh-nv/components/pyh-nv/pyh-nv.vue
Normal file
515
uni_modules/pyh-nv/components/pyh-nv/pyh-nv.vue
Normal file
@@ -0,0 +1,515 @@
|
||||
<template name="nv">
|
||||
<view class="pyh-nv-box" :style="style">
|
||||
<view class='nvHeight' :style="[{'height':navigatorHeight+'px'},{'background':(config.fixedAssist&&config.fixedAssist.bgColor)||''}]" v-if="isFixed&&!(config.fixedAssist&&config.fixedAssist.hide)"></view>
|
||||
<image :src="config.bgImage" :style="[{'position':config.model?'fixed':'absolute'},{'top':(config.model?(navigatorTop+'px'):0)},{'width':windowWidth+'px','height':navigatorHeight+'px'}]" v-if="config.bgImage" class="bgImage"></image>
|
||||
<view :class="['nvBox',{'noModel':!config.model}]" :style="[{'width':windowWidth+'px'},{'color':getTxtColor},{'background':getBgColor},{'opacity':config.transparent&&config.transparent.type=='content'?transparent.opacity:1},{'position':isFixed?'fixed':'relative'},{'top':(isFixed&&config.model?(navigatorTop+'px'):0)}]">
|
||||
<view class='nvHeight' :style="[{'height':navigatorHeight+'px'}]"></view>
|
||||
<view class='nvFixed' :style="[{'width':windowWidth+'px'}]">
|
||||
<!-- 单logo -->
|
||||
<view :class="['nvContent','nvLogoBox',{'androidwx':androidwx}]" v-if="config.type=='logo'">
|
||||
<image :src="config.logo.src?config.logo.src:'/static/logo.png'" class="nvLogo" :style="config.logo.style" :mode="config.logo.style|getImgMode" @tap.stop="nvLogoTap"></image>
|
||||
<view v-if="config.btn&&config.btn.length>0" class="nvBtnGroup">
|
||||
<block v-for="(b,n) in config.btn" :key="n">
|
||||
<view class="nvBtn" v-if="b.icon" @tap.stop="nvBtnTap" :data-index="n" :data-type="b.type" :style="b.style||''">
|
||||
<image :src="b.icon" mode="widthFix" class="nvBtnImg"></image>
|
||||
<text class="nvBtnIconTxt" v-if="b.text">{{b.text}}</text>
|
||||
<view class="nvBadge" v-if="b.badge&&b.badge.text" :style="b.badge.style||''">{{b.badge.text}}</view>
|
||||
</view>
|
||||
<view class="nvBtn" v-else-if="b.text" @tap.stop="nvBtnTap" :data-index="n" :data-type="b.type" :style="b.style||{color:getTxtColor}">
|
||||
<text>{{b.text}}</text>
|
||||
<view class="nvBadge" v-if="b.badge&&b.badge.text" :style="b.badge.style||''">{{b.badge.text}}</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 含搜索 -->
|
||||
<view :class="['nvContent','nvSearchBox',{'nvHadBack':!config.hideback}]" v-else-if="config.type=='search'">
|
||||
<image :src="config.logo.src?config.logo.src:'/static/logo.png'" class="nvLogo nvSearchLogo" :style="config.logo.style" :mode="config.logo.style|getImgMode" @tap.stop="nvLogoTap" v-if="config.logo&&!config.address"></image>
|
||||
<view class="nvAddress" :style="[{'background':(config.address.bgColor||config.componentBgColor||'')},{'color':(config.address.color||'')}]" v-if="config.address" @tap.stop="nvAddressTap">
|
||||
<text class="iconfont nvAddressIcon" :style="{'color':(config.address.color||'')}"></text>
|
||||
|
||||
<view class="nvAddressTextBox">
|
||||
<text class="nvAddressText">{{config.address[config.address.fields||'province']||'广东省'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nvSForm" >
|
||||
<view class="nvSBox" :style="[{'background':(config.search.bgColor||config.componentBgColor||'')},{'border':config.search.border||''}]" @tap.stop="searchTap" data-isInput="true">
|
||||
<icon type="search" size="18" class="searchIcon"></icon>
|
||||
<input class="nvInput" type="text" :value="inputValue" :focus="config.search.focus" :placeholder="config.search.placeholder" :disabled="!config.search.input" @input="inputChange" @confirm="formSubmit" :confirm-type="config.search.confirmType||'search'" placeholder-class="searchPlac" :placeholder-style="config.search.placeholderStyle||''"/>
|
||||
<icon type="clear" size="15" class="nvSClose" @tap.stop="inputClear" v-if="inputValue"></icon>
|
||||
</view>
|
||||
<text class='nvSBtn' @tap.stop="formSubmit" v-if="config.search.btn&&config.search.input" :style="config.search.btn.style||''">{{config.search.btn.text||'搜索'}}</text>
|
||||
</view>
|
||||
<view v-if="config.btn&&config.btn.length>0" class="nvBtnGroup nvBtnGroup-static">
|
||||
<block v-for="(b,n) in config.btn" :key="n">
|
||||
<view class="nvBtn" v-if="b.icon" @tap.stop="nvBtnTap" :data-index="n" :data-type="b.type" :style="b.style||''">
|
||||
<image :src="b.icon" mode="widthFix" class="nvBtnImg"></image>
|
||||
<text class="nvBtnIconTxt" v-if="b.text">{{b.text}}</text>
|
||||
<view class="nvBadge" v-if="b.badge&&b.badge.text" :style="b.badge.style||''">{{b.badge.text}}</view>
|
||||
</view>
|
||||
<view class="nvBtn" v-else-if="b.text" @tap.stop="nvBtnTap" :data-index="n" :data-type="b.type" :style="b.style||{color:getTxtColor}">
|
||||
<text>{{b.text}}</text>
|
||||
<view class="nvBadge" v-if="b.badge&&b.badge.text" :style="b.badge.style||''">{{b.badge.text}}</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 默认导航栏 -->
|
||||
<view class="nvContent nvDefault" v-else>
|
||||
<view v-if="config.tabArr&&config.tabArr.length>0" :class="['nvTitle','nvTabBox',{'androidwx':androidwx}]">
|
||||
<view :class="['nvTab',{'nvTabHide':t.hide}]" @tap.stop="nvTabTap" :data-index="i" v-for="(t,i) in config.tabArr" :key="i">
|
||||
<text :class="[t.active?'nTTxt-ac':'nTTxt']" :style="{'color':(t.active?mainColor:getTxtColor)}">{{t.title}}</text>
|
||||
<view :class="[t.active?'nTLine-ac':'nTLine']"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else :class="['nvTitle',{'androidwx':androidwx},{'hideback':config.hideback}]">
|
||||
<text :style="{'color': getTxtColor}">{{config.title||title}}</text>
|
||||
|
||||
</view>
|
||||
<view v-if="config.btn&&config.btn.length>0" class="nvBtnGroup">
|
||||
<block v-for="(b,n) in config.btn" :key="n">
|
||||
<view class="nvBtn" v-if="b.icon" @tap.stop="nvBtnTap" :data-index="n" :data-type="b.type" :style="b.style||''">
|
||||
<image :src="b.icon" mode="widthFix" class="nvBtnImg"></image>
|
||||
<text class="nvBtnIconTxt" v-if="b.text">{{b.text}}</text>
|
||||
<view class="nvBadge" v-if="b.badge&&b.badge.text" :style="b.badge.style||''">{{b.badge.text}}</view>
|
||||
</view>
|
||||
<view class="nvBtn" v-else-if="b.text" @tap.stop="nvBtnTap" :data-index="n" :data-type="b.type" :style="b.style||{color:getTxtColor}">
|
||||
<text>{{b.text}}</text>
|
||||
<view class="nvBadge" v-if="b.badge&&b.badge.text" :style="b.badge.style||''">{{b.badge.text}}</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 返回键 -->
|
||||
<text :class="['iconfont','nvback',{'nvhome':isSharePage&&!config.closeCheckback}]" @tap.stop="backTap" :style="{'background':(isSharePage&&!config.closeCheckback?(config.componentBgColor||''):''),'color':getTxtColor,'border-radius':'26rpx','font-size': isSharePage&&!config.closeCheckback?'36rpx':'54rpx'}" v-if="!config.hideback">{{isSharePage&&!config.closeCheckback?'':''}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="iconfont nvToTop" :style="(config.toTop&&config.toTop.style)||''" v-if="config.toTop&&showToTop" @tap.stop="toTopTap"></text>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
var platform;
|
||||
//#ifdef H5
|
||||
platform="h5"
|
||||
//#endif
|
||||
//#ifdef APP-PLUS
|
||||
platform="app"
|
||||
//#endif
|
||||
//#ifdef MP
|
||||
platform="mp"
|
||||
//#endif
|
||||
export default {
|
||||
name:"nv",
|
||||
props:{
|
||||
config:{
|
||||
type:Object,
|
||||
default(){
|
||||
return {}
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title:getApp().globalData.NAME||"pyh-nv",
|
||||
h5AutoTitle:true,
|
||||
platform:platform||'h5',
|
||||
mainColor:getApp().globalData.mainColor||"#fff",
|
||||
currentPages:getCurrentPages().length||1,
|
||||
home:getApp().globalData.HOME||"/pages/index/index",
|
||||
inputValue:'',
|
||||
showToTop:false,
|
||||
transparent:{
|
||||
initColor:"#ffffff",
|
||||
finishColor:"#000000",
|
||||
color:"#ffffff",
|
||||
opacity:0
|
||||
},
|
||||
windowWidth:uni.getSystemInfoSync().windowWidth,
|
||||
style:""
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
"config.search.value":function(value){
|
||||
//监听输入框值得改变
|
||||
var e = {detail:{value:value}};
|
||||
this.inputValue = e.detail.value;
|
||||
if(this.config.type=="search"&&this.config.search.input)this.$emit("nvInput",e);
|
||||
}
|
||||
},
|
||||
filters:{
|
||||
getImgMode(style){
|
||||
//获取图片mode类型
|
||||
if(style&&style.indexOf("height")>-1){
|
||||
return 'aspectFill';
|
||||
}else{
|
||||
return 'widthFix';
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
statusHeight(){
|
||||
//状态栏高度
|
||||
var statusBarHeight = this.config.model?0:uni.getSystemInfoSync().statusBarHeight;
|
||||
return statusBarHeight+'px';
|
||||
},
|
||||
navigatorHeight(){
|
||||
//导航栏高度
|
||||
var statusBarHeight = this.config.model?0:uni.getSystemInfoSync().statusBarHeight;
|
||||
var windowWidth = this.lockWindowWidth&&this.windowWidth>750?375:this.windowWidth;
|
||||
return parseInt(88*windowWidth/750)+statusBarHeight;
|
||||
},
|
||||
navigatorTop(){
|
||||
//model类型下的顶部高度
|
||||
var windowWidth = this.lockWindowWidth&&this.windowWidth>750?375:this.windowWidth;
|
||||
if(this.config.model){
|
||||
return parseInt(88*windowWidth/750)+uni.getSystemInfoSync().statusBarHeight;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
//安全区域高度
|
||||
safeArea(){return this.config.safeArea||uni.getSystemInfoSync().safeArea.height;},
|
||||
//固定定位判断
|
||||
isFixed(){return this.config.transparent||this.config.position=='fixed'||this.config.position=='absolute'||!this.config.position;},
|
||||
//判断分享页
|
||||
isSharePage(){return this.currentPages==1;},
|
||||
//安卓微信
|
||||
androidwx(){
|
||||
if(this.config.checkAndroidwx&&this.platform=="mp"&&uni.getSystemInfoSync().platform.indexOf("ios")==-1){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
},
|
||||
//获取字体色
|
||||
getTxtColor(){
|
||||
return ((this.config.transparent&&this.config.transparent.initColor)?this.transparent.color:'')||this.config.color||'';
|
||||
},
|
||||
//获取/转换背景色
|
||||
getBgColor(){
|
||||
var that = this;
|
||||
if(this.config.bgImage){
|
||||
return "transparent";
|
||||
}else if(this.config.bgColor&&this.config.bgColor.indexOf("gradient")>-1){
|
||||
return this.config.bgColor;
|
||||
}else{
|
||||
return (this.config.bgColor||this.config.transparent)?'rgba('+getRgbString()+','+(this.config.transparent&&this.config.transparent.type!='content'?this.transparent.opacity:1)+')':'#fff';
|
||||
}
|
||||
function getRgbString(){
|
||||
var bgColor = that.config.bgColor||"#ffffff",returnString=""
|
||||
if(bgColor.indexOf(",")>-1){
|
||||
returnString = bgColor.split('(')[1].replace(')','').split(',').slice(0,3).join(",")
|
||||
}else{
|
||||
if(bgColor.length==4)bgColor = bgColor+bgColor.charAt(bgColor.length-1)+bgColor.charAt(bgColor.length-1)+bgColor.charAt(bgColor.length-1)
|
||||
var string = bgColor.replace("#",'');
|
||||
returnString = parseInt(string.substring(0,2), 16)+','+parseInt(string.substring(2,4), 16)+','+parseInt(string.substring(4,6), 16)
|
||||
}
|
||||
return returnString
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// #ifdef APP-NVUE
|
||||
var domModule = weex.requireModule("dom");
|
||||
domModule.addRule('fontFace', {
|
||||
'fontFamily': 'iconfont',
|
||||
'src': "url('http://at.alicdn.com/t/font_1687851_vdpjdiddv6.ttf')"
|
||||
})
|
||||
// #endif
|
||||
|
||||
if(this.config.search&&this.config.search.value)this.inputValue=this.config.search.value;
|
||||
if(this.config.transparent&&this.config.transparent.initColor){
|
||||
var initColor = this.config.transparent.initColor,finishColor = this.config.color||"#000000";
|
||||
if(initColor.indexOf("#")>-1&&initColor.length==4){
|
||||
initColor = initColor+initColor.charAt(initColor.length-1)+initColor.charAt(initColor.length-1)+initColor.charAt(initColor.length-1);
|
||||
}
|
||||
if(finishColor.indexOf("#")>-1&&finishColor.length==4){
|
||||
finishColor = finishColor+finishColor.charAt(finishColor.length-1)+finishColor.charAt(finishColor.length-1)+finishColor.charAt(finishColor.length-1);
|
||||
}
|
||||
if(!((initColor=="#000000"||initColor=="#ffffff")&&(finishColor=="#000000"||finishColor=="#ffffff"))){
|
||||
console.log("状态栏颜色只支持,#000000或#ffffff");
|
||||
}
|
||||
this.transparent.initColor = initColor;
|
||||
this.transparent.color = initColor;
|
||||
this.transparent.finishColor = finishColor;
|
||||
}
|
||||
this.deviceOrientation=uni.getSystemInfoSync().windowWidth>750?"landscape":"portrait";
|
||||
if(this.deviceOrientation=="portrait")this.lockWindowWidth=true;
|
||||
uni.onWindowResize((res)=>{
|
||||
if(this.deviceOrientation!=res.deviceOrientation){
|
||||
this.deviceOrientation = res.deviceOrientation;
|
||||
this.windowWidth = res.size.windowWidth;
|
||||
}
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
if(this.config.color){
|
||||
var obj = {frontColor:this.config.color,backgroundColor:this.config.bgColor||"#ffffff"};
|
||||
uni.setNavigationBarColor(obj);
|
||||
}
|
||||
if(this.config.transparent&&this.config.transparent.initColor){
|
||||
var obj = {frontColor:this.transparent.initColor,backgroundColor:this.config.bgColor||"#ffffff"};
|
||||
uni.setNavigationBarColor(obj);
|
||||
}
|
||||
if(platform=="h5"&&!this.config.model){
|
||||
this.config.title&&uni.setNavigationBarTitle({title:this.config.title})
|
||||
if(document.title&&this.h5AutoTitle)this.title=document.title
|
||||
document.setTitle = function(t) {document.title = t;var i = document.createElement('iframe');/*i.src = '//m.baidu.com/favicon.ico';*/i.style.display = 'none';i.onload = function() {setTimeout(function(){i.remove();}, 9)};document.body.appendChild(i);}
|
||||
setTimeout(()=>{document.setTitle(this.config.title||this.title);}, 1);
|
||||
}
|
||||
},
|
||||
onUnload() {uni.offWindowResize();},
|
||||
methods:{
|
||||
setStyle(object){
|
||||
//设置导航栏样式
|
||||
var style = "";
|
||||
for(var i in object){style += (i+":"+object[i]+";")}
|
||||
this.style=style;
|
||||
},
|
||||
nvLogoTap(e){
|
||||
//logo点击
|
||||
var url = this.config.logo.url;
|
||||
this.$emit("nvLogoTap");
|
||||
url&&uni.reLaunch({url:url});
|
||||
},
|
||||
nvAddressTap(e){
|
||||
//地址图标点击
|
||||
this.$emit("nvAddressTap");
|
||||
},
|
||||
searchTap(e){
|
||||
//搜索按钮点击
|
||||
if(this.config.search.url||this.config.search.linkType){
|
||||
this.linkTo({currentTarget:{dataset:{url:this.config.search.url,type:this.config.search.linkType||''}}});
|
||||
}else{
|
||||
this.$emit("searchTap");
|
||||
}
|
||||
},
|
||||
inputChange(e){
|
||||
//输入框输入
|
||||
this.inputValue = e.detail.value;
|
||||
if(this.config.type=="search"&&this.config.search.input)this.$emit("nvInput",e)
|
||||
},
|
||||
inputClear(e){
|
||||
//输入框清除
|
||||
this.inputValue="";
|
||||
if(this.config.type=="search"&&this.config.search.input)this.$emit("nvInput",e);
|
||||
},
|
||||
formSubmit(e){
|
||||
//输入框提交
|
||||
var e = {detail:{value:this.inputValue}};
|
||||
this.$emit("nvFormSubmit",e)
|
||||
},
|
||||
nvBtnTap(e){
|
||||
//右按键点击
|
||||
var e = {type:e.currentTarget.dataset.type,index:parseInt(e.currentTarget.dataset.index)};
|
||||
this.$emit("nvBtnTap",e);
|
||||
},
|
||||
nvTabTap(e){
|
||||
//中间tab按键点击
|
||||
var e = {index:parseInt(e.currentTarget.dataset.index)};
|
||||
this.$emit("nvTabTap",e);
|
||||
},
|
||||
toTopTap(e){
|
||||
//回到顶部
|
||||
this.showToTop=false
|
||||
uni.pageScrollTo({scrollTop:0,duration:this.config.toTop.duration||(this.config.toTop.duration===0?0:300)});
|
||||
this.$emit("nvToTop");
|
||||
},
|
||||
pageScroll(e={scrollTop:0}){
|
||||
//页面滚动
|
||||
if(!this.config.transparent)return;
|
||||
var anchor = this.navigatorHeight;
|
||||
if(this.config.transparent.anchor)anchor=this.config.transparent.anchor;
|
||||
var op = parseFloat(parseFloat(e.scrollTop/anchor).toFixed(1));
|
||||
if(e.scrollTop<=anchor){
|
||||
this.transparent.opacity = op;
|
||||
if(this.config.transparent.initColor){
|
||||
if(op>=.5){
|
||||
this.transparent.color=this.transparent.finishColor;
|
||||
uni.setNavigationBarColor({frontColor:this.transparent.finishColor,backgroundColor:this.config.bgColor||"#ffffff"});
|
||||
}else{
|
||||
this.transparent.color=this.transparent.initColor;
|
||||
uni.setNavigationBarColor({frontColor:this.transparent.initColor,backgroundColor:this.config.bgColor||"#ffffff"});
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.transparent.opacity = 1;
|
||||
}
|
||||
if(this.config.toTop){
|
||||
if(this.showToTop&&e.scrollTop<this.safeArea){
|
||||
this.showToTop=false;
|
||||
}
|
||||
if(!this.showToTop&&e.scrollTop>=this.safeArea){
|
||||
this.showToTop=true;
|
||||
}
|
||||
}
|
||||
},
|
||||
backTap(){
|
||||
//返回键点击
|
||||
if(this.config.backpress){
|
||||
this.$emit("backTap");
|
||||
}else{
|
||||
this.linkTo({currentTarget:{dataset:{type:'navigateBack'}}});
|
||||
}
|
||||
},
|
||||
linkTo(e) {
|
||||
//跳转
|
||||
var url=e.currentTarget.dataset.url,
|
||||
type=e.currentTarget.dataset.type,
|
||||
isInput=e.currentTarget.dataset.isInput;
|
||||
if(isInput&&this.config.type=="search"&&this.config.search&&this.config.search.input){
|
||||
return;
|
||||
}
|
||||
if(this.$nv){
|
||||
this.$nv(url,type);
|
||||
}else{
|
||||
if(!url&&!type)return;
|
||||
if(url=="/"||url==".")return;
|
||||
if(typeof(url)=="object"){
|
||||
uni.navigateTo(url);
|
||||
return
|
||||
}
|
||||
if(typeof(url)=="number"){
|
||||
if(this.currentPages==1){
|
||||
uni.reLaunch({url:this.home})
|
||||
}else{
|
||||
uni.navigateBack({delta:Math.abs(url||1)})
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(type){
|
||||
if (type.indexOf("ab")>-1) {
|
||||
uni.switchTab({ url: url });
|
||||
} else if (type=='-1'||type.indexOf("redirect")>-1||type.indexOf("rep")>-1) {
|
||||
uni.redirectTo({ url: url });
|
||||
} else if (type.indexOf("aunch")>-1) {
|
||||
uni.reLaunch({ url: url });
|
||||
} else if (type.indexOf("ack")>-1) {
|
||||
if(this.currentPages==1){
|
||||
uni.reLaunch({url:this.home});
|
||||
}else{
|
||||
uni.navigateBack();
|
||||
}
|
||||
}else{
|
||||
uni.navigateTo({url:url});
|
||||
}
|
||||
}else{
|
||||
if(url.indexOf("/")==0||url.indexOf(".")==0){
|
||||
uni.navigateTo({url:url});
|
||||
}else{
|
||||
if(url.indexOf("?")>0){url+="&platform="+platform;}else{url+="?platform="+platform;};
|
||||
if(platform=="h5"){
|
||||
top.location.href=url;
|
||||
}else if(platform=="app"){
|
||||
plus.runtime.openUrl(url);
|
||||
}else{
|
||||
uni.navigateTo({url:"/pages/other/webview/webview?src="+url.replace("?","&")});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@font-face {
|
||||
font-family: iconfont;
|
||||
src: url('./iconfont.ttf')
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: iconfont;
|
||||
font-size: 30rpx;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
//主色,可以设置uni.scss的$mainColor
|
||||
//或
|
||||
//uni.scss未定义或定义为null,修改下方$mainColor的默认值
|
||||
$mainColor: #aa55ff !default;
|
||||
|
||||
.pyh-nv-box{position: relative;}
|
||||
.bgImage{position: absolute;left: 0;top: 0;}
|
||||
.nvBox{background-color: #fff;z-index: 991;color: #000000;}
|
||||
.noModel{z-index: 992;}
|
||||
.nvHeight{height: 88rpx;}
|
||||
.nvFixed{position: absolute;bottom: 0;height: 88rpx;left: 0;z-index: 992;padding: 0 20rpx;}
|
||||
.nvContent{flex: 1;height: 88rpx;align-items: center;}
|
||||
.nvInput{font-size: inherit;flex: 1;}
|
||||
.searchIcon{
|
||||
width: 18px;
|
||||
margin-right: 20rpx;
|
||||
/* #ifdef MP */
|
||||
height: 18px;
|
||||
/* #endif */
|
||||
}
|
||||
.nvTitle{position: absolute;top: 0;left: 0;right: 0;text-align: center;height: 88rpx;line-height: 88rpx;align-items: center;justify-content: center;padding: 0 80rpx;font-size: 32rpx;font-weight: bold;overflow: hidden;text-overflow: ellipsis;}
|
||||
.androidwx{text-align: left;padding-left: 80rpx;justify-content: flex-start!important;}
|
||||
.nvback{font-size: 54rpx;position: absolute;left: 6rpx;padding-left: 8rpx;bottom: 18rpx;flex-direction: row;align-items: center;z-index: 992;width: 52rpx;height: 52rpx;}
|
||||
.nvhome{border-radius: 26rpx;font-size: 36rpx;padding: 0;left: 20rpx;text-align: center;justify-content: center;}
|
||||
.nvHadBack{padding-left: 60rpx;}
|
||||
|
||||
//logo
|
||||
.nvLogoBox{align-items: center;justify-content: center;position: absolute;left: 0;padding-right: 0rpx!important;left: 0;right: 0;}
|
||||
.nvLogo{width: 60rpx;}
|
||||
|
||||
//含搜索框
|
||||
.nvSearchLogo{margin-right: 20rpx;}
|
||||
.nvAddress{background-color: #f8f8f8;border-radius: 44rpx;justify-content: center;align-items: center;padding: 0 16rpx 0 10rpx;font-size: 28rpx;line-height: 30rpx;margin-right: 20rpx;color: #000000;height: 60rpx;width: 144rpx;}
|
||||
.nvAddressIcon{width: 30rpx;margin-right: 4rpx;font-size: 34rpx;}
|
||||
.nvAddressTextBox{width: 84rpx;overflow: hidden;}
|
||||
.nvAddressText{flex: 1;font-size: 28rpx;line-height: 30rpx;overflow: hidden;text-overflow: ellipsis;}
|
||||
.searchPlac{color: #bbb;}
|
||||
.nvSForm{flex: 1;justify-content: space-between;align-items: center;}
|
||||
.nvSBox{flex: 1;border-radius: 44rpx;background-color: #f8f8f8;height: 60rpx;line-height: 60rpx;padding: 0 20rpx;align-items: center;}
|
||||
.nvSBtn{color: #fff;border-radius: 44rpx;height: 60rpx;line-height: 60rpx;width: 120rpx;padding: 0;text-align: center;font-size: 28rpx;margin-left: 20rpx;background-color: $mainColor;}
|
||||
.nvSClose{
|
||||
/* #ifdef MP */
|
||||
height: 15px;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
//右边按钮组
|
||||
.nvBtnGroup{position: absolute;right: 20rpx;top: 0;height: 88rpx;align-items: center;justify-content: center;z-index: 993;font-size: 28rpx;color: #000000;}
|
||||
.nvBtn{display: flex;align-items: center;justify-content: center;flex-direction: column;text-align: center;}
|
||||
.nvBtn:first-child{margin-left: 0;}
|
||||
.nvBtn,.nvBtnImg{padding: 0;margin-left: 20rpx;background: transparent;border: 0;color: #000000;z-index: 3;font-size: 28rpx;position: relative;}
|
||||
.nvBtnImg{width: 48rpx;margin-left: 0;}
|
||||
.nvBtnGroup-static{position: relative;padding-left: 20rpx;right: 0;}
|
||||
.nvBtn .nvBadge{width: 26rpx;height: 26rpx;position: absolute;top: -8rpx;right: -8rpx;display: flex;align-items: center;justify-content: center;border-radius: 50%;overflow: hidden;background-color: red;color: #fff;font-size: 16rpx;z-index: 4;}
|
||||
|
||||
//tab栏
|
||||
.nvTabBox{position: absolute!important;}
|
||||
.nvTab{flex-direction: column!important;align-items: center;justify-content: flex-end;margin: 0 10rpx;position: relative;}
|
||||
.nTTxt,.nTTxt-ac{padding: 0 10rpx;line-height: 88rpx;}
|
||||
.nTLine,.nTLine-ac{height: 4rpx;border-radius: 2rpx;background: transparent;position: absolute;bottom: 0;left: 0;right: 0;}
|
||||
.nTTxt-ac{color: $mainColor;}
|
||||
.nTLine-ac{background: $mainColor;}
|
||||
.nvTabHide{width:0;height:0;margin:0;overflow:hidden;}
|
||||
|
||||
//回到顶部
|
||||
.nvToTop{position: fixed;bottom: 200rpx;right: 40rpx;z-index: 992;background: #fff;border-radius: 50%;width: 80rpx;height: 80rpx;text-align: center;line-height: 80rpx;font-size: 46rpx;box-shadow: 2rpx 2rpx 2rpx 2rpx #ddd;}
|
||||
|
||||
//小程序胶囊留位
|
||||
/* #ifdef MP-WEIXIN */
|
||||
.noModel .nvContent{padding-right: 200rpx;}
|
||||
.noModel .nvSBtn,.noModel .nvBtnGroup{display: none;}
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef APP-NVUE */
|
||||
.nvContent,.nvback,.nvLogoBox,.nvSearchBox,.nvAddress,.nvSForm,.nvSBox,.nvBtnGroup,.nvTabBox,.nvTab{flex-direction: row;}
|
||||
.nvTitle,.nvAddress,.nvAddressText{lines: 1;}
|
||||
.pyh-nv-box,.nvBox,.nvHeight,.nvFixed,.nvTitle,.nvLogoBox,.nvSearchBox,.nTLine,.nTLine-ac{flex: 1;}
|
||||
.nvTab{flex-direction: column!important;align-items: center;justify-content: flex-end;line-height: 80rpx;margin: 0 10rpx;}
|
||||
/* #endif */
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
.nvContent,.nvback,.nvLogoBox,.nvSearchBox,.nvAddress,.nvSForm,.nvSBox,.nvBtnGroup,.nvTabBox,.nvTab{display: flex;flex-direction: row;}
|
||||
.nvTitle,.nvAddressText{white-space: nowrap;}
|
||||
.nvBox,.nvBox *,.nvContent,.nvTitle,.nvFixed{box-sizing: border-box;}
|
||||
.nvLogo,.nvAddressIcon,.nvBtnImg{height: auto;}
|
||||
.pyh-nv-box,.nvBox,.nvHeight,.nvFixed,.nvTitle,.nvLogoBox,.nvSearchBox,.nTLine,.nTLine-ac{width: 100%;}
|
||||
/* #endif */
|
||||
</style>
|
||||
79
uni_modules/pyh-nv/package.json
Normal file
79
uni_modules/pyh-nv/package.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"id": "pyh-nv",
|
||||
"name": "pyh-nv 全自定义、全兼容、全功能、多类型、可渐变导航栏",
|
||||
"version": "1.2.8",
|
||||
"description": "所有属性都可自定义,兼容各端包括nvue,所有类型导航栏都可渐变,还可设置状态栏字体色;1.1.6版本后续非uni_modules版本不再更新",
|
||||
"keywords": [
|
||||
"导航栏",
|
||||
"自定义",
|
||||
"渐变",
|
||||
"状态栏",
|
||||
"多端兼容"
|
||||
],
|
||||
"displayName": "pyh-nv 全自定义、全兼容、全功能、多类型、可渐变导航栏",
|
||||
"repository": "https://github.com/Ulovely/pyh-nv",
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "u",
|
||||
"IE": "u",
|
||||
"Edge": "u",
|
||||
"Firefox": "u",
|
||||
"Safari": "u"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
}
|
||||
}
|
||||
131
uni_modules/pyh-nv/readme.md
Normal file
131
uni_modules/pyh-nv/readme.md
Normal file
@@ -0,0 +1,131 @@
|
||||
### pyh-nv 全自定义、全兼容、全功能、多类型、可渐变导航栏
|
||||
|
||||
pyh-nv 导航栏组件,组件名:``nv``,代码块: nv。
|
||||
|
||||
**使用方式:**
|
||||
|
||||
uni_modules:
|
||||
|
||||
[uni_modules使用方法](https://uniapp.dcloud.io/uni_modules?id=%e4%bd%bf%e7%94%a8-uni_modules-%e6%8f%92%e4%bb%b6);
|
||||
|
||||
uni_modules在template内的名称为pyh-nv,兼容nv写法,需要在pages.json添加代码:
|
||||
"easycom": {"nv": "@/uni_modules/pyh-nv/components/pyh-nv/pyh-nv.vue"}
|
||||
|
||||
非uni_modules:
|
||||
|
||||
复制uni_modules->pyh-nv->components->pyh-nv文件到根目录的components下
|
||||
|
||||
在 ``main.js`` 中引用组件
|
||||
|
||||
```javascript
|
||||
|
||||
import nv from "@/components/pyh-nv/pyh-nv.vue";
|
||||
Vue.component("nv",nv)
|
||||
|
||||
```
|
||||
|
||||
在 ``template`` 中使用组件
|
||||
|
||||
```html
|
||||
|
||||
<nv></nv>
|
||||
|
||||
<nv :config="{'hideback':true}"></nv>
|
||||
|
||||
<nv :config="config"></nv>
|
||||
|
||||
```
|
||||
|
||||
在 ``script`` 中 config 说明
|
||||
|
||||
所有配置都为选填,无需要可以不配置,不复杂!!!</br>
|
||||
所有配置都为选填,无需要可以不配置,不复杂!!!</br>
|
||||
所有配置都为选填,无需要可以不配置,不复杂!!!</br>
|
||||
|
||||
**config 属性说明:**
|
||||
|
||||
|属性名 |类型 |默认值 |说明 |
|
||||
|--- |---- |--- |--- |
|
||||
|title |String |'pyh-nv' |标题,默认值为getApp().globalData.NAME或组件内title写死的字符串;h5端能自动同步标签标题(比如微信标题);标题可以使用config配置修改|
|
||||
|position |String |'fixed' |定位方式,fixed和absoult都是固定定位,其它值为静态导航栏,随页面滚动 |
|
||||
|hideback |Boolean|false |是否隐藏导航栏返回功能 |
|
||||
|model |Boolean|false |是否页面内独立使用模型,如果是固定定位,top为导航栏高度 |
|
||||
|bgImage |String |'' |导航栏背景图,如果使用,则bgColor无效|
|
||||
|bgColor |String |'#ffffff' |导航栏背景色,如果使用渐变色,transparent渐变属性失效|
|
||||
|color |String |'#000000' |导航栏和状态栏字体色,也用于渐变完成时字体色(状态栏字体只支持#000000或#ffffff)|
|
||||
|componentBgColor |String |'#f8f8f8' |导航栏组件背景色(可被覆盖),如果有设置,回到首页的返回键有背景色|
|
||||
|type |String |'default' |导航栏类型(默认为通用),还有logo和search |
|
||||
|safeArea |Number |安全高度 |暂时只用于控制滚动显示,比如回到顶部 |
|
||||
|toTop |Object | |是否使用回到顶部,有该属性就是使用,详细见下方toTop说明} |
|
||||
|logo |Object | |导航栏logo的配置,仅type为logo或search时有效,详细见下方logo说明 |
|
||||
|search |Object | |导航栏含搜索框的配置,仅type为search时有效,详细见下方search说明 |
|
||||
|transparent |Object | |导航栏渐变配置,详细见下方transparent说明 |
|
||||
|fixedAssist |Object | |固定/绝对定位时辅助容器,{hide:false,bgColor:''} |
|
||||
|address |Object | |搜索导航栏左地址配置,{province:'广东省'} |
|
||||
|btn |Array |[] |导航栏右方按钮组,{text:'点击1',style:''},{icon:'',text:'',badge:{text:'1',style:''}}|
|
||||
|tabArr |Array |[] |导航栏中间tab切换,{title:'',active:true,hide:false} |
|
||||
**pyh-nv.vue 内配置说明:**
|
||||
|title |String |'pyh-nv' |标题默认值,getApp().globalData.NAME或自定义字符串 |
|
||||
|h5AutoTitle |Boolean|false |为true时而且config没传入title,h5端自动获取pages.json的navigationBarTitleText|
|
||||
|
||||
**config 内 toTop 配置说明:**
|
||||
|
||||
|属性名 |类型 |默认值 |说明 |
|
||||
|--- |---- |--- |--- |
|
||||
|duration |Number |300 |回到顶部的滚动动画时间(ms) |
|
||||
|style |String |'' |样式配置 |
|
||||
|
||||
**config 内 logo 配置说明:**
|
||||
|
||||
|属性名 |类型 |默认值 |说明 |
|
||||
|--- |---- |--- |--- |
|
||||
|src |String |'/static/logo.png' |logo路径 |
|
||||
|url |String |'' |如果传值,点击logo会reLaunch到该url |
|
||||
|style |String |'' |样式配置 |
|
||||
|
||||
**config 内 search 配置说明:**
|
||||
|
||||
|属性名 |类型 |默认值 |说明 |
|
||||
|--- |---- |--- |--- |
|
||||
|value |String |'' |input的初始值,如需动态赋值,必须初始化 |
|
||||
|bgColor |String |'#f8f8f8' |组件背景色,覆盖 componentBgColor |
|
||||
|input |Boolean|false |输入框提示语样式 |
|
||||
|url |String |'' |input为false时生效,点击navigateTo到url |
|
||||
|focus |Boolean|false |是否自动聚焦 |
|
||||
|border |String |'' |输入框边框样式 |
|
||||
|placeholder |String |'搜索' |输入框提示语 |
|
||||
|placeholderStyle |String |'' |输入框提示语样式 |
|
||||
|btn |Object | |input为true时生效,搜索框提交按钮,{text:'搜索',style:''} |
|
||||
|confirmType |String |'search' |同官方input的confirm-type,设置回车键文字 |
|
||||
|
||||
**config 内 transparent 配置说明:**
|
||||
|
||||
|属性名 |类型 |默认值 |说明 |
|
||||
|--- |---- |--- |--- |
|
||||
|type |String |'background' |渐变类型,content为全透明渐变 |
|
||||
|anchor |Number |当前导航栏高度 |最终渐变位置 |
|
||||
|initColor |String |'#ffffff' |导航栏与状态栏初始色,(状态栏字体只支持#000000或#ffffff) |
|
||||
|
||||
|
||||
**组件pyh-nv 事件说明(详情请参考示例项目):**
|
||||
|
||||
|属名 |说明 |
|
||||
|--- |---- |
|
||||
|nvLogoTap |点击logo,仅logo存在时生效 |
|
||||
|nvAddressTap |点击地址,仅地址存在时生效 |
|
||||
|nvInput |输入框input事件,仅search.input为true时生效 |
|
||||
|nvFormSubmit |输入框确认事件,仅search.input为true时生效 |
|
||||
|nvBtnTap |右方按钮组点击事件,仅右方按钮存在时生效 |
|
||||
|nvTabTap |中间tab组点击事件,仅中间tab按钮存在时生效 |
|
||||
|
||||
|
||||
**ref 事件说明(详情请参考示例项目):**
|
||||
|
||||
|事件名 |参数类型 |参数默认值 |说明 |
|
||||
|--- |---- |---- |---
|
||||
|setStyle |Object |{} |直接设置导航栏样式 |
|
||||
|pageScroll |Object |{scrollTop:0} |传递页面滚动信息 |
|
||||
|
||||
**感谢:**
|
||||
|
||||
> 有更多优化建议和需求,请联系作者 panyh 。谢谢!
|
||||
8
uni_modules/uni-fab/changelog.md
Normal file
8
uni_modules/uni-fab/changelog.md
Normal file
@@ -0,0 +1,8 @@
|
||||
## 1.1.0(2021-07-30)
|
||||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
## 1.0.7(2021-05-12)
|
||||
- 新增 组件示例地址
|
||||
## 1.0.6(2021-02-05)
|
||||
- 调整为uni_modules目录规范
|
||||
- 优化 按钮背景色调整
|
||||
- 优化 兼容pc端
|
||||
448
uni_modules/uni-fab/components/uni-fab/uni-fab.vue
Normal file
448
uni_modules/uni-fab/components/uni-fab/uni-fab.vue
Normal file
@@ -0,0 +1,448 @@
|
||||
<template>
|
||||
<view class="uni-cursor-point">
|
||||
<view v-if="popMenu && (leftBottom||rightBottom||leftTop||rightTop) && content.length > 0" :class="{
|
||||
'uni-fab--leftBottom': leftBottom,
|
||||
'uni-fab--rightBottom': rightBottom,
|
||||
'uni-fab--leftTop': leftTop,
|
||||
'uni-fab--rightTop': rightTop
|
||||
}"
|
||||
class="uni-fab">
|
||||
<view :class="{
|
||||
'uni-fab__content--left': horizontal === 'left',
|
||||
'uni-fab__content--right': horizontal === 'right',
|
||||
'uni-fab__content--flexDirection': direction === 'vertical',
|
||||
'uni-fab__content--flexDirectionStart': flexDirectionStart,
|
||||
'uni-fab__content--flexDirectionEnd': flexDirectionEnd,
|
||||
'uni-fab__content--other-platform': !isAndroidNvue
|
||||
}"
|
||||
:style="{ width: boxWidth, height: boxHeight, backgroundColor: styles.backgroundColor }" class="uni-fab__content"
|
||||
elevation="5">
|
||||
<view v-if="flexDirectionStart || horizontalLeft" class="uni-fab__item uni-fab__item--first" />
|
||||
<view v-for="(item, index) in content" :key="index" :class="{ 'uni-fab__item--active': isShow }" class="uni-fab__item"
|
||||
@click="_onItemClick(index, item)">
|
||||
<image :src="item.active ? item.selectedIconPath : item.iconPath" class="uni-fab__item-image" mode="widthFix" />
|
||||
<text class="uni-fab__item-text" :style="{ color: item.active ? styles.selectedColor : styles.color }">{{ item.text }}</text>
|
||||
</view>
|
||||
<view v-if="flexDirectionEnd || horizontalRight" class="uni-fab__item uni-fab__item--first" />
|
||||
</view>
|
||||
</view>
|
||||
<view :class="{
|
||||
'uni-fab__circle--leftBottom': leftBottom,
|
||||
'uni-fab__circle--rightBottom': rightBottom,
|
||||
'uni-fab__circle--leftTop': leftTop,
|
||||
'uni-fab__circle--rightTop': rightTop,
|
||||
'uni-fab__content--other-platform': !isAndroidNvue
|
||||
}"
|
||||
class="uni-fab__circle uni-fab__plus" :style="{ 'background-color': styles.buttonColor }" @click="_onClick">
|
||||
<view class="fab-circle-v" :class="{'uni-fab__plus--active': isShow && content.length > 0}"></view>
|
||||
<view class="fab-circle-h" :class="{'uni-fab__plus--active': isShow && content.length > 0}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let platform = 'other'
|
||||
// #ifdef APP-NVUE
|
||||
platform = uni.getSystemInfoSync().platform
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* Fab 悬浮按钮
|
||||
* @description 点击可展开一个图形按钮菜单
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=144
|
||||
* @property {Object} pattern 可选样式配置项
|
||||
* @property {Object} horizontal = [left | right] 水平对齐方式
|
||||
* @value left 左对齐
|
||||
* @value right 右对齐
|
||||
* @property {Object} vertical = [bottom | top] 垂直对齐方式
|
||||
* @value bottom 下对齐
|
||||
* @value top 上对齐
|
||||
* @property {Object} direction = [horizontal | vertical] 展开菜单显示方式
|
||||
* @value horizontal 水平显示
|
||||
* @value vertical 垂直显示
|
||||
* @property {Array} content 展开菜单内容配置项
|
||||
* @property {Boolean} popMenu 是否使用弹出菜单
|
||||
* @event {Function} trigger 展开菜单点击事件,返回点击信息
|
||||
* @event {Function} fabClick 悬浮按钮点击事件
|
||||
*/
|
||||
export default {
|
||||
name: 'UniFab',
|
||||
emits:['fabClick','trigger'],
|
||||
props: {
|
||||
pattern: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
horizontal: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
vertical: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'horizontal'
|
||||
},
|
||||
content: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
popMenu: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fabShow: false,
|
||||
isShow: false,
|
||||
isAndroidNvue: platform === 'android',
|
||||
styles: {
|
||||
color: '#3c3e49',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#fff',
|
||||
buttonColor: '#007AFF'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
contentWidth(e) {
|
||||
return (this.content.length + 1) * 55 + 10 + 'px'
|
||||
},
|
||||
contentWidthMin() {
|
||||
return 55 + 'px'
|
||||
},
|
||||
// 动态计算宽度
|
||||
boxWidth() {
|
||||
return this.getPosition(3, 'horizontal')
|
||||
},
|
||||
// 动态计算高度
|
||||
boxHeight() {
|
||||
return this.getPosition(3, 'vertical')
|
||||
},
|
||||
// 计算左下位置
|
||||
leftBottom() {
|
||||
return this.getPosition(0, 'left', 'bottom')
|
||||
},
|
||||
// 计算右下位置
|
||||
rightBottom() {
|
||||
return this.getPosition(0, 'right', 'bottom')
|
||||
},
|
||||
// 计算左上位置
|
||||
leftTop() {
|
||||
return this.getPosition(0, 'left', 'top')
|
||||
},
|
||||
rightTop() {
|
||||
return this.getPosition(0, 'right', 'top')
|
||||
},
|
||||
flexDirectionStart() {
|
||||
return this.getPosition(1, 'vertical', 'top')
|
||||
},
|
||||
flexDirectionEnd() {
|
||||
return this.getPosition(1, 'vertical', 'bottom')
|
||||
},
|
||||
horizontalLeft() {
|
||||
return this.getPosition(2, 'horizontal', 'left')
|
||||
},
|
||||
horizontalRight() {
|
||||
return this.getPosition(2, 'horizontal', 'right')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pattern(newValue, oldValue) {
|
||||
//console.log(JSON.stringify(newValue))
|
||||
this.styles = Object.assign({}, this.styles, newValue)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isShow = this.show
|
||||
if (this.top === 0) {
|
||||
this.fabShow = true
|
||||
}
|
||||
// 初始化样式
|
||||
this.styles = Object.assign({}, this.styles, this.pattern)
|
||||
},
|
||||
methods: {
|
||||
_onClick() {
|
||||
this.$emit('fabClick')
|
||||
if (!this.popMenu) {
|
||||
return
|
||||
}
|
||||
this.isShow = !this.isShow
|
||||
},
|
||||
open() {
|
||||
this.isShow = true
|
||||
},
|
||||
close() {
|
||||
this.isShow = false
|
||||
},
|
||||
/**
|
||||
* 按钮点击事件
|
||||
*/
|
||||
_onItemClick(index, item) {
|
||||
this.$emit('trigger', {
|
||||
index,
|
||||
item
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取 位置信息
|
||||
*/
|
||||
getPosition(types, paramA, paramB) {
|
||||
if (types === 0) {
|
||||
return this.horizontal === paramA && this.vertical === paramB
|
||||
} else if (types === 1) {
|
||||
return this.direction === paramA && this.vertical === paramB
|
||||
} else if (types === 2) {
|
||||
return this.direction === paramA && this.horizontal === paramB
|
||||
} else {
|
||||
return this.isShow && this.direction === paramA ? this.contentWidth : this.contentWidthMin
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uni-fab {
|
||||
position: fixed;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.uni-cursor-point {
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-fab--active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.uni-fab--leftBottom {
|
||||
left: 5px;
|
||||
bottom: 20px;
|
||||
/* #ifdef H5 */
|
||||
left: calc(5px + var(--window-left));
|
||||
bottom: calc(20px + var(--window-bottom));
|
||||
/* #endif */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.uni-fab--leftTop {
|
||||
left: 5px;
|
||||
top: 30px;
|
||||
/* #ifdef H5 */
|
||||
left: calc(5px + var(--window-left));
|
||||
top: calc(30px + var(--window-top));
|
||||
/* #endif */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.uni-fab--rightBottom {
|
||||
right: 5px;
|
||||
bottom: 20px;
|
||||
/* #ifdef H5 */
|
||||
right: calc(5px + var(--window-right));
|
||||
bottom: calc(20px + var(--window-bottom));
|
||||
/* #endif */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.uni-fab--rightTop {
|
||||
right: 5px;
|
||||
top: 30px;
|
||||
/* #ifdef H5 */
|
||||
right: calc(5px + var(--window-right));
|
||||
top: calc(30px + var(--window-top));
|
||||
/* #endif */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.uni-fab__circle {
|
||||
position: fixed;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
background-color: #3c3e49;
|
||||
border-radius: 55px;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.uni-fab__circle--leftBottom {
|
||||
left: 15px;
|
||||
bottom: 30px;
|
||||
/* #ifdef H5 */
|
||||
left: calc(15px + var(--window-left));
|
||||
bottom: calc(30px + var(--window-bottom));
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-fab__circle--leftTop {
|
||||
left: 15px;
|
||||
top: 40px;
|
||||
/* #ifdef H5 */
|
||||
left: calc(15px + var(--window-left));
|
||||
top: calc(40px + var(--window-top));
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-fab__circle--rightBottom {
|
||||
right: 15px;
|
||||
bottom: 30px;
|
||||
/* #ifdef H5 */
|
||||
right: calc(15px + var(--window-right));
|
||||
bottom: calc(30px + var(--window-bottom));
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-fab__circle--rightTop {
|
||||
right: 15px;
|
||||
top: 40px;
|
||||
/* #ifdef H5 */
|
||||
right: calc(15px + var(--window-right));
|
||||
top: calc(40px + var(--window-top));
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-fab__circle--left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.uni-fab__circle--right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.uni-fab__circle--top {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.uni-fab__circle--bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.uni-fab__plus {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fab-circle-v {
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
height: 31px;
|
||||
left: 26px;
|
||||
top: 12px;
|
||||
background-color: white;
|
||||
transform: rotate(0deg);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.fab-circle-h {
|
||||
position: absolute;
|
||||
width: 31px;
|
||||
height: 3px;
|
||||
left: 12px;
|
||||
top: 26px;
|
||||
background-color: white;
|
||||
transform: rotate(0deg);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.uni-fab__plus--active {
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.uni-fab__content {
|
||||
/* #ifndef APP-NVUE */
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
border-radius: 55px;
|
||||
overflow: hidden;
|
||||
transition-property: width, height;
|
||||
transition-duration: 0.2s;
|
||||
width: 55px;
|
||||
border-color: #DDDDDD;
|
||||
border-width: 1rpx;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.uni-fab__content--other-platform {
|
||||
border-width: 0px;
|
||||
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.uni-fab__content--left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.uni-fab__content--right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.uni-fab__content--flexDirection {
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.uni-fab__content--flexDirectionStart {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.uni-fab__content--flexDirectionEnd {
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.uni-fab__item {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.uni-fab__item--active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.uni-fab__item-image {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.uni-fab__item-text {
|
||||
color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.uni-fab__item--first {
|
||||
width: 55px;
|
||||
}
|
||||
</style>
|
||||
383
uni_modules/uni-fab/components/uni-fab/uni-fab.vue.bak
Normal file
383
uni_modules/uni-fab/components/uni-fab/uni-fab.vue.bak
Normal file
@@ -0,0 +1,383 @@
|
||||
<template>
|
||||
<view>
|
||||
<view :class="{
|
||||
leftBottom: leftBottom,
|
||||
rightBottom: rightBottom,
|
||||
leftTop: leftTop,
|
||||
rightTop: rightTop
|
||||
}" v-if="leftBottom||rightBottom||leftTop||rightTop" class="fab-box fab">
|
||||
<view :class="{
|
||||
left: horizontal === 'left' && direction === 'horizontal',
|
||||
top: vertical === 'top' && direction === 'vertical',
|
||||
bottom: vertical === 'bottom' && direction === 'vertical',
|
||||
right: horizontal === 'right' && direction === 'horizontal'
|
||||
}" :style="{ 'background-color': styles.buttonColor }" class="fab-circle" @click="_onClick">
|
||||
<view class="fab-circle-box" :class="{ active: isShow }">
|
||||
<view class="fab-circle-v"></view>
|
||||
<view class="fab-circle-h"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view :class="{
|
||||
left: horizontal === 'left',
|
||||
right: horizontal === 'right',
|
||||
flexDirection: direction === 'vertical',
|
||||
flexDirectionStart: flexDirectionStart,
|
||||
flexDirectionEnd: flexDirectionEnd
|
||||
}" :style="{ width: boxWidth, height: boxHeight, background: styles.backgroundColor }" class="fab-content">
|
||||
<view v-if="flexDirectionStart || horizontalLeft" class="fab-item first" />
|
||||
<view v-for="(item, index) in content" :key="index" :class="{ active: isShow }" :style="{
|
||||
color: item.active ? styles.selectedColor : styles.color
|
||||
}" class="fab-item" @click="_onItemClick(index, item)">
|
||||
<image :src="item.active ? item.selectedIconPath : item.iconPath" class="content-image" mode="widthFix" />
|
||||
<text class="text">{{ item.text }}</text>
|
||||
</view>
|
||||
<view v-if="flexDirectionEnd || horizontalRight" class="fab-item first" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniIcons from "../uni-icons/uni-icons.vue";
|
||||
export default {
|
||||
name: 'UniFab',
|
||||
components:{
|
||||
uniIcons
|
||||
},
|
||||
props: {
|
||||
pattern: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
horizontal: {
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
vertical: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'horizontal'
|
||||
},
|
||||
content: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fabShow: false,
|
||||
flug: true,
|
||||
isShow: false,
|
||||
styles: {
|
||||
color: '#3c3e49',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#fff',
|
||||
buttonColor: '#3c3e49'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
contentWidth(e) {
|
||||
return uni.upx2px((this.content.length + 1) * 110 + 20) + 'px'
|
||||
},
|
||||
contentWidthMin() {
|
||||
return uni.upx2px(110) + 'px'
|
||||
},
|
||||
// 动态计算宽度
|
||||
boxWidth() {
|
||||
return this.getPosition(3, 'horizontal')
|
||||
},
|
||||
// 动态计算高度
|
||||
boxHeight() {
|
||||
return this.getPosition(3, 'vertical')
|
||||
},
|
||||
// 计算左下位置
|
||||
leftBottom() {
|
||||
return this.getPosition(0, 'left', 'bottom')
|
||||
},
|
||||
// 计算右下位置
|
||||
rightBottom() {
|
||||
return this.getPosition(0, 'right', 'bottom')
|
||||
},
|
||||
// 计算左上位置
|
||||
leftTop() {
|
||||
return this.getPosition(0, 'left', 'top')
|
||||
},
|
||||
rightTop() {
|
||||
return this.getPosition(0, 'right', 'top')
|
||||
},
|
||||
flexDirectionStart() {
|
||||
return this.getPosition(1, 'vertical', 'top')
|
||||
},
|
||||
flexDirectionEnd() {
|
||||
return this.getPosition(1, 'vertical', 'bottom')
|
||||
},
|
||||
horizontalLeft() {
|
||||
return this.getPosition(2, 'horizontal', 'left')
|
||||
},
|
||||
horizontalRight() {
|
||||
return this.getPosition(2, 'horizontal', 'right')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pattern(newValue, oldValue) {
|
||||
//console.log(JSON.stringify(newValue))
|
||||
this.styles = Object.assign({}, this.styles, newValue)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isShow = this.show
|
||||
if (this.top === 0) {
|
||||
this.fabShow = true
|
||||
}
|
||||
// 初始化样式
|
||||
this.styles = Object.assign({}, this.styles, this.pattern)
|
||||
},
|
||||
methods: {
|
||||
_onClick() {
|
||||
this.isShow = !this.isShow
|
||||
},
|
||||
open() {
|
||||
this.isShow = true
|
||||
},
|
||||
close() {
|
||||
this.isShow = false
|
||||
},
|
||||
/**
|
||||
* 按钮点击事件
|
||||
*/
|
||||
_onItemClick(index, item) {
|
||||
this.$emit('trigger', {
|
||||
index,
|
||||
item
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取 位置信息
|
||||
*/
|
||||
getPosition(types, paramA, paramB) {
|
||||
if (types === 0) {
|
||||
return this.horizontal === paramA && this.vertical === paramB
|
||||
} else if (types === 1) {
|
||||
return this.direction === paramA && this.vertical === paramB
|
||||
} else if (types === 2) {
|
||||
return this.direction === paramA && this.horizontal === paramB
|
||||
} else {
|
||||
return this.isShow && this.direction === paramA ? this.contentWidth : this.contentWidthMin
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.uni-icon {
|
||||
font-family: uniicons;
|
||||
font-size: 30px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.fab-box {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.fab-box.top {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
right: 30rpx;
|
||||
bottom: 60rpx;
|
||||
border: 1px #5989b9 solid;
|
||||
background: #6699cc;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
transition: all 0.3;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fab-box.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fab-box.fab {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.fab-box.fab.leftBottom {
|
||||
left: 30rpx;
|
||||
bottom: 60rpx;
|
||||
}
|
||||
|
||||
.fab-box.fab.leftTop {
|
||||
left: 30rpx;
|
||||
top: 80rpx;
|
||||
/* #ifdef H5 */
|
||||
top: calc(80rpx + var(--window-top));
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fab-box.fab.rightBottom {
|
||||
right: 30rpx;
|
||||
bottom: 60rpx;
|
||||
}
|
||||
|
||||
.fab-box.fab.rightTop {
|
||||
right: 30rpx;
|
||||
top: 80rpx;
|
||||
/* #ifdef H5 */
|
||||
top: calc(80rpx + var(--window-top));
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.fab-circle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
background: #3c3e49;
|
||||
/* background: #5989b9; */
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.2);
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.fab-circle-box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.fab-circle-v {
|
||||
position: absolute;
|
||||
width: 8rpx;
|
||||
height: 60rpx;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin: -30rpx 0 0 -4rpx;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.fab-circle-h {
|
||||
position: absolute;
|
||||
width: 60rpx;
|
||||
height: 8rpx;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin: -4rpx 0 0 -30rpx;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.fab-circle.left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.fab-circle.right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.fab-circle.top {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.fab-circle.bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.fab-circle .uni-icon-plusempty {
|
||||
color: #ffffff;
|
||||
font-size: 80rpx;
|
||||
transition: all 0.3s;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fab-circle-box.active {
|
||||
transform: rotate(135deg);
|
||||
font-size: 80rpx;
|
||||
}
|
||||
|
||||
.fab-content {
|
||||
background: #6699cc;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
border-radius: 100rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s;
|
||||
width: 110rpx;
|
||||
}
|
||||
|
||||
.fab-content.left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.fab-content.right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.fab-content.flexDirection {
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.fab-content.flexDirectionStart {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.fab-content.flexDirectionEnd {
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.fab-content .fab-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.fab-content .fab-item.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fab-content .fab-item .content-image {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.fab-content .fab-item.first {
|
||||
width: 110rpx;
|
||||
}
|
||||
</style>
|
||||
83
uni_modules/uni-fab/package.json
Normal file
83
uni_modules/uni-fab/package.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"id": "uni-fab",
|
||||
"displayName": "uni-fab 悬浮按钮",
|
||||
"version": "1.1.0",
|
||||
"description": "悬浮按钮 fab button ,点击可展开一个图标按钮菜单。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"按钮",
|
||||
"悬浮按钮",
|
||||
"fab"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
uni_modules/uni-fab/readme.md
Normal file
91
uni_modules/uni-fab/readme.md
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
|
||||
## Fab 悬浮按钮
|
||||
> **组件名:uni-fab**
|
||||
> 代码块: `uFab`
|
||||
|
||||
|
||||
点击可展开一个图形按钮菜单
|
||||
|
||||
### 安装方式
|
||||
|
||||
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
|
||||
|
||||
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
|
||||
|
||||
> **注意事项**
|
||||
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
|
||||
> - 不建议动态修改属性,可能会耗损部分性能。
|
||||
> - 展开菜单暂不支持字体图标,使用图片路径时建议使用绝对路径,相对路径可能会有问题。
|
||||
> - 选中状态要通过自己控制,如果不希望有选中状态,不处理 `active` 即可。
|
||||
> - 展开菜单建议最多显示四个,如果过多对于小屏手机可能会超出屏幕。
|
||||
|
||||
|
||||
### 基本用法
|
||||
|
||||
在 `template` 中使用组件
|
||||
|
||||
```html
|
||||
<template>
|
||||
<view>
|
||||
<uni-fab
|
||||
:pattern="pattern"
|
||||
:content="content"
|
||||
:horizontal="horizontal"
|
||||
:vertical="vertical"
|
||||
:direction="direction"
|
||||
@trigger="trigger"
|
||||
></uni-fab>
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Fab Props
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| pattern | Object | - | 可选样式配置项 |
|
||||
| horizontal| String | 'left' | 水平对齐方式。`left`:左对齐,`right`:右对齐 |
|
||||
| vertical | String | 'bottom' | 垂直对齐方式。`bottom`:下对齐,`top`:上对齐 |
|
||||
| direction | String | 'horizontal' | 展开菜单显示方式。`horizontal`:水平显示,`vertical`:垂直显示 |
|
||||
| popMenu | Boolean | true | 是否使用弹出菜单 |
|
||||
| content | Array | - | 展开菜单内容配置项 |
|
||||
|
||||
|
||||
|
||||
**pattern配置项:**
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| color | String | #3c3e49 | 文字默认颜色 |
|
||||
| selectedColor | String | #007AFF | 文字选中时的颜色 |
|
||||
| backgroundColor | String | #ffffff | 背景色 |
|
||||
| buttonColor | String | #3c3e49 | 按钮背景色 |
|
||||
|
||||
**content配置项:**
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| :-: | :-: | :-: | :-: |
|
||||
| iconPath | String | 图片路径 |
|
||||
| selectedIconPath | String | 选中后图片路径|
|
||||
| text | String | 文字 |
|
||||
| active | Boolean | 是否选中当前 |
|
||||
|
||||
### Fab Events
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
| :-: | :-: | :-: |
|
||||
| @trigger | Function | 展开菜单点击事件,返回点击信息|
|
||||
| @fabClick | Function | 悬浮按钮点击事件 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 组件示例
|
||||
|
||||
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/fab/fab](https://hellouniapp.dcloud.net.cn/pages/extUI/fab/fab)
|
||||
10
uni_modules/uni-load-more/changelog.md
Normal file
10
uni_modules/uni-load-more/changelog.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 1.2.1(2021-08-24)
|
||||
- 新增 支持国际化
|
||||
## 1.2.0(2021-07-30)
|
||||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
## 1.1.8(2021-05-12)
|
||||
- 新增 组件示例地址
|
||||
## 1.1.7(2021-03-30)
|
||||
- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
|
||||
## 1.1.6(2021-02-05)
|
||||
- 调整为uni_modules目录规范
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"uni-load-more.contentdown": "Pull up to show more",
|
||||
"uni-load-more.contentrefresh": "loading...",
|
||||
"uni-load-more.contentnomore": "No more data"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import en from './en.json'
|
||||
import zhHans from './zh-Hans.json'
|
||||
import zhHant from './zh-Hant.json'
|
||||
export default {
|
||||
en,
|
||||
'zh-Hans': zhHans,
|
||||
'zh-Hant': zhHant
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"uni-load-more.contentdown": "上拉显示更多",
|
||||
"uni-load-more.contentrefresh": "正在加载...",
|
||||
"uni-load-more.contentnomore": "没有更多数据了"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"uni-load-more.contentdown": "上拉顯示更多",
|
||||
"uni-load-more.contentrefresh": "正在加載...",
|
||||
"uni-load-more.contentnomore": "沒有更多數據了"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
86
uni_modules/uni-load-more/package.json
Normal file
86
uni_modules/uni-load-more/package.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"id": "uni-load-more",
|
||||
"displayName": "uni-load-more 加载更多",
|
||||
"version": "1.2.1",
|
||||
"description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"加载更多",
|
||||
"load-more"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
uni_modules/uni-load-more/readme.md
Normal file
70
uni_modules/uni-load-more/readme.md
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
### LoadMore 加载更多
|
||||
> **组件名:uni-load-more**
|
||||
> 代码块: `uLoadMore`
|
||||
|
||||
|
||||
用于列表中,做滚动加载使用,展示 loading 的各种状态。
|
||||
|
||||
### 安装方式
|
||||
|
||||
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
|
||||
|
||||
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
|
||||
|
||||
### 使用方式
|
||||
|
||||
在 ``template`` 中使用组件
|
||||
|
||||
```html
|
||||
<uni-load-more :status="more"></uni-load-more>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### LoadMore Props
|
||||
|
||||
|属性名 |类型 | 可选值 |默认值 |说明 |
|
||||
|:-: |:-: |:-: |:-: |:-: |
|
||||
|iconSize |Number |- |24 |指定图标大小 |
|
||||
|status |String |more/loading/noMore |more |loading 的状态 |
|
||||
|showIcon |Boolean|- |true |是否显示 loading 图标 |
|
||||
|iconType |String |snow/circle/auto |auto |指定图标样式|
|
||||
|color |String |- |#777777 |图标和文字颜色 |
|
||||
|contentText|Object|- |{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}|各状态文字说明 |
|
||||
|
||||
|
||||
#### Status Options
|
||||
|参数名称 |说明 |
|
||||
|:-: |:-: |
|
||||
|more |loading前 |
|
||||
|loading|loading前中 |
|
||||
|more |没有更多数据 |
|
||||
|
||||
#### IconType Options
|
||||
|参数名称 |说明 |
|
||||
|:-: |:-: |
|
||||
|snow |ios雪花加载样式 |
|
||||
|circle |安卓环形加载样式 |
|
||||
|auto |根据平台自动选择加载样式 |
|
||||
|
||||
|
||||
|
||||
|
||||
> **说明**
|
||||
> `iconType`为`snow`时,在`APP-NVUE`平台不可设置大小,在非`APP-NVUE`平台不可设置颜色
|
||||
|
||||
|
||||
|
||||
### 事件说明
|
||||
|
||||
|事件名 |说明 |返回值 |
|
||||
|:-: |:-: |:-: |
|
||||
|clickLoadMore |点击加载更多时触发 |e.detail={status:'loading'}|
|
||||
|
||||
|
||||
|
||||
## 组件示例
|
||||
|
||||
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/load-more/load-more](https://hellouniapp.dcloud.net.cn/pages/extUI/load-more/load-more)
|
||||
20
uni_modules/uni-rate/changelog.md
Normal file
20
uni_modules/uni-rate/changelog.md
Normal file
@@ -0,0 +1,20 @@
|
||||
## 1.2.2(2021-09-10)
|
||||
- 优化 默认值修改为 0 颗星
|
||||
## 1.2.1(2021-07-30)
|
||||
- 优化 vue3下事件警告的问题
|
||||
## 1.2.0(2021-07-13)
|
||||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
## 1.1.2(2021-05-12)
|
||||
- 新增 组件示例地址
|
||||
## 1.1.1(2021-04-21)
|
||||
- 修复 布局变化后 uni-rate 星星计算不准确的 bug
|
||||
- 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
|
||||
## 1.1.0(2021-04-16)
|
||||
- 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
|
||||
|
||||
## 1.0.9(2021-02-05)
|
||||
- 优化 组件引用关系,通过uni_modules引用组件
|
||||
|
||||
## 1.0.8(2021-02-05)
|
||||
- 调整为uni_modules目录规范
|
||||
- 支持 pc 端
|
||||
393
uni_modules/uni-rate/components/uni-rate/uni-rate.vue
Normal file
393
uni_modules/uni-rate/components/uni-rate/uni-rate.vue
Normal file
@@ -0,0 +1,393 @@
|
||||
<template>
|
||||
<view>
|
||||
<view
|
||||
ref="uni-rate"
|
||||
class="uni-rate"
|
||||
>
|
||||
<view
|
||||
class="uni-rate__icon"
|
||||
:class="{'uni-cursor-not-allowed': disabled}"
|
||||
:style="{ 'margin-right': marginNumber + 'px' }"
|
||||
v-for="(star, index) in stars"
|
||||
:key="index"
|
||||
@touchstart.stop="touchstart"
|
||||
@touchmove.stop="touchmove"
|
||||
@mousedown.stop="mousedown"
|
||||
@mousemove.stop="mousemove"
|
||||
@mouseleave="mouseleave"
|
||||
>
|
||||
<uni-icons
|
||||
:color="color"
|
||||
:size="size"
|
||||
:type="isFill ? 'star-filled' : 'star'"
|
||||
/>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<view
|
||||
:style="{ width: star.activeWitch.replace('%','')*size/100+'px'}"
|
||||
class="uni-rate__icon-on"
|
||||
>
|
||||
<uni-icons
|
||||
style="text-align: left;"
|
||||
:color="disabled?'#ccc':activeColor"
|
||||
:size="size"
|
||||
type="star-filled"
|
||||
/>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<view
|
||||
:style="{ width: star.activeWitch}"
|
||||
class="uni-rate__icon-on"
|
||||
>
|
||||
<uni-icons
|
||||
:color="disabled?disabledColor:activeColor"
|
||||
:size="size"
|
||||
type="star-filled"
|
||||
/>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-NVUE
|
||||
const dom = uni.requireNativePlugin('dom');
|
||||
// #endif
|
||||
/**
|
||||
* Rate 评分
|
||||
* @description 评分组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=33
|
||||
* @property {Boolean} isFill = [true|false] 星星的类型,是否为实心类型, 默认为实心
|
||||
* @property {String} color 未选中状态的星星颜色,默认为 "#ececec"
|
||||
* @property {String} activeColor 选中状态的星星颜色,默认为 "#ffca3e"
|
||||
* @property {String} disabledColor 禁用状态的星星颜色,默认为 "#c0c0c0"
|
||||
* @property {Number} size 星星的大小
|
||||
* @property {Number} value/v-model 当前评分
|
||||
* @property {Number} max 最大评分评分数量,目前一分一颗星
|
||||
* @property {Number} margin 星星的间距,单位 px
|
||||
* @property {Boolean} disabled = [true|false] 是否为禁用状态,默认为 false
|
||||
* @property {Boolean} readonly = [true|false] 是否为只读状态,默认为 false
|
||||
* @property {Boolean} allowHalf = [true|false] 是否实现半星,默认为 false
|
||||
* @property {Boolean} touchable = [true|false] 是否支持滑动手势,默认为 true
|
||||
* @event {Function} change uniRate 的 value 改变时触发事件,e={value:Number}
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "UniRate",
|
||||
props: {
|
||||
isFill: {
|
||||
// 星星的类型,是否镂空
|
||||
type: [Boolean, String],
|
||||
default: true
|
||||
},
|
||||
color: {
|
||||
// 星星未选中的颜色
|
||||
type: String,
|
||||
default: "#ececec"
|
||||
},
|
||||
activeColor: {
|
||||
// 星星选中状态颜色
|
||||
type: String,
|
||||
default: "#ffca3e"
|
||||
},
|
||||
disabledColor: {
|
||||
// 星星禁用状态颜色
|
||||
type: String,
|
||||
default: "#c0c0c0"
|
||||
},
|
||||
size: {
|
||||
// 星星的大小
|
||||
type: [Number, String],
|
||||
default: 24
|
||||
},
|
||||
value: {
|
||||
// 当前评分
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
modelValue: {
|
||||
// 当前评分
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
// 最大评分
|
||||
type: [Number, String],
|
||||
default: 5
|
||||
},
|
||||
margin: {
|
||||
// 星星的间距
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
disabled: {
|
||||
// 是否可点击
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
// 是否只读
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
allowHalf: {
|
||||
// 是否显示半星
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
touchable: {
|
||||
// 是否支持滑动手势
|
||||
type: [Boolean, String],
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
valueSync: "",
|
||||
userMouseFristMove: true,
|
||||
userRated: false,
|
||||
userLastRate: 1
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(newVal) {
|
||||
this.valueSync = Number(newVal);
|
||||
},
|
||||
modelValue(newVal) {
|
||||
this.valueSync = Number(newVal);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
stars() {
|
||||
const value = this.valueSync ? this.valueSync : 0;
|
||||
const starList = [];
|
||||
const floorValue = Math.floor(value);
|
||||
const ceilValue = Math.ceil(value);
|
||||
for (let i = 0; i < this.max; i++) {
|
||||
if (floorValue > i) {
|
||||
starList.push({
|
||||
activeWitch: "100%"
|
||||
});
|
||||
} else if (ceilValue - 1 === i) {
|
||||
starList.push({
|
||||
activeWitch: (value - floorValue) * 100 + "%"
|
||||
});
|
||||
} else {
|
||||
starList.push({
|
||||
activeWitch: "0"
|
||||
});
|
||||
}
|
||||
}
|
||||
return starList;
|
||||
},
|
||||
|
||||
marginNumber() {
|
||||
return Number(this.margin)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.valueSync = Number(this.value||this.modelValue);
|
||||
this._rateBoxLeft = 0
|
||||
this._oldValue = null
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this._getSize()
|
||||
}, 100)
|
||||
// #ifdef H5
|
||||
this.PC = this.IsPC()
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
touchstart(e) {
|
||||
// #ifdef H5
|
||||
if( this.IsPC() ) return
|
||||
// #endif
|
||||
if (this.readonly || this.disabled) return
|
||||
const {
|
||||
clientX,
|
||||
screenX
|
||||
} = e.changedTouches[0]
|
||||
// TODO 做一下兼容,只有 Nvue 下才有 screenX,其他平台式 clientX
|
||||
this._getRateCount(clientX || screenX)
|
||||
},
|
||||
touchmove(e) {
|
||||
// #ifdef H5
|
||||
if( this.IsPC() ) return
|
||||
// #endif
|
||||
if (this.readonly || this.disabled || !this.touchable) return
|
||||
const {
|
||||
clientX,
|
||||
screenX
|
||||
} = e.changedTouches[0]
|
||||
this._getRateCount(clientX || screenX)
|
||||
},
|
||||
|
||||
/**
|
||||
* 兼容 PC @tian
|
||||
*/
|
||||
|
||||
mousedown(e) {
|
||||
// #ifdef H5
|
||||
if( !this.IsPC() ) return
|
||||
if (this.readonly || this.disabled) return
|
||||
const {
|
||||
clientX,
|
||||
} = e
|
||||
this.userLastRate = this.valueSync
|
||||
this._getRateCount(clientX)
|
||||
this.userRated = true
|
||||
// #endif
|
||||
},
|
||||
mousemove(e) {
|
||||
// #ifdef H5
|
||||
if( !this.IsPC() ) return
|
||||
if( this.userRated ) return
|
||||
if( this.userMouseFristMove ) {
|
||||
console.log('---mousemove----', this.valueSync);
|
||||
this.userLastRate = this.valueSync
|
||||
this.userMouseFristMove = false
|
||||
}
|
||||
if (this.readonly || this.disabled || !this.touchable) return
|
||||
const {
|
||||
clientX,
|
||||
} = e
|
||||
this._getRateCount(clientX)
|
||||
// #endif
|
||||
},
|
||||
mouseleave(e) {
|
||||
// #ifdef H5
|
||||
if( !this.IsPC() ) return
|
||||
if (this.readonly || this.disabled || !this.touchable) return
|
||||
if( this.userRated ) {
|
||||
this.userRated = false
|
||||
return
|
||||
}
|
||||
this.valueSync = this.userLastRate
|
||||
// #endif
|
||||
},
|
||||
// #ifdef H5
|
||||
IsPC() {
|
||||
var userAgentInfo = navigator.userAgent;
|
||||
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
|
||||
var flag = true;
|
||||
for (let v = 0; v < Agents.length - 1; v++) {
|
||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
},
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* 获取星星个数
|
||||
*/
|
||||
_getRateCount(clientX) {
|
||||
this._getSize()
|
||||
const size = Number(this.size)
|
||||
if(size === NaN){
|
||||
return new Error('size 属性只能设置为数字')
|
||||
}
|
||||
const rateMoveRange = clientX - this._rateBoxLeft
|
||||
let index = parseInt(rateMoveRange / (size + this.marginNumber))
|
||||
index = index < 0 ? 0 : index;
|
||||
index = index > this.max ? this.max : index;
|
||||
const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
|
||||
let value = 0;
|
||||
if (this._oldValue === index && !this.PC) return;
|
||||
this._oldValue = index;
|
||||
if (this.allowHalf) {
|
||||
if (range > (size / 2)) {
|
||||
value = index + 1
|
||||
} else {
|
||||
value = index + 0.5
|
||||
}
|
||||
} else {
|
||||
value = index + 1
|
||||
}
|
||||
|
||||
value = Math.max(0.5, Math.min(value, this.max))
|
||||
this.valueSync = value
|
||||
this._onChange()
|
||||
},
|
||||
|
||||
/**
|
||||
* 触发动态修改
|
||||
*/
|
||||
_onChange() {
|
||||
|
||||
this.$emit("input", this.valueSync);
|
||||
this.$emit("update:modelValue", this.valueSync);
|
||||
this.$emit("change", {
|
||||
value: this.valueSync
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取星星距离屏幕左侧距离
|
||||
*/
|
||||
_getSize() {
|
||||
// #ifndef APP-NVUE
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.uni-rate')
|
||||
.boundingClientRect()
|
||||
.exec(ret => {
|
||||
if (ret) {
|
||||
this._rateBoxLeft = ret[0].left
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
|
||||
const size = ret.size
|
||||
if (size) {
|
||||
this._rateBoxLeft = size.left
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style
|
||||
lang="scss"
|
||||
scoped
|
||||
>
|
||||
.uni-rate {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
line-height: 1;
|
||||
font-size: 0;
|
||||
flex-direction: row;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-rate__icon {
|
||||
position: relative;
|
||||
line-height: 1;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.uni-rate__icon-on {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.uni-cursor-not-allowed {
|
||||
/* #ifdef H5 */
|
||||
cursor: not-allowed !important;
|
||||
/* #endif */
|
||||
}
|
||||
</style>
|
||||
87
uni_modules/uni-rate/package.json
Normal file
87
uni_modules/uni-rate/package.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"id": "uni-rate",
|
||||
"displayName": "uni-rate 评分",
|
||||
"version": "1.2.2",
|
||||
"description": "Rate 评分组件,可自定义评分星星图标的大小、间隔、评分数。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"评分"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uni-icons"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
107
uni_modules/uni-rate/readme.md
Normal file
107
uni_modules/uni-rate/readme.md
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
|
||||
## Rate 评分
|
||||
> **组件名:uni-rate**
|
||||
> 代码块: `uRate`
|
||||
> 关联组件:`uni-icons`
|
||||
|
||||
|
||||
评分组件,多用于购买商品后,对商品进行评价等场景
|
||||
|
||||
> **注意事项**
|
||||
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的使用说明,可以帮你避免一些错误。
|
||||
> - 暂时不支持零星选择
|
||||
> - 当前版本暂不支持修改图标,后续版本会继续优化
|
||||
> - 绑定值推荐使用 `v-model` 的方式
|
||||
> - 如需设置一个星星表示多分,如:显示5个星星,最高分10分。这种情况请在 change 事件监听中自行处理,获取到的值乘以你的基数就可以,默认组件是一星一分
|
||||
|
||||
|
||||
### 安装方式
|
||||
|
||||
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
|
||||
|
||||
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
|
||||
|
||||
|
||||
## 基本用法
|
||||
|
||||
```html
|
||||
<!-- 基本用法 -->
|
||||
<!-- 需要在 script 中绑定 value 变量 -->
|
||||
<uni-rate v-model="value" @change="onChange"/>
|
||||
|
||||
<!-- 不支持滑动手势选择评分 -->
|
||||
<uni-rate :touchable="false" :value="5"/>
|
||||
<!-- 设置尺寸大小 -->
|
||||
<uni-rate :size="18" :value="5"/>
|
||||
|
||||
<!-- 设置评分数 -->
|
||||
<uni-rate :max="10" :value="5" />
|
||||
|
||||
<!-- 设置星星间隔 -->
|
||||
<uni-rate :value="4" :margin="20" />
|
||||
|
||||
<!-- 设置颜色 -->
|
||||
<uni-rate :value="3" color="#bbb" active-color="red" />
|
||||
|
||||
<!-- 选择半星 -->
|
||||
<uni-rate allow-half :value="3.5" />
|
||||
|
||||
<!-- 只读状态 -->
|
||||
<uni-rate :readonly="true" :value="2" />
|
||||
|
||||
<!-- 禁用状态 -->
|
||||
<uni-rate :disabled="true" disabledColor="#ccc" :value="3" />
|
||||
|
||||
<!-- 未选中的星星为镂空状态 -->
|
||||
<uni-rate :value="3" :is-fill="false" />
|
||||
|
||||
|
||||
```
|
||||
|
||||
```javascript
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
value: 2
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
console.log('rate发生改变:' + JSON.stringify(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
### Rate Props
|
||||
|
||||
属性名 | 类型 | 默认值 | 说明
|
||||
:-: | :-: | :-: | :-:
|
||||
value/v-model | Number | 0 | 当前评分
|
||||
color | String | #ececec | 未选中状态的星星颜色
|
||||
activeColor | String | #ffca3e | 选中状态的星星颜色
|
||||
disabledColor | String | #c0c0c0 | 禁用状态的星星颜色
|
||||
size | Number | 24 | 星星的大小
|
||||
max | Number | 5 | 最大评分评分数量,目前一分一颗星
|
||||
margin | Number | 0 | 星星的间距,单位 px
|
||||
isFill | Boolean | true | 星星的类型,是否为实心类型
|
||||
disabled | Boolean | false | 是否为禁用状态 (之前版本为已读状态,现更正为禁用状态)
|
||||
readonly | Boolean | false | 是否为只读状态
|
||||
allowHalf | Boolean | false | 是否展示半星
|
||||
touchable | Boolean | true | 是否支持滑动手势
|
||||
|
||||
### Rate Events
|
||||
|
||||
事件称名 | 说明 | 返回参数
|
||||
:-: | :-: | :-:
|
||||
@change | 改变 value 的值返回 | e = { value:number }
|
||||
|
||||
|
||||
## 组件示例
|
||||
|
||||
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/rate/rate](https://hellouniapp.dcloud.net.cn/pages/extUI/rate/rate)
|
||||
Reference in New Issue
Block a user