Commit 9a297f22 authored by wlxuqu's avatar wlxuqu

1. 修复rate评分组件setTimeout的参数错误

2. 将switch和swipAction组件的震动参数设置为可选,且默认关闭
3. 修复swipeAction文档show参数的缺失
4. 给checkbox和radio组件添加label-size控制描述文字大小的参数
5. 增加swipeAction滑动单元格按钮数量配置,
parent b443a0a4
common/
components/
node_modules/
pages/
static/
store/
unpackage/
.gitignore
App.vue
LICENSE.txt
main.js
manifext.json
pages.json
vue.config.js
package-lock.json
.editorconfig
uni.scss
template.h5.html
......@@ -14,7 +14,7 @@
</script>
<style lang="scss">
@import "@/uview/index.scss";
@import "uview-ui/index.scss";
/*每个页面公共css */
/* H5的时候,隐藏滚动条 */
/* #ifdef H5 */
......
// 如果没有通过拦截器配置域名的话,可以在这里写上完整的URL(加上域名部分)
let hotSearchUrl = '/ebapi/store_api/hot_search';
let indexUrl = '/ebapi/public_api/index';
// 此处第二个参数vm,就是我们在页面使用的this,你可以通过vm获取vuex等操作,更多内容详见uView对拦截器的介绍部分:
// https://uviewui.com/js/http.html#%E4%BD%95%E8%B0%93%E8%AF%B7%E6%B1%82%E6%8B%A6%E6%88%AA%EF%BC%9F
const install = (Vue, vm) => {
// 此处没有使用传入的params参数
let getSearch = (params = {}) => vm.$u.get(hotSearchUrl, {
id: 2
});
// 此处使用了传入的params参数,一切自定义即可
let getInfo = (params = {}) => vm.$u.post(indexUrl, params);
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
vm.$u.api = {getSearch, getInfo};
}
export default {
install
}
\ No newline at end of file
<template>
<view class="nav-wrap">
<view class="nav-title">
<image class="logo" src="http://cdn.uviewui.com/uview/common/logo.png" mode="widthFix"></image>
<image class="logo" src="https://cdn.uviewui.com/uview/common/logo.png" mode="widthFix"></image>
<view class="nav-info">
<view class="nav-title__text">
uView UI
......
......@@ -15,7 +15,7 @@ App.mpType = 'app'
Vue.prototype.vuePrototype = '枣红'
// 引入全局uView
import uView from '@/uview'
import uView from 'uview-ui'
Vue.use(uView)
// 此处为演示vuex使用,非uView的功能部分
......@@ -26,7 +26,7 @@ let vuexStore = require('@/store/$u.mixin.js')
Vue.mixin(vuexStore)
// 引入uView对小程序分享的mixin封装
let mpShare = require('@/uview/libs/mixin/mpShare.js');
let mpShare = require('uview-ui/libs/mixin/mpShare.js');
Vue.mixin(mpShare)
const app = new Vue({
......@@ -38,5 +38,9 @@ const app = new Vue({
import httpInterceptor from '@/common/http.interceptor.js'
Vue.use(httpInterceptor, app)
// http接口API抽离,免于写url或者一些固定的参数
import httpApi from '@/common/http.api.js'
Vue.use(httpApi, app)
app.$mount()
{
"easycom": {
"^u-(.*)": "@/uview/components/u-$1/u-$1.vue"
},
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "test", //模式名称
"path": "pages/componentsC/cell/index", //启动页面,必选
"query": "id=1&name=2" //启动参数,在页面的-+onLoad函数里面得到
}]
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},
// "condition": { //模式配置,仅开发期间生效
// "current": 0, //当前激活的模式(list 的索引项)
// "list": [{
// "name": "test", //模式名称
// "path": "pages/componentsB/swipeAction/index", //启动页面,必选
// "query": "id=1&name=2" //启动参数,在页面的-+onLoad函数里面得到
// }]
// },
"pages": [
// 演示-组件
// 演示-组件
{
"path": "pages/example/components",
"style": {
"navigationBarTitleText": "组件"
"navigationBarTitleText": "组件"
}
},
// avatarCropper-头像裁剪
{
"path": "uview/components/u-avatar-cropper/u-avatar-cropper",
"path": "uview-ui/components/u-avatar-cropper/u-avatar-cropper",
"style": {
"navigationBarTitleText": "头像裁剪",
"navigationBarBackgroundColor": "#000000"
......@@ -42,7 +42,7 @@
},
// fullScreen-压窗屏
{
"path": "uview/components/u-full-screen/u-full-screen",
"path": "uview-ui/components/u-full-screen/u-full-screen",
"style": {
"navigationStyle": "custom",
"app-plus": {
......
......@@ -50,7 +50,7 @@
methods: {
chooseAvatar() {
this.$u.route({
url: '/uview/components/u-avatar-cropper/u-avatar-cropper',
url: '/uview-ui/components/u-avatar-cropper/u-avatar-cropper',
params: {
// 输出图片宽度,高等于宽,单位px
destWidth: 300,
......
......@@ -37,7 +37,7 @@
openModal(index) {
// 可以传递参数
if(index == 0) {
this.$u.route("/uview/components/u-full-screen/u-full-screen?id=1");
this.$u.route("/uview-ui/components/u-full-screen/u-full-screen?id=1");
}
}
}
......
......@@ -4,9 +4,19 @@
<view class="u-demo-title">演示效果</view>
<view class="u-demo-area">
<u-toast ref="uToast"></u-toast>
<u-swipe-action bg-color="rgb(250, 250, 250)" @open="open" :disabled="disabled" :index="index" v-for="(item, index) in list"
:key="item.id" :show="item.show" @click="click" :btn-text="btnText" :btn-width="btnWidth"
:btn-bg-color="btnBgColor" @close="close">
<u-swipe-action
bg-color="rgb(250, 250, 250)"
@open="open"
:disabled="disabled"
:index="index"
v-for="(item, index) in list"
:key="item.id"
:show="item.show"
@click="click"
:btn-width="btnWidth"
@close="close"
:options="options"
>
<view class="item u-border-bottom">
<image mode="aspectFill" :src="item.images" />
<!-- 此层wrap在此为必写的,否则可能会出现标题定位错误 -->
......@@ -18,9 +28,7 @@
</view>
</view>
<view class="u-config-wrap">
<view class="u-config-title u-border-bottom">
参数配置
</view>
<view class="u-config-title u-border-bottom">参数配置</view>
<view class="u-config-item">
<view class="u-item-title">状态(操作第一个)</view>
<u-subsection vibrateShort :current="1" :list="['打开', '关闭']" @change="showChange"></u-subsection>
......@@ -29,108 +37,107 @@
<view class="u-item-title">禁止滑动</view>
<u-subsection vibrateShort :current="1" :list="['是', '否']" @change="disabledChange"></u-subsection>
</view>
<view class="u-config-item">
<view class="u-item-title">自定义样式</view>
<u-subsection vibrateShort :current="1" :list="['是', '否']" @change="styleChange"></u-subsection>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [{
id: 1,
title: '长安回望绣成堆,山顶千门次第开,一骑红尘妃子笑,无人知是荔枝来',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false,
},
{
id: 2,
title: '新丰绿树起黄埃,数骑渔阳探使回,霓裳一曲千峰上,舞破中原始下来',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false
},
{
id: 3,
title: '登临送目,正故国晚秋,天气初肃。千里澄江似练,翠峰如簇',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false,
}
],
disabled: false,
btnWidth: 180,
btnText: '删除',
btnBgColor: '#FF0033',
show: false,
};
},
methods: {
disabledChange(index) {
this.disabled = index == 0 ? true : false;
},
styleChange(index) {
if(index == 0) {
this.btnWidth = 240;
this.btnText = '收藏';
this.btnBgColor = this.$u.color['warning'];
} else {
this.btnWidth = 180;
this.btnText = '删除';
this.btnBgColor = '#FF0033';
export default {
data() {
return {
list: [
{
id: 1,
title: '长安回望绣成堆,山顶千门次第开,一骑红尘妃子笑,无人知是荔枝来',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false
},
{
id: 2,
title: '新丰绿树起黄埃,数骑渔阳探使回,霓裳一曲千峰上,舞破中原始下来',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false
},
{
id: 3,
title: '登临送目,正故国晚秋,天气初肃。千里澄江似练,翠峰如簇',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false,
}
},
showChange(index) {
if(index == 0) {
this.list.map((val, ids) => {
if(ids != 0) val.show = false;
else val.show = true;
})
} else {
this.list[0].show = false;
],
disabled: false,
btnWidth: 180,
show: false,
options: [
{
text: '收藏',
style: {
backgroundColor: '#007aff'
}
},
{
text: '删除',
style: {
backgroundColor: '#dd524d'
}
}
},
click(index) {
]
};
},
methods: {
disabledChange(index) {
this.disabled = index == 0 ? true : false;
},
showChange(index) {
if (index == 0) {
this.list.map((val, ids) => {
if (ids != 0) val.show = false;
else val.show = true;
});
} else {
this.list[0].show = false;
}
},
click(index, index1) {
if(index1 == 1) {
this.list.splice(index, 1);
this.$refs.uToast.show({
type: 'warning',
title: `删除了第${index}个cell`,
})
},
open(index) {
this.list[index].show = true;
this.list.map((val, idx) => {
if(index != idx) this.list[idx].show = false;
})
},
close(index) {
this.$u.toast(`删除了第${index}个cell`);
} else {
this.list[index].show = false;
this.$u.toast(`收藏成功`);
}
},
open(index) {
this.list[index].show = true;
this.list.map((val, idx) => {
if (index != idx) this.list[idx].show = false;
});
},
close(index) {
this.list[index].show = false;
}
};
}
};
</script>
<style lang="scss" scoped>
.item {
display: flex;
padding: 20rpx;
}
image {
width: 120rpx;
flex: 0 0 120rpx;
height: 120rpx;
margin-right: 20rpx;
border-radius: 12rpx;
}
.item {
display: flex;
padding: 20rpx;
}
.title {
text-align: left;
font-size: 28rpx;
color: $u-content-color;
margin-top: 20rpx;
}
image {
width: 120rpx;
flex: 0 0 120rpx;
height: 120rpx;
margin-right: 20rpx;
border-radius: 12rpx;
}
.title {
text-align: left;
font-size: 28rpx;
color: $u-content-color;
margin-top: 20rpx;
}
</style>
......@@ -88,7 +88,7 @@
</template>
<script>
import Uvalidation from "@/uview/libs/validation/validation.js";
import Uvalidation from "uview-ui/libs/validation/validation.js";
export default {
data() {
return {
......
......@@ -26,7 +26,7 @@
export default {
data() {
return {
href: 'http://www.uviewui.com',
href: 'https://www.uviewui.com',
underLine: true,
fontSize: 28,
color: '#2979ff'
......
<template>
<view>
<u-dropdown-list :dropdown-list="dropdownList" @change="handleDropChange"></u-dropdown-list>
</view>
<view>
<u-swipe-action :show="item.show" :index="index"
v-for="(item, index) in list" :key="item.id"
@click="click" @open="open"
:options="options"
>
<view class="item u-border-bottom">
<image mode="aspectFill" :src="item.images" />
<!-- 此层wrap在此为必写的,否则可能会出现标题定位错误 -->
<view class="title-wrap">
<text class="title u-line-2">{{ item.title }}</text>
</view>
</view>
</u-swipe-action>
</view>
</template>
<script>
const dropdownOption1 = [
{ text: '类型', value: '', select: false },
{ text: '全场券', value: 1, select: false },
{ text: '品类券', value: 2, select: false },
{ text: '单品券', value: 3, select: false },
{ text: '业务券', value: 4, select: false }
]
const dropdownOption2 = [
{ text: '状态', value: '', select: false },
{ text: '可使用', value: 1, select: false },
{ text: '已过期', value: 2, select: false }
]
const dropdownOption3 = [
{ text: '优惠力度', value: '', select: false },
{ text: '满100-20', value: 1, select: false },
{ text: '满100-50', value: 2, select: false }
]
export default {
props: {},
data() {
return {
dropdownList: [
{ name: '类型', show: false, options: dropdownOption1 },
{ name: '状态', show: false, options: dropdownOption2 },
{ name: '优惠力度', show: false, options: dropdownOption3 }
]
}
},
methods: {
handleDropChange(select, options) {
console.log(select, options)
}
}
}
export default {
data() {
return {
list: [
{
id: 1,
title: '长安回望绣成堆,山顶千门次第开,一骑红尘妃子笑,无人知是荔枝来',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false
},
{
id: 2,
title: '新丰绿树起黄埃,数骑渔阳探使回,霓裳一曲千峰上,舞破中原始下来',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false
},
{
id: 3,
title: '登临送目,正故国晚秋,天气初肃。千里澄江似练,翠峰如簇',
images: 'https://cdn.uviewui.com/uview/common/logo.png',
show: false,
}
],
disabled: false,
btnWidth: 180,
show: false,
options: [
{
text: '收藏',
style: {
backgroundColor: '#007aff'
}
},
{
text: '删除',
style: {
backgroundColor: '#dd524d'
}
}
]
};
},
methods: {
click(index, index1) {
if(index1 == 1) {
this.list.splice(index, 1);
this.$u.toast(`删除了第${index}个cell`);
} else {
this.list[index].show = false;
this.$u.toast(`收藏成功`);
}
},
// 如果打开一个的时候,不需要关闭其他,则无需实现本方法
open(index) {
// 先将正在被操作的swipeAction标记为打开状态,否则由于props的特性限制,
// 原本为'false',再次设置为'false'会无效
this.list[index].show = true;
this.list.map((val, idx) => {
if(index != idx) this.list[idx].show = false;
})
}
}
};
</script>
<style lang="scss" scoped>
</style>
.item {
display: flex;
padding: 20rpx;
}
image {
width: 120rpx;
flex: 0 0 120rpx;
height: 120rpx;
margin-right: 20rpx;
border-radius: 12rpx;
}
.title {
text-align: left;
font-size: 28rpx;
color: $u-content-color;
margin-top: 20rpx;
}
</style>
\ No newline at end of file
......@@ -26,6 +26,14 @@ export default [
path: 'timeFormat',
icon: 'timeFormat',
title: 'TimeFormat 时间格式化',
},{
path: 'timeFrom',
icon: 'timeFrom',
title: 'timeFrom 多久之前',
},{
path: 'guid',
icon: 'guid',
title: 'Guid 全局唯一id',
},{
path: 'route',
icon: 'route',
......
......@@ -21,7 +21,7 @@
</template>
<script>
import md5Libs from "@/uview/libs/function/md5";
import md5Libs from "uview-ui/libs/function/md5";
export default {
data() {
return {
......
......@@ -3,4 +3,4 @@
* 使用的时候,请将下面的一行复制到您的uniapp项目根目录的uni.scss中即可
* uView自定义的css类名和scss变量,均以"u-"开头,不会造成冲突,请放心使用
*/
@import '@/uview/theme.scss';
\ No newline at end of file
@import 'uview-ui/theme.scss';
\ No newline at end of file
<p align="center">
<img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
</p>
<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView</h3>
<h3 align="center">多平台快速开发的UI框架</h3>
## 说明
uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
## 特性
- 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序
- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
- 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨
- 众多的常用页面和布局,让您专注逻辑,事半功倍
- 详尽的文档支持,现代化的演示效果
- 按需引入,精简打包体积
## 安装
```bash
# npm方式安装
npm i uview-ui
```
## 快速上手
1. `main.js`引入uView库
```js
// main.js
import uView from 'uview-ui';
Vue.use(uView);
```
2. `App.vue`引入基础样式(注意style标签需声明scss属性支持)
```css
/* App.vue */
<style lang="scss">
@import "uview-ui/index.scss";
</style>
```
3. `uni.scss`引入全局scss变量文件
```css
/* uni.scss */
@import "uview-ui/themb.scss";
```
4. `pages.json`配置easycom规则(按需引入)
```js
// pages.json
{
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
// 此为本身已有的内容
"pages": [
// ......
]
}
```
请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
## 使用方法
配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
```html
<template>
<u-buton>按钮</u-buton>
</template>
```
请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
## 链接
- [官方文档](https://uviewui.com/)
- [更新日志](https://uviewui.com/components/changelog.html)
- [升级指南](https://uviewui.com/components/changelog.html)
- [关于我们](https://uviewui.com/cooperation/about.html)
## 预览
您可以通过**微信**扫码,查看最佳的演示效果。
<br>
<br>
<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
<!-- ## 捐赠uView的研发
uView文档和源码全部开源免费,如果您认为uView帮到了您的开发工作,您可以捐赠uView的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。
<img src="https://uviewui.com/common/wechat.png" width="220" >
<img style="margin-left: 100px;" src="https://uviewui.com/common/alipay.png" width="220" >
-->
## 版权信息
uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
<template>
<u-popup mode="bottom" :border-radius="borderRadius" :popup="false" v-model="value" :maskCloseAble="maskCloseAble"
length="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="popupClose" :z-index="uZIndex">
<view class="u-tips u-border-bottom" v-if="tips.text" :style="tipsStyle">
{{tips.text}}
</view>
<block v-for="(item, index) in list" :key="index">
<view @touchmove.stop.prevent @tap="itemClick(index)" :style="[itemStyle(index)]" class="u-action-sheet-item" :class="[index < list.length - 1 ? 'u-border-bottom' : '']"
hover-class="u-hover-class" :hover-stay-time="150">
{{item.text}}
</view>
</block>
<view class="u-gab" v-if="cancelBtn">
</view>
<view @touchmove.stop.prevent class="u-actionsheet-cancel u-action-sheet-item" hover-class="u-hover-class"
:hover-stay-time="150" v-if="cancelBtn" @tap="close">取消</view>
</u-popup>
</template>
<script>
/**
* actionSheet 操作菜单
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
* @tutorial https://www.uviewui.com/components/actionSheet.html
* @property {Array<Object>} list 按钮的文字数组,见官方文档示例
* @property {Object} tips 顶部的提示文字,见官方文档示例
* @property {Boolean} cancel-btn 是否显示底部的取消按钮(默认true)
* @property {Number String} border-radius 弹出部分顶部左右的圆角值,单位rpx(默认0)
* @property {Boolean} mask-close-able 点击遮罩是否可以关闭(默认true)
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {Number String} z-index z-index值(默认1075)
* @event {Function} click 点击ActionSheet列表项时触发
* @event {Function} close 点击取消按钮时触发
* @example <u-action-sheet :list="list" @click="click" v-model="show"></u-action-sheet>
*/
export default {
name: "u-action-sheet",
props: {
// 点击遮罩是否可以关闭actionsheet
maskCloseAble: {
type: Boolean,
default: true
},
// 按钮的文字数组,可以自定义颜色和字体大小,字体单位为rpx
list: {
type: Array,
default () {
// 如下
// return [{
// text: '确定',
// color: '',
// fontSize: ''
// }]
return [];
}
},
// 顶部的提示文字
tips: {
type: Object,
default () {
return {
text: '',
color: '',
fontSize: '26'
}
}
},
// 底部的取消按钮
cancelBtn: {
type: Boolean,
default: true
},
// 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// 通过双向绑定控制组件的弹出与收起
value: {
type: Boolean,
default: false
},
// 弹出的顶部圆角值
borderRadius: {
type: [String, Number],
default: 0
},
// 弹出的z-index值
zIndex: {
type: [String, Number],
default: 0
}
},
computed: {
// 顶部提示的样式
tipsStyle() {
let style = {};
if (this.tips.color) style.color = this.tips.color;
if (this.tips.fontSize) style.fontSize = this.tips.fontSize + 'rpx';
return style;
},
// 操作项目的样式
itemStyle() {
return (index) => {
let style = {};
if (this.list[index].color) style.color = this.list[index].color;
if (this.list[index].fontSize) style.fontSize = this.list[index].fontSize + 'rpx';
return style;
}
},
uZIndex() {
// 如果用户有传递z-index值,优先使用
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
}
},
methods: {
// 点击取消按钮
close() {
// 发送input事件,并不会作用于父组件,而是要设置组件内部通过props传递的value参数
// 这是一个vue发送事件的特殊用法
this.popupClose();
this.$emit('close');
},
// 弹窗关闭
popupClose() {
this.$emit('input', false);
},
// 点击某一个itemif (!this.show) return;
itemClick(index) {
this.$emit('click', index);
this.$emit('input', false);
}
}
}
</script>
<style lang="scss" scoped>
.u-tips {
font-size: 26rpx;
text-align: center;
padding: 34rpx 0;
line-height: 1;
color: $u-tips-color;
}
.u-action-sheet-item {
display: flex;
line-height: 1;
justify-content: center;
align-items: center;
font-size: 34rpx;
padding: 34rpx 0;
}
.u-gab {
height: 12rpx;
background-color: rgb(234, 234, 236);
}
.u-actionsheet-cancel {
color: $u-main-color;
}
<template>
<u-popup mode="bottom" :border-radius="borderRadius" :popup="false" v-model="value" :maskCloseAble="maskCloseAble"
length="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="popupClose" :z-index="uZIndex">
<view class="u-tips u-border-bottom" v-if="tips.text" :style="tipsStyle">
{{tips.text}}
</view>
<block v-for="(item, index) in list" :key="index">
<view @touchmove.stop.prevent @tap="itemClick(index)" :style="[itemStyle(index)]" class="u-action-sheet-item" :class="[index < list.length - 1 ? 'u-border-bottom' : '']"
hover-class="u-hover-class" :hover-stay-time="150">
{{item.text}}
</view>
</block>
<view class="u-gab" v-if="cancelBtn">
</view>
<view @touchmove.stop.prevent class="u-actionsheet-cancel u-action-sheet-item" hover-class="u-hover-class"
:hover-stay-time="150" v-if="cancelBtn" @tap="close">取消</view>
</u-popup>
</template>
<script>
/**
* actionSheet 操作菜单
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
* @tutorial https://www.uviewui.com/components/actionSheet.html
* @property {Array<Object>} list 按钮的文字数组,见官方文档示例
* @property {Object} tips 顶部的提示文字,见官方文档示例
* @property {Boolean} cancel-btn 是否显示底部的取消按钮(默认true)
* @property {Number String} border-radius 弹出部分顶部左右的圆角值,单位rpx(默认0)
* @property {Boolean} mask-close-able 点击遮罩是否可以关闭(默认true)
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {Number String} z-index z-index值(默认1075)
* @event {Function} click 点击ActionSheet列表项时触发
* @event {Function} close 点击取消按钮时触发
* @example <u-action-sheet :list="list" @click="click" v-model="show"></u-action-sheet>
*/
export default {
name: "u-action-sheet",
props: {
// 点击遮罩是否可以关闭actionsheet
maskCloseAble: {
type: Boolean,
default: true
},
// 按钮的文字数组,可以自定义颜色和字体大小,字体单位为rpx
list: {
type: Array,
default () {
// 如下
// return [{
// text: '确定',
// color: '',
// fontSize: ''
// }]
return [];
}
},
// 顶部的提示文字
tips: {
type: Object,
default () {
return {
text: '',
color: '',
fontSize: '26'
}
}
},
// 底部的取消按钮
cancelBtn: {
type: Boolean,
default: true
},
// 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距
safeAreaInsetBottom: {
type: Boolean,
default: false
},
// 通过双向绑定控制组件的弹出与收起
value: {
type: Boolean,
default: false
},
// 弹出的顶部圆角值
borderRadius: {
type: [String, Number],
default: 0
},
// 弹出的z-index值
zIndex: {
type: [String, Number],
default: 0
}
},
computed: {
// 顶部提示的样式
tipsStyle() {
let style = {};
if (this.tips.color) style.color = this.tips.color;
if (this.tips.fontSize) style.fontSize = this.tips.fontSize + 'rpx';
return style;
},
// 操作项目的样式
itemStyle() {
return (index) => {
let style = {};
if (this.list[index].color) style.color = this.list[index].color;
if (this.list[index].fontSize) style.fontSize = this.list[index].fontSize + 'rpx';
return style;
}
},
uZIndex() {
// 如果用户有传递z-index值,优先使用
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
}
},
methods: {
// 点击取消按钮
close() {
// 发送input事件,并不会作用于父组件,而是要设置组件内部通过props传递的value参数
// 这是一个vue发送事件的特殊用法
this.popupClose();
this.$emit('close');
},
// 弹窗关闭
popupClose() {
this.$emit('input', false);
},
// 点击某一个itemif (!this.show) return;
itemClick(index) {
this.$emit('click', index);
this.$emit('input', false);
}
}
}
</script>
<style lang="scss" scoped>
.u-tips {
font-size: 26rpx;
text-align: center;
padding: 34rpx 0;
line-height: 1;
color: $u-tips-color;
}
.u-action-sheet-item {
display: flex;
line-height: 1;
justify-content: center;
align-items: center;
font-size: 34rpx;
padding: 34rpx 0;
}
.u-gab {
height: 12rpx;
background-color: rgb(234, 234, 236);
}
.u-actionsheet-cancel {
color: $u-main-color;
}
</style>
<template>
<button id="u-wave-btn" class="u-btn u-line-1 u-fix-ios-appearance" :class="[
'u-size-' + size,
plain ? 'u-' + type + '-plain' : '',
loading ? 'u-loading' : '',
shape == 'circle' ? 'u-round-circle' : '',
hairLine ? showHairLineBorder : 'u-bold-border',
]"
: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" :session-from="sessionFrom" :send-message-img="sendMessageImg" :show-message-card="showMessageCard"
@getphonenumber="getphonenumber" @getuserinfo="getuserinfo" @error="error" @opensetting="opensetting" @launchapp="launchapp"
:style="[buttonStyle]" @tap="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为true时有效
* @property {String} type 按钮的样式类型
* @property {Boolean} plain 按钮是否镂空,背景色透明
<template>
<button id="u-wave-btn" class="u-btn u-line-1 u-fix-ios-appearance" :class="[
'u-size-' + size,
plain ? 'u-' + type + '-plain' : '',
loading ? 'u-loading' : '',
shape == 'circle' ? 'u-round-circle' : '',
hairLine ? showHairLineBorder : 'u-bold-border',
]"
: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" :session-from="sessionFrom" :send-message-img="sendMessageImg" :show-message-card="showMessageCard"
@getphonenumber="getphonenumber" @getuserinfo="getuserinfo" @error="error" @opensetting="opensetting" @launchapp="launchapp"
:style="[buttonStyle]" @tap="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为true时有效
* @property {String} type 按钮的样式类型
* @property {Boolean} plain 按钮是否镂空,背景色透明
* @property {Boolean} disabled 是否禁用
* @property {Boolean} hair-line 是否显示按钮的细边框(默认true)
* @property {Boolean} shape 按钮外观形状,见文档说明
* @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台,在 ios 上为雪花,Android上为圆圈)
* @property {String} form-type 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
......@@ -41,446 +42,446 @@
* @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 按钮点击
* @property {Object} custom-style 对按钮的自定义样式,对象形式,见文档说明
* @event {Function} click 按钮点击
* @event {Function} getphonenumber open-type="getPhoneNumber"时有效
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo
* @event {Function} error 当使用开放能力时,发生错误的回调
* @event {Function} opensetting 在打开授权设置页并关闭后回调
* @event {Function} launchapp 打开 APP 成功的回调
* @example <u-button>月落</u-button>
*/
* @example <u-button>月落</u-button>
*/
export default {
name:"u-button",
props: {
// 是否细边框
hairLine: {
type: Boolean,
default: true
},
// 按钮的预置样式,default,primary,error,warning,success
type: {
type: String,
default: 'default'
},
// 按钮尺寸,default,medium,mini
size: {
type: String,
default: 'default'
},
// 按钮形状,circle(两边为半圆),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(提交表单),reset(重置表单)
formType: {
type: String,
default: ''
},
// 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
// 只微信小程序、QQ小程序有效
appParameter: {
type: String,
default: ''
},
// 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
hoverStopPropagation: {
type: Boolean,
default: false
},
// 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
lang: {
type: String,
default: 'en'
},
// 会话来源,open-type="contact"时有效。只微信小程序有效
sessionFrom: {
type: String,
default: ''
},
// 会话内消息卡片标题,open-type="contact"时有效
// 默认当前标题,只微信小程序有效
sendMessageTitle: {
type: String,
default: ''
},
// 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
// 默认当前分享路径,只微信小程序有效
sendMessagePath: {
type: String,
default: ''
},
// 会话内消息卡片图片,open-type="contact"时有效
// 默认当前页面截图,只微信小程序有效
sendMessageImg: {
type: String,
default: ''
},
// 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
// 用户点击后可以快速发送小程序消息,open-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 {}
}
}
},
computed: {
// 当没有传bgColor变量时,按钮按下去的颜色类名
getHoverClass() {
// 如果开启水波纹效果,则不启用hover-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;
},
// 按钮主题
buttonStyle() {
let style = {};
if (this.type == 'default') {
if (this.disabled) {
style.color = "#c0c4cc";
style.backgroundColor = "#ffffff";
style.borderColor = "#e4e7ed";
} else {
style.color = this.$u.color['contentColor'];
style.backgroundColor = "#ffffff";
style.borderColor = "#c0c4cc";
}
} else {
if (this.disabled) {
if (this.plain) {
style.color = this.$u.color[this.type + 'Disabled'];
style.backgroundColor = this.$u.color[this.type + 'Light'];
style.borderColor = this.$u.color[this.type + 'Disabled'];
} else {
style.color = "#ffffff";
style.backgroundColor = this.$u.color[this.type + 'Disabled'];
style.borderColor = this.$u.color[this.type + 'Disabled'];
}
} else {
if (this.plain) {
style.color = this.$u.color[this.type]
style.backgroundColor = this.$u.color[this.type + 'Light'];
style.borderColor = this.$u.color[this.type + 'Disabled'];
} else {
style.color = "#ffffff";
style.backgroundColor = this.$u.color[this.type];
style.borderColor = this.$u.color[this.type];
}
}
}
return Object.assign(style, this.customStyle);
},
// 在'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, // 水波纹起点X坐标到按钮左边界的距离
fields: {}, // 波纹按钮节点信息
waveActive: false, // 激活水波纹
}
},
methods: {
// 按钮点击
click(e) {
// 如果按钮时disabled和loading状态,不触发水波纹效果
if (this.loading === true || this.disabled === true) return;
// 是否开启水波纹效果
if (this.ripple) {
// 每次点击时,移除上一次的类,再次添加,才能触发动画效果
this.waveActive = false;
this.$nextTick(function() {
this.getWaveQuery(e);
});
}
this.$emit('click');
},
// 查询按钮的节点信息
getWaveQuery(e) {
this.getElQuery().then(res => {
// 查询返回的是一个数组节点
let data = res[0];
// 查询不到节点信息,不操作
if (!data.width || !data.width) return;
// 水波纹的最终形态是一个正方形(通过border-radius让其变为一个圆形),这里要保证正方形的边长等于按钮的最长边
// 最终的方形(变换后的圆形)才能覆盖整个按钮
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和y坐标,原理是通过屏幕的触摸点(touchesY),减去按钮的上边界data.top
// 但是由于`transform-origin`默认是center,所以这里再减去半径才是水波纹view应该的位置
// 总的来说,就是把水波纹的矩形(变换后的圆形)的中心点,移动到我们的触摸点位置
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);
queryInfo.select('.u-btn').boundingClientRect();
queryInfo.exec((data) => {
resolve(data)
});
})
},
// 下面为对接uniapp官方按钮开放能力事件回调的对接
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">
button::after {
border: none;
}
.u-btn {
position: relative;
border: 0;
//border-radius: 10rpx;
display: inline-block;
overflow: hidden;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0 40rpx;
z-index: 1;
box-sizing: border-box;
transition: all 0.15s;
}
.u-hairline-border:after {
content: ' ';
position: absolute;
pointer-events: none;
// 设置为border-box,意味着下面的scale缩小为0.5,实际上缩小的是伪元素的内容(border-box意味着内容不含border)
box-sizing: border-box;
// 中心点作为变形(scale())的原点
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
left: 0;
top: 0;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5, 0.5);
transform: scale(0.5, 0.5);
border: 1px solid currentColor;
z-index: 0;
}
.u-bold-border {
border: 1px solid #FFFFFF;
}
.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%, .35);
}
.u-size-default {
font-size: 30rpx;
height: 80rpx;
line-height: 80rpx;
}
.u-size-medium {
display: inline-flex;
width: auto;
font-size: 26rpx;
height: 70rpx;
line-height: 70rpx;
padding: 0 80rpx;
}
.u-size-mini {
display: inline-flex;
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;
}
name:"u-button",
props: {
// 是否细边框
hairLine: {
type: Boolean,
default: true
},
// 按钮的预置样式,default,primary,error,warning,success
type: {
type: String,
default: 'default'
},
// 按钮尺寸,default,medium,mini
size: {
type: String,
default: 'default'
},
// 按钮形状,circle(两边为半圆),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(提交表单),reset(重置表单)
formType: {
type: String,
default: ''
},
// 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
// 只微信小程序、QQ小程序有效
appParameter: {
type: String,
default: ''
},
// 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
hoverStopPropagation: {
type: Boolean,
default: false
},
// 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
lang: {
type: String,
default: 'en'
},
// 会话来源,open-type="contact"时有效。只微信小程序有效
sessionFrom: {
type: String,
default: ''
},
// 会话内消息卡片标题,open-type="contact"时有效
// 默认当前标题,只微信小程序有效
sendMessageTitle: {
type: String,
default: ''
},
// 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
// 默认当前分享路径,只微信小程序有效
sendMessagePath: {
type: String,
default: ''
},
// 会话内消息卡片图片,open-type="contact"时有效
// 默认当前页面截图,只微信小程序有效
sendMessageImg: {
type: String,
default: ''
},
// 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
// 用户点击后可以快速发送小程序消息,open-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 {}
}
}
},
computed: {
// 当没有传bgColor变量时,按钮按下去的颜色类名
getHoverClass() {
// 如果开启水波纹效果,则不启用hover-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;
},
// 按钮主题
buttonStyle() {
let style = {};
if (this.type == 'default') {
if (this.disabled) {
style.color = "#c0c4cc";
style.backgroundColor = "#ffffff";
style.borderColor = "#e4e7ed";
} else {
style.color = this.$u.color['contentColor'];
style.backgroundColor = "#ffffff";
style.borderColor = "#c0c4cc";
}
} else {
if (this.disabled) {
if (this.plain) {
style.color = this.$u.color[this.type + 'Disabled'];
style.backgroundColor = this.$u.color[this.type + 'Light'];
style.borderColor = this.$u.color[this.type + 'Disabled'];
} else {
style.color = "#ffffff";
style.backgroundColor = this.$u.color[this.type + 'Disabled'];
style.borderColor = this.$u.color[this.type + 'Disabled'];
}
} else {
if (this.plain) {
style.color = this.$u.color[this.type]
style.backgroundColor = this.$u.color[this.type + 'Light'];
style.borderColor = this.$u.color[this.type + 'Disabled'];
} else {
style.color = "#ffffff";
style.backgroundColor = this.$u.color[this.type];
style.borderColor = this.$u.color[this.type];
}
}
}
return Object.assign(style, this.customStyle);
},
// 在'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, // 水波纹起点X坐标到按钮左边界的距离
fields: {}, // 波纹按钮节点信息
waveActive: false, // 激活水波纹
}
},
methods: {
// 按钮点击
click(e) {
// 如果按钮时disabled和loading状态,不触发水波纹效果
if (this.loading === true || this.disabled === true) return;
// 是否开启水波纹效果
if (this.ripple) {
// 每次点击时,移除上一次的类,再次添加,才能触发动画效果
this.waveActive = false;
this.$nextTick(function() {
this.getWaveQuery(e);
});
}
this.$emit('click');
},
// 查询按钮的节点信息
getWaveQuery(e) {
this.getElQuery().then(res => {
// 查询返回的是一个数组节点
let data = res[0];
// 查询不到节点信息,不操作
if (!data.width || !data.width) return;
// 水波纹的最终形态是一个正方形(通过border-radius让其变为一个圆形),这里要保证正方形的边长等于按钮的最长边
// 最终的方形(变换后的圆形)才能覆盖整个按钮
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和y坐标,原理是通过屏幕的触摸点(touchesY),减去按钮的上边界data.top
// 但是由于`transform-origin`默认是center,所以这里再减去半径才是水波纹view应该的位置
// 总的来说,就是把水波纹的矩形(变换后的圆形)的中心点,移动到我们的触摸点位置
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);
queryInfo.select('.u-btn').boundingClientRect();
queryInfo.exec((data) => {
resolve(data)
});
})
},
// 下面为对接uniapp官方按钮开放能力事件回调的对接
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">
button::after {
border: none;
}
.u-btn {
position: relative;
border: 0;
//border-radius: 10rpx;
display: inline-block;
overflow: hidden;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0 40rpx;
z-index: 1;
box-sizing: border-box;
transition: all 0.15s;
}
.u-hairline-border:after {
content: ' ';
position: absolute;
pointer-events: none;
// 设置为border-box,意味着下面的scale缩小为0.5,实际上缩小的是伪元素的内容(border-box意味着内容不含border)
box-sizing: border-box;
// 中心点作为变形(scale())的原点
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
left: 0;
top: 0;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5, 0.5);
transform: scale(0.5, 0.5);
border: 1px solid currentColor;
z-index: 0;
}
.u-bold-border {
border: 1px solid #FFFFFF;
}
.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%, .35);
}
.u-size-default {
font-size: 30rpx;
height: 80rpx;
line-height: 80rpx;
}
.u-size-medium {
display: inline-flex;
width: auto;
font-size: 26rpx;
height: 70rpx;
line-height: 70rpx;
padding: 0 80rpx;
}
.u-size-mini {
display: inline-flex;
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>
<template>
<view class="u-keyboard" @touchmove.stop.prevent>
<view class="u-keyboard-grids">
<block>
<view class="u-keyboard-grids-item" v-for="(group, i) in abc ? EngKeyBoardList : areaList" :key="i">
<view :hover-stay-time="100" @tap="carInputClick(i, j)" hover-class="u-carinput-hover" class="u-keyboard-grids-btn"
v-for="(item, j) in group" :key="j">
{{ item }}
</view>
</view>
<view @touchstart="backspaceClick" @touchend="clearTimer" :hover-stay-time="100" class="u-keyboard-back"
hover-class="u-hover-class">
<u-icon :size="38" name="backspace" :bold="true"></u-icon>
</view>
<view :hover-stay-time="100" class="u-keyboard-change" hover-class="u-carinput-hover" @tap="changeCarInputMode">
<text class="zh" :class="[!abc ? 'active' : 'inactive']"></text>
/
<text class="en" :class="[abc ? 'active' : 'inactive']"></text>
</view>
</block>
</view>
</view>
</template>
<script>
/**
* carKeyboard 车牌号键盘
* @description 此为uViw自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3中模式,都有可以打乱按键顺序的选项。
* @tutorial https://www.uviewui.com/components/keyboard.html
* @property {String} mode 键盘类型,见官网基本使用的说明(默认number)
* @property {Boolean} dot-enabled 是否显示"."按键,只在mode=number时有效(默认true)
* @property {Boolean} tooltip 是否显示键盘顶部工具条(默认true)
* @property {String} tips 工具条中间的提示文字,见官网基本使用的说明,如不需要,请传""空字符
* @property {Boolean} cancel-btn 是否显示工具条左边的"取消"按钮(默认true)
* @property {Boolean} confirm-btn 是否显示工具条右边的"完成"按钮(默认true)
* @property {Boolean} mask 是否显示遮罩(默认true)
* @property {Number String} z-index 弹出键盘的z-index值(默认1075)
* @property {Boolean} random 是否打乱键盘按键的顺序(默认false)
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {Boolean} mask-close-able 是否允许点击遮罩收起键盘(默认true)
* @event {Function} change 按键被点击(不包含退格键被点击)
* @event {Function} cancel 键盘顶部工具条左边的"取消"按钮被点击
* @event {Function} confirm 键盘顶部工具条右边的"完成"按钮被点击
* @event {Function} backspace 键盘退格键被点击
* @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
*/
export default {
name: "u-keyboard",
props: {
// 是否打乱键盘按键的顺序
random: {
type: Boolean,
default: false
}
},
data() {
return {
// 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
abc: false
};
},
computed: {
areaList() {
let data = [
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'使',
''
];
let tmp = [];
// 打乱顺序
if (this.random) data = this.$u.randomArray(data);
// 切割成二维数组
tmp[0] = data.slice(0, 10);
tmp[1] = data.slice(10, 20);
tmp[2] = data.slice(20, 30);
tmp[3] = data.slice(30, 36);
return tmp;
},
EngKeyBoardList() {
let data = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
0,
'Q',
'W',
'E',
'R',
'T',
'Y',
'U',
'I',
'O',
'P',
'A',
'S',
'D',
'F',
'G',
'H',
'J',
'K',
'L',
'Z',
'X',
'C',
'V',
'B',
'N',
'M'
];
let tmp = [];
if (this.random) data = this.$u.randomArray(data);
tmp[0] = data.slice(0, 10);
tmp[1] = data.slice(10, 20);
tmp[2] = data.slice(20, 30);
tmp[3] = data.slice(30, 36);
return tmp;
}
},
methods: {
// 点击键盘按钮
carInputClick(i, j) {
let value = '';
// 不同模式,获取不同数组的值
if (this.abc) value = this.EngKeyBoardList[i][j];
else value = this.areaList[i][j];
this.$emit('change', value);
},
// 修改汽车牌键盘的输入模式,中文|英文
changeCarInputMode() {
this.abc = !this.abc;
},
// 点击退格键
backspaceClick() {
this.$emit('backspace');
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = setInterval(() => {
this.$emit('backspace');
}, 250);
},
clearTimer() {
clearInterval(this.timer);
},
}
};
</script>
<style lang="scss" scoped>
.u-keyboard-grids {
background: rgb(215, 215, 217);
padding: 24rpx 0;
position: relative;
}
.u-keyboard-grids-item {
display: flex;
align-items: center;
justify-content: center;
}
.u-keyboard-grids-btn {
text-decoration: none;
width: 62rpx;
flex: 0 0 64rpx;
height: 80rpx;
display: inline-block;
font-size: 36rpx;
text-align: center;
line-height: 80rpx;
background-color: #fff;
margin: 8rpx 5rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 0rpx #888992;
font-weight: 500;
}
.u-carinput-hover {
background-color: rgb(185, 188, 195) !important;
}
.u-keyboard-back {
position: absolute;
width: 96rpx;
right: 22rpx;
bottom: 32rpx;
height: 80rpx;
background-color: rgb(185, 188, 195);
display: flex;
align-items: center;
border-radius: 8rpx;
justify-content: center;
box-shadow: 0 2rpx 0rpx #888992;
}
.u-keyboard-change {
font-size: 24rpx;
box-shadow: 0 2rpx 0rpx #888992;
position: absolute;
width: 96rpx;
left: 22rpx;
line-height: 1;
bottom: 32rpx;
height: 80rpx;
background-color: #ffffff;
display: flex;
align-items: center;
border-radius: 8rpx;
justify-content: center;
}
.u-keyboard-change .inactive.zh {
transform: scale(0.85) translateY(-10rpx);
}
.u-keyboard-change .inactive.en {
transform: scale(0.85) translateY(10rpx);
}
.u-keyboard-change .active {
color: rgb(237, 112, 64);
font-size: 30rpx;
}
.u-keyboard-change .zh {
transform: translateY(-10rpx);
}
.u-keyboard-change .en {
transform: translateY(10rpx);
}
<template>
<view class="u-keyboard" @touchmove.stop.prevent>
<view class="u-keyboard-grids">
<block>
<view class="u-keyboard-grids-item" v-for="(group, i) in abc ? EngKeyBoardList : areaList" :key="i">
<view :hover-stay-time="100" @tap="carInputClick(i, j)" hover-class="u-carinput-hover" class="u-keyboard-grids-btn"
v-for="(item, j) in group" :key="j">
{{ item }}
</view>
</view>
<view @touchstart="backspaceClick" @touchend="clearTimer" :hover-stay-time="100" class="u-keyboard-back"
hover-class="u-hover-class">
<u-icon :size="38" name="backspace" :bold="true"></u-icon>
</view>
<view :hover-stay-time="100" class="u-keyboard-change" hover-class="u-carinput-hover" @tap="changeCarInputMode">
<text class="zh" :class="[!abc ? 'active' : 'inactive']"></text>
/
<text class="en" :class="[abc ? 'active' : 'inactive']"></text>
</view>
</block>
</view>
</view>
</template>
<script>
/**
* carKeyboard 车牌号键盘
* @description 此为uViw自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3中模式,都有可以打乱按键顺序的选项。
* @tutorial https://www.uviewui.com/components/keyboard.html
* @property {String} mode 键盘类型,见官网基本使用的说明(默认number)
* @property {Boolean} dot-enabled 是否显示"."按键,只在mode=number时有效(默认true)
* @property {Boolean} tooltip 是否显示键盘顶部工具条(默认true)
* @property {String} tips 工具条中间的提示文字,见官网基本使用的说明,如不需要,请传""空字符
* @property {Boolean} cancel-btn 是否显示工具条左边的"取消"按钮(默认true)
* @property {Boolean} confirm-btn 是否显示工具条右边的"完成"按钮(默认true)
* @property {Boolean} mask 是否显示遮罩(默认true)
* @property {Number String} z-index 弹出键盘的z-index值(默认1075)
* @property {Boolean} random 是否打乱键盘按键的顺序(默认false)
* @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
* @property {Boolean} mask-close-able 是否允许点击遮罩收起键盘(默认true)
* @event {Function} change 按键被点击(不包含退格键被点击)
* @event {Function} cancel 键盘顶部工具条左边的"取消"按钮被点击
* @event {Function} confirm 键盘顶部工具条右边的"完成"按钮被点击
* @event {Function} backspace 键盘退格键被点击
* @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
*/
export default {
name: "u-keyboard",
props: {
// 是否打乱键盘按键的顺序
random: {
type: Boolean,
default: false
}
},
data() {
return {
// 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
abc: false
};
},
computed: {
areaList() {
let data = [
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'使',
''
];
let tmp = [];
// 打乱顺序
if (this.random) data = this.$u.randomArray(data);
// 切割成二维数组
tmp[0] = data.slice(0, 10);
tmp[1] = data.slice(10, 20);
tmp[2] = data.slice(20, 30);
tmp[3] = data.slice(30, 36);
return tmp;
},
EngKeyBoardList() {
let data = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
0,
'Q',
'W',
'E',
'R',
'T',
'Y',
'U',
'I',
'O',
'P',
'A',
'S',
'D',
'F',
'G',
'H',
'J',
'K',
'L',
'Z',
'X',
'C',
'V',
'B',
'N',
'M'
];
let tmp = [];
if (this.random) data = this.$u.randomArray(data);
tmp[0] = data.slice(0, 10);
tmp[1] = data.slice(10, 20);
tmp[2] = data.slice(20, 30);
tmp[3] = data.slice(30, 36);
return tmp;
}
},
methods: {
// 点击键盘按钮
carInputClick(i, j) {
let value = '';
// 不同模式,获取不同数组的值
if (this.abc) value = this.EngKeyBoardList[i][j];
else value = this.areaList[i][j];
this.$emit('change', value);
},
// 修改汽车牌键盘的输入模式,中文|英文
changeCarInputMode() {
this.abc = !this.abc;
},
// 点击退格键
backspaceClick() {
this.$emit('backspace');
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = setInterval(() => {
this.$emit('backspace');
}, 250);
},
clearTimer() {
clearInterval(this.timer);
},
}
};
</script>
<style lang="scss" scoped>
.u-keyboard-grids {
background: rgb(215, 215, 217);
padding: 24rpx 0;
position: relative;
}
.u-keyboard-grids-item {
display: flex;
align-items: center;
justify-content: center;
}
.u-keyboard-grids-btn {
text-decoration: none;
width: 62rpx;
flex: 0 0 64rpx;
height: 80rpx;
display: inline-block;
font-size: 36rpx;
text-align: center;
line-height: 80rpx;
background-color: #fff;
margin: 8rpx 5rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 0rpx #888992;
font-weight: 500;
}
.u-carinput-hover {
background-color: rgb(185, 188, 195) !important;
}
.u-keyboard-back {
position: absolute;
width: 96rpx;
right: 22rpx;
bottom: 32rpx;
height: 80rpx;
background-color: rgb(185, 188, 195);
display: flex;
align-items: center;
border-radius: 8rpx;
justify-content: center;
box-shadow: 0 2rpx 0rpx #888992;
}
.u-keyboard-change {
font-size: 24rpx;
box-shadow: 0 2rpx 0rpx #888992;
position: absolute;
width: 96rpx;
left: 22rpx;
line-height: 1;
bottom: 32rpx;
height: 80rpx;
background-color: #ffffff;
display: flex;
align-items: center;
border-radius: 8rpx;
justify-content: center;
}
.u-keyboard-change .inactive.zh {
transform: scale(0.85) translateY(-10rpx);
}
.u-keyboard-change .inactive.en {
transform: scale(0.85) translateY(10rpx);
}
.u-keyboard-change .active {
color: rgb(237, 112, 64);
font-size: 30rpx;
}
.u-keyboard-change .zh {
transform: translateY(-10rpx);
}
.u-keyboard-change .en {
transform: translateY(10rpx);
}
</style>
<template>
<view class="u-cell-box">
<view class="u-cell-title" v-if="title" :style="[titleStyle]">
{{title}}
</view>
<view class="u-cell-item-box" :class="{'u-border-bottom u-border-top': border}">
<slot />
</view>
</view>
</template>
<script>
/**
* cellGroup 单元格父组件Group
* @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。搭配u-cell-item
* @tutorial https://www.uviewui.com/components/cell.html
* @property {String} title 分组标题
* @property {Boolean} border 是否显示外边框(默认true)
* @property {Object} title-style 分组标题的的样式,对象形式,如{'font-size': '24rpx'} 或 {'fontSize': '24rpx'}
* @example <u-cell-group title="设置喜好">
*/
export default {
name: "u-cell-group",
props: {
// 分组标题
title: {
type: String,
default: ''
},
// 是否显示分组list上下边框
border: {
type: Boolean,
default: true
},
// 分组标题的样式,对象形式,注意驼峰属性写法
// 类似 {'font-size': '24rpx'} 和 {'fontSize': '24rpx'}
titleStyle: {
type: Object,
default () {
return {};
}
}
},
data() {
return {
index: 0,
}
},
provide() {
return {
uCellGroup: this
}
},
}
</script>
<style lang="scss" scoped>
.u-cell-box {
width: 100%;
}
.u-cell-title {
padding: 30rpx 32rpx 10rpx 32rpx;
font-size: 30rpx;
text-align: left;
color: $u-tips-color;
}
.u-cell-item-box {
background-color: #FFFFFF;
}
<template>
<view class="u-cell-box">
<view class="u-cell-title" v-if="title" :style="[titleStyle]">
{{title}}
</view>
<view class="u-cell-item-box" :class="{'u-border-bottom u-border-top': border}">
<slot />
</view>
</view>
</template>
<script>
/**
* cellGroup 单元格父组件Group
* @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。搭配u-cell-item
* @tutorial https://www.uviewui.com/components/cell.html
* @property {String} title 分组标题
* @property {Boolean} border 是否显示外边框(默认true)
* @property {Object} title-style 分组标题的的样式,对象形式,如{'font-size': '24rpx'} 或 {'fontSize': '24rpx'}
* @example <u-cell-group title="设置喜好">
*/
export default {
name: "u-cell-group",
props: {
// 分组标题
title: {
type: String,
default: ''
},
// 是否显示分组list上下边框
border: {
type: Boolean,
default: true
},
// 分组标题的样式,对象形式,注意驼峰属性写法
// 类似 {'font-size': '24rpx'} 和 {'fontSize': '24rpx'}
titleStyle: {
type: Object,
default () {
return {};
}
}
},
data() {
return {
index: 0,
}
},
provide() {
return {
uCellGroup: this
}
},
}
</script>
<style lang="scss" scoped>
.u-cell-box {
width: 100%;
}
.u-cell-title {
padding: 30rpx 32rpx 10rpx 32rpx;
font-size: 30rpx;
text-align: left;
color: $u-tips-color;
}
.u-cell-item-box {
background-color: #FFFFFF;
}
</style>
<template>
<view
@tap="click"
class="u-cell"
:class="{ 'u-cell-border': itemIndex > 0 && borderBottom, 'u-col-center': center, 'u-border-gap': borderGap, 'u-cell--required': required }"
hover-stay-time="150"
:hover-class="hoverClass"
:style="{
backgroundColor: bgColor
}"
>
<u-icon :size="iconSize" :name="icon" v-if="icon" class="u-cell__left-icon-wrap"></u-icon>
<view class="u-flex" v-else>
<slot name="icon"></slot>
</view>
<view
class="u-cell_title"
:style="[
{
width: titleWidth ? titleWidth + 'rpx' : 'auto'
},
titleStyle
]"
>
<block v-if="title">{{ title }}</block>
<slot name="title" v-else></slot>
<view class="u-cell__label" v-if="label || $slots.label" :style="[labelStyle]">
<block v-if="label">{{ label }}</block>
<slot name="label" v-else></slot>
</view>
</view>
<view class="u-cell__value" :style="[valueStyle]">
<block class="u-cell__value" v-if="value">{{ value }}</block>
<slot v-else></slot>
</view>
<u-icon v-if="arrow" name="arrow-right" :style="[arrowStyle]" class="u-icon-wrap u-cell__right-icon-wrap"></u-icon>
<view class="u-flex" v-else>
<slot name="right-icon"></slot>
</view>
</view>
</template>
<script>
/**
* cellItem 单元格Item
* @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。搭配u-cell-group使用
* @tutorial https://www.uviewui.com/components/cell.html
* @property {String} title 左侧标题
* @property {String} icon 左侧图标名,只支持uView内置图标,见Icon 图标
* @property {String} value 右侧内容
* @property {String} label 标题下方的描述信息
* @property {Boolean} border-bottom 是否显示每个cell的下边框(默认true)
* @property {String} hover-class 是否开启点击反馈,none为无效果(默认true)
* @property {Boolean} border-gap border-bottom为true时,Cell列表中间的条目的下边框是否与左边有一个间隔(默认true)
* @property {Boolean} arrow 是否显示右侧箭头(默认true)
* @property {Boolean} required 箭头方向,可选值(默认right)
* @property {Boolean} arrow-direction 是否显示左边表示必填的星号(默认false)
* @property {Object} title-style 标题样式,对象形式
* @property {Object} value-style 右侧内容样式,对象形式
* @property {Object} label-style 标题下方描述信息的样式,对象形式
* @property {String} bg-color 背景颜色(默认transparent)
* @property {String Number} index 用于在click事件回调中返回,标识当前是第几个Item
* @property {String Number} title-width 标题的宽度,单位rpx
* @example <u-cell-item icon="integral-fill" title="会员等级" value="新版本"></u-cell-item>
*/
export default {
name: 'u-cell-item',
props: {
// 左侧图标名称(只能uView内置图标),或者图标src
icon: {
type: String,
default: ''
},
// 左侧标题
title: {
type: String,
default: ''
},
// 右侧内容
value: {
type: String,
default: ''
},
// 标题下方的描述信息
label: {
type: String,
default: ''
},
// 是否显示内边框
borderBottom: {
type: Boolean,
default: true
},
// 多个cell中,中间的cell显示下划线时,下划线是否给一个到左边的距离
borderGap: {
type: Boolean,
default: true
},
// 是否开启点击反馈,即点击时cell背景为灰色,none为无效果
hoverClass: {
type: String,
default: 'u-cell-hover'
},
// 是否显示右侧箭头
arrow: {
type: Boolean,
default: true
},
// 内容是否垂直居中
center: {
type: Boolean,
default: false
},
// 是否显示左边表示必填的星号
required: {
type: Boolean,
default: false
},
// 标题的宽度,单位rpx
titleWidth: {
type: [Number, String],
default: ''
},
// 右侧箭头方向,可选值:right|up|down,默认为right
arrowDirection: {
type: String,
default: 'right'
},
// 控制标题的样式
titleStyle: {
type: Object,
default() {
return {};
}
},
// 右侧显示内容的样式
valueStyle: {
type: Object,
default() {
return {};
}
},
// 描述信息的样式
labelStyle: {
type: Object,
default() {
return {};
}
},
// 背景颜色
bgColor: {
type: String,
default: 'transparent'
},
// 用于识别被点击的是第几个cell
index: {
type: [String, Number],
default: ''
},
// 是否使用lable插槽
useLabelSlot: {
type: Boolean,
default: false
},
// 左边图标的大小,单位rpx,只对传入icon字段时有效
iconSize: {
type: [Number, String],
default: 34
}
},
inject: ['uCellGroup'],
data() {
return {
itemIndex: 0
};
},
created() {
this.itemIndex = this.uCellGroup.index++;
},
computed: {
arrowStyle() {
let style = {};
if (this.arrowDirection == 'up') style.transform = 'rotate(-90deg)';
else if (this.arrowDirection == 'down') style.transform = 'rotate(90deg)';
else style.transform = 'rotate(0deg)';
return style;
}
},
methods: {
click() {
this.$emit('click', this.index);
}
}
};
</script>
<style lang="scss" scoped>
.u-cell {
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
padding: 20rpx 32rpx;
font-size: 28rpx;
line-height: 48rpx;
color: $u-content-color;
background-color: #fff;
text-align: left;
}
.u-cell_title {
font-size: 28rpx;
}
.u-cell__left-icon-wrap {
margin-right: 10rpx;
font-size: 32rpx;
}
.u-cell__right-icon-wrap {
margin-left: 10rpx;
color: #969799;
font-size: 28rpx;
}
.u-cell__left-icon-wrap,
.u-cell__right-icon-wrap {
display: flex;
align-items: center;
height: 48rpx;
}
.u-cell-border:after {
position: absolute;
box-sizing: border-box;
content: ' ';
pointer-events: none;
right: 0;
left: 0;
top: 0;
border-bottom: 1px solid $u-border-color;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
.u-cell-border {
position: relative;
}
.u-border-gap:after {
left: 32rpx !important;
}
.u-cell__label {
margin-top: 6rpx;
font-size: 26rpx;
line-height: 36rpx;
color: $u-tips-color;
}
.u-cell__value {
overflow: hidden;
text-align: right;
vertical-align: middle;
color: $u-tips-color;
font-size: 26rpx;
}
.u-cell__title,
.u-cell__value {
flex: 1;
}
.u-cell--required {
overflow: visible;
display: flex;
align-items: center;
}
.u-cell--required:before {
position: absolute;
content: '*';
left: 8px;
margin-top: 4rpx;
font-size: 14px;
color: $u-type-error;
}
<template>
<view
@tap="click"
class="u-cell"
:class="{ 'u-cell-border': itemIndex > 0 && borderBottom, 'u-col-center': center, 'u-border-gap': borderGap, 'u-cell--required': required }"
hover-stay-time="150"
:hover-class="hoverClass"
:style="{
backgroundColor: bgColor
}"
>
<u-icon :size="iconSize" :name="icon" v-if="icon" class="u-cell__left-icon-wrap"></u-icon>
<view class="u-flex" v-else>
<slot name="icon"></slot>
</view>
<view
class="u-cell_title"
:style="[
{
width: titleWidth ? titleWidth + 'rpx' : 'auto'
},
titleStyle
]"
>
<block v-if="title">{{ title }}</block>
<slot name="title" v-else></slot>
<view class="u-cell__label" v-if="label || $slots.label" :style="[labelStyle]">
<block v-if="label">{{ label }}</block>
<slot name="label" v-else></slot>
</view>
</view>
<view class="u-cell__value" :style="[valueStyle]">
<block class="u-cell__value" v-if="value">{{ value }}</block>
<slot v-else></slot>
</view>
<u-icon v-if="arrow" name="arrow-right" :style="[arrowStyle]" class="u-icon-wrap u-cell__right-icon-wrap"></u-icon>
<view class="u-flex" v-else>
<slot name="right-icon"></slot>
</view>
</view>
</template>
<script>
/**
* cellItem 单元格Item
* @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。搭配u-cell-group使用
* @tutorial https://www.uviewui.com/components/cell.html
* @property {String} title 左侧标题
* @property {String} icon 左侧图标名,只支持uView内置图标,见Icon 图标
* @property {String} value 右侧内容
* @property {String} label 标题下方的描述信息
* @property {Boolean} border-bottom 是否显示每个cell的下边框(默认true)
* @property {Boolean} center 是否使内容垂直居中(默认false)
* @property {String} hover-class 是否开启点击反馈,none为无效果(默认true)
* @property {Boolean} border-gap border-bottom为true时,Cell列表中间的条目的下边框是否与左边有一个间隔(默认true)
* @property {Boolean} arrow 是否显示右侧箭头(默认true)
* @property {Boolean} required 箭头方向,可选值(默认right)
* @property {Boolean} arrow-direction 是否显示左边表示必填的星号(默认false)
* @property {Object} title-style 标题样式,对象形式
* @property {Object} value-style 右侧内容样式,对象形式
* @property {Object} label-style 标题下方描述信息的样式,对象形式
* @property {String} bg-color 背景颜色(默认transparent)
* @property {String Number} index 用于在click事件回调中返回,标识当前是第几个Item
* @property {String Number} title-width 标题的宽度,单位rpx
* @example <u-cell-item icon="integral-fill" title="会员等级" value="新版本"></u-cell-item>
*/
export default {
name: 'u-cell-item',
props: {
// 左侧图标名称(只能uView内置图标),或者图标src
icon: {
type: String,
default: ''
},
// 左侧标题
title: {
type: String,
default: ''
},
// 右侧内容
value: {
type: String,
default: ''
},
// 标题下方的描述信息
label: {
type: String,
default: ''
},
// 是否显示内边框
borderBottom: {
type: Boolean,
default: true
},
// 多个cell中,中间的cell显示下划线时,下划线是否给一个到左边的距离
borderGap: {
type: Boolean,
default: true
},
// 是否开启点击反馈,即点击时cell背景为灰色,none为无效果
hoverClass: {
type: String,
default: 'u-cell-hover'
},
// 是否显示右侧箭头
arrow: {
type: Boolean,
default: true
},
// 内容是否垂直居中
center: {
type: Boolean,
default: false
},
// 是否显示左边表示必填的星号
required: {
type: Boolean,
default: false
},
// 标题的宽度,单位rpx
titleWidth: {
type: [Number, String],
default: ''
},
// 右侧箭头方向,可选值:right|up|down,默认为right
arrowDirection: {
type: String,
default: 'right'
},
// 控制标题的样式
titleStyle: {
type: Object,
default() {
return {};
}
},
// 右侧显示内容的样式
valueStyle: {
type: Object,
default() {
return {};
}
},
// 描述信息的样式
labelStyle: {
type: Object,
default() {
return {};
}
},
// 背景颜色
bgColor: {
type: String,
default: 'transparent'
},
// 用于识别被点击的是第几个cell
index: {
type: [String, Number],
default: ''
},
// 是否使用lable插槽
useLabelSlot: {
type: Boolean,
default: false
},
// 左边图标的大小,单位rpx,只对传入icon字段时有效
iconSize: {
type: [Number, String],
default: 34
}
},
inject: ['uCellGroup'],
data() {
return {
itemIndex: 0
};
},
created() {
this.itemIndex = this.uCellGroup.index++;
},
computed: {
arrowStyle() {
let style = {};
if (this.arrowDirection == 'up') style.transform = 'rotate(-90deg)';
else if (this.arrowDirection == 'down') style.transform = 'rotate(90deg)';
else style.transform = 'rotate(0deg)';
return style;
}
},
methods: {
click() {
this.$emit('click', this.index);
}
}
};
</script>
<style lang="scss" scoped>
.u-cell {
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
padding: 20rpx 32rpx;
font-size: 28rpx;
line-height: 48rpx;
color: $u-content-color;
background-color: #fff;
text-align: left;
}
.u-cell_title {
font-size: 28rpx;
}
.u-cell__left-icon-wrap {
margin-right: 10rpx;
font-size: 32rpx;
}
.u-cell__right-icon-wrap {
margin-left: 10rpx;
color: #969799;
font-size: 28rpx;
}
.u-cell__left-icon-wrap,
.u-cell__right-icon-wrap {
display: flex;
align-items: center;
height: 48rpx;
}
.u-cell-border:after {
position: absolute;
box-sizing: border-box;
content: ' ';
pointer-events: none;
right: 0;
left: 0;
top: 0;
border-bottom: 1px solid $u-border-color;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
.u-cell-border {
position: relative;
}
.u-border-gap:after {
left: 32rpx !important;
}
.u-cell__label {
margin-top: 6rpx;
font-size: 26rpx;
line-height: 36rpx;
color: $u-tips-color;
}
.u-cell__value {
overflow: hidden;
text-align: right;
vertical-align: middle;
color: $u-tips-color;
font-size: 26rpx;
}
.u-cell__title,
.u-cell__value {
flex: 1;
}
.u-cell--required {
overflow: visible;
display: flex;
align-items: center;
}
.u-cell--required:before {
position: absolute;
content: '*';
left: 8px;
margin-top: 4rpx;
font-size: 14px;
color: $u-type-error;
}
</style>
......@@ -5,17 +5,17 @@
</template>
<script>
/**
* checkboxGroup 开关选择器父组件Group
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
* @tutorial https://www.uviewui.com/components/checkbox.html
* @property {String Number} max 最多能选中多少个checkbox(默认999)
* @property {Boolean} disabled 是否禁用所有checkbox(默认false)
* @property {String} active-color 选中时的颜色,应用到所有子Checkbox组件(默认#2979ff)
/**
* checkboxGroup 开关选择器父组件Group
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
* @tutorial https://www.uviewui.com/components/checkbox.html
* @property {String Number} max 最多能选中多少个checkbox(默认999)
* @property {Boolean} disabled 是否禁用所有checkbox(默认false)
* @property {String} active-color 选中时的颜色,应用到所有子Checkbox组件(默认#2979ff)
* @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
* @example <u-checkbox-group></u-checkbox-group>
* @example <u-checkbox-group></u-checkbox-group>
*/
export default {
export default {
name: 'u-checkbox-group',
props: {
// 最多能选中多少个checkbox
......
<template>
<view class="u-checkbox">
<view class="u-checkbox__icon-wrap" @tap="toggle">
<u-icon :class="iconClass" name="checkbox-mark" :size="iconSize" :color="iconColor" class="u-checkbox__icon" :style="[iconStyle]" />
</view>
<view class="u-label-class u-checkbox__label" @tap="onClickLabel">
<slot />
</view>
</view>
</template>
<script>
/**
* checkbox 复选框
* @description 该组件需要搭配checkboxGroup组件使用,以便用户进行操作时,获得当前复选框组的选中情况。
* @tutorial https://www.uviewui.com/components/checkbox.html
* @property {String Number} icon-size 图标大小,单位rpx(默认24)
* @property {String Number} size 组件整体的大小,单位rpx(默认40)
* @property {String Number} name checkbox组件的标示符
* @property {String} shape 形状,见官网说明(默认circle)
* @property {Boolean} disabled 是否禁用(默认false)
* @property {Boolean} label-disabled 点击文本是否可以操作checkbox(默认true)
* @property {String} active-color 选中时的颜色,如设置CheckboxGroup的active-color将失效
* @event {Function} change 某个checkbox状态发生变化时触发,回调为一个对象
* @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
*/
export default {
name: "u-checkbox",
props: {
// checkbox的名称
name: {
type: [String, Number],
default: ''
},
// 形状,square为方形,circle为原型
shape: {
type: String,
default: 'square'
},
// 是否为选中状态
value: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 是否禁止点击提示语选中复选框
labelDisabled: {
type: Boolean,
default: false
},
// 选中状态下的颜色,如设置此值,将会覆盖checkboxGroup的activeColor值
activeColor: {
type: String,
default: ''
},
// 图标的大小,单位rpx
iconSize: {
type: [String, Number],
default: 24
},
},
inject: ['checkboxGroup'],
data() {
return {
parentDisabled: false,
};
},
created() {
this.parentDisabled = this.checkboxGroup.disabled;
this.checkboxGroup.children.push(this);
},
computed: {
iconStyle() {
let style = {};
if (this.checkboxActiveColor && this.value && !this.disabled && !this.parentDisabled) {
style.borderColor = this.checkboxActiveColor;
style.backgroundColor = this.checkboxActiveColor;
}
style.width = this.checkboxGroup.size + 'rpx';
style.height = this.checkboxGroup.size + 'rpx';
return style;
},
iconColor() {
return this.value ? '#ffffff' : 'transparent';
},
iconClass() {
let classs = [];
classs.push('u-checkbox__icon--' + this.shape);
if (this.value == true) classs.push('u-checkbox__icon--checked');
if (this.disabled || this.parentDisabled) classs.push('u-checkbox__icon--disabled');
if (this.value && (this.disabled || this.parentDisabled)) classs.push('u-checkbox__icon--disabled--checked');
return classs;
},
// 激活的颜色,可能受checkboxGroup和本组件的activeColor影响
// 本组件的activeColor值优先
checkboxActiveColor() {
return this.activeColor ? this.activeColor : this.checkboxGroup.activeColor;
}
},
methods: {
onClickLabel() {
if (!this.disabled && !this.labelDisabled && !this.parentDisabled) {
this.setValue();
}
},
toggle() {
if (!this.disabled && !this.parentDisabled) {
this.setValue();
}
},
emitEvent() {
this.$emit('change', {
value: this.value,
name: this.name
})
this.checkboxGroup.emitEvent();
},
// 设置input的值,这里通过input事件,设置通过v-model绑定的组件的值
setValue() {
// 判断是否超过了可选的最大数量
let checkedNum = 0;
this.checkboxGroup.children.map(val => {
if (val.value) checkedNum++;
})
// 如果原来为选中状态,那么可以取消
if (this.value == true) {
this.$emit('input', !this.value);
// 等待下一个周期再执行,因为this.$emit('input')作用于父组件,再反馈到子组件内部,需要时间
this.$nextTick(function() {
this.emitEvent();
})
} else if (checkedNum < this.checkboxGroup.max && this.value == false) {
// 如果原来为未选中状态,需要选中的数量少于父组件中设置的max值,才可以选中
this.$emit('input', !this.value);
// 等待下一个周期再执行,因为this.$emit('input')作用于父组件,再反馈到子组件内部,需要时间
this.$nextTick(function() {
this.emitEvent();
})
}
}
}
};
</script>
<style lang="scss" scoped>
.u-checkbox {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
overflow: hidden;
-webkit-user-select: none;
user-select: none;
}
.u-checkbox__icon-wrap,
.u-checkbox__label {
color: $u-content-color;
}
.u-checkbox__icon-wrap {
-webkit-flex: none;
flex: none;
}
.u-checkbox__icon {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
box-sizing: border-box;
width: 42rpx;
height: 42rpx;
color: transparent;
text-align: center;
transition-property: color, border-color, background-color;
font-size: 20px;
border: 1px solid #c8c9cc;
transition-duration: 0.2s;
}
.u-checkbox__icon--circle {
border-radius: 100%;
}
.u-checkbox__icon--square {
border-radius: 3px;
}
.u-checkbox__icon--checked {
color: #fff;
background-color: #2979ff;
border-color: #2979ff;
}
.u-checkbox__icon--disabled {
background-color: #ebedf0;
border-color: #c8c9cc;
}
.u-checkbox__icon--disabled--checked {
color: #c8c9cc !important;
}
.u-checkbox__label {
word-wrap: break-word;
margin-left: 10rpx;
margin-right: 18rpx;
color: $u-content-color;
font-size: 30rpx;
}
.u-checkbox__label--disabled {
color: #c8c9cc;
}
.u-checkbox__label:empty {
margin: 0;
}
<template>
<view class="u-checkbox">
<view class="u-checkbox__icon-wrap" @tap="toggle">
<u-icon :class="iconClass" name="checkbox-mark" :size="iconSize" :color="iconColor" class="u-checkbox__icon" :style="[iconStyle]" />
</view>
<view class="u-label-class u-checkbox__label" @tap="onClickLabel" :style="{
fontSize: labelSize + 'rpx'
}">
<slot />
</view>
</view>
</template>
<script>
/**
* checkbox 复选框
* @description 该组件需要搭配checkboxGroup组件使用,以便用户进行操作时,获得当前复选框组的选中情况。
* @tutorial https://www.uviewui.com/components/checkbox.html
* @property {String Number} icon-size 图标大小,单位rpx(默认24)
* @property {String Number} label-size label字体大小,单位rpx(默认28)
* @property {String Number} size 组件整体的大小,单位rpx(默认40)
* @property {String Number} name checkbox组件的标示符
* @property {String} shape 形状,见官网说明(默认circle)
* @property {Boolean} disabled 是否禁用(默认false)
* @property {Boolean} label-disabled 点击文本是否可以操作checkbox(默认true)
* @property {String} active-color 选中时的颜色,如设置CheckboxGroup的active-color将失效
* @event {Function} change 某个checkbox状态发生变化时触发,回调为一个对象
* @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
*/
export default {
name: "u-checkbox",
props: {
// checkbox的名称
name: {
type: [String, Number],
default: ''
},
// 形状,square为方形,circle为原型
shape: {
type: String,
default: 'square'
},
// 是否为选中状态
value: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 是否禁止点击提示语选中复选框
labelDisabled: {
type: Boolean,
default: false
},
// 选中状态下的颜色,如设置此值,将会覆盖checkboxGroup的activeColor值
activeColor: {
type: String,
default: ''
},
// 图标的大小,单位rpx
iconSize: {
type: [String, Number],
default: 24
},
// label的字体大小,rpx单位
labelSize: {
type: [String, Number],
default: 28
},
},
inject: ['checkboxGroup'],
data() {
return {
parentDisabled: false,
};
},
created() {
this.parentDisabled = this.checkboxGroup.disabled;
this.checkboxGroup.children.push(this);
},
computed: {
iconStyle() {
let style = {};
if (this.checkboxActiveColor && this.value && !this.disabled && !this.parentDisabled) {
style.borderColor = this.checkboxActiveColor;
style.backgroundColor = this.checkboxActiveColor;
}
style.width = this.checkboxGroup.size + 'rpx';
style.height = this.checkboxGroup.size + 'rpx';
return style;
},
iconColor() {
return this.value ? '#ffffff' : 'transparent';
},
iconClass() {
let classs = [];
classs.push('u-checkbox__icon--' + this.shape);
if (this.value == true) classs.push('u-checkbox__icon--checked');
if (this.disabled || this.parentDisabled) classs.push('u-checkbox__icon--disabled');
if (this.value && (this.disabled || this.parentDisabled)) classs.push('u-checkbox__icon--disabled--checked');
return classs;
},
// 激活的颜色,可能受checkboxGroup和本组件的activeColor影响
// 本组件的activeColor值优先
checkboxActiveColor() {
return this.activeColor ? this.activeColor : this.checkboxGroup.activeColor;
}
},
methods: {
onClickLabel() {
if (!this.disabled && !this.labelDisabled && !this.parentDisabled) {
this.setValue();
}
},
toggle() {
if (!this.disabled && !this.parentDisabled) {
this.setValue();
}
},
emitEvent() {
this.$emit('change', {
value: this.value,
name: this.name
})
this.checkboxGroup.emitEvent();
},
// 设置input的值,这里通过input事件,设置通过v-model绑定的组件的值
setValue() {
// 判断是否超过了可选的最大数量
let checkedNum = 0;
this.checkboxGroup.children.map(val => {
if (val.value) checkedNum++;
})
// 如果原来为选中状态,那么可以取消
if (this.value == true) {
this.$emit('input', !this.value);
// 等待下一个周期再执行,因为this.$emit('input')作用于父组件,再反馈到子组件内部,需要时间
this.$nextTick(function() {
this.emitEvent();
})
} else if (checkedNum < this.checkboxGroup.max && this.value == false) {
// 如果原来为未选中状态,需要选中的数量少于父组件中设置的max值,才可以选中
this.$emit('input', !this.value);
// 等待下一个周期再执行,因为this.$emit('input')作用于父组件,再反馈到子组件内部,需要时间
this.$nextTick(function() {
this.emitEvent();
})
}
}
}
};
</script>
<style lang="scss" scoped>
.u-checkbox {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
overflow: hidden;
-webkit-user-select: none;
user-select: none;
}
.u-checkbox__icon-wrap,
.u-checkbox__label {
color: $u-content-color;
}
.u-checkbox__icon-wrap {
-webkit-flex: none;
flex: none;
}
.u-checkbox__icon {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
box-sizing: border-box;
width: 42rpx;
height: 42rpx;
color: transparent;
text-align: center;
transition-property: color, border-color, background-color;
font-size: 20px;
border: 1px solid #c8c9cc;
transition-duration: 0.2s;
}
.u-checkbox__icon--circle {
border-radius: 100%;
}
.u-checkbox__icon--square {
border-radius: 3px;
}
.u-checkbox__icon--checked {
color: #fff;
background-color: #2979ff;
border-color: #2979ff;
}
.u-checkbox__icon--disabled {
background-color: #ebedf0;
border-color: #c8c9cc;
}
.u-checkbox__icon--disabled--checked {
color: #c8c9cc !important;
}
.u-checkbox__label {
word-wrap: break-word;
margin-left: 10rpx;
margin-right: 18rpx;
color: $u-content-color;
font-size: 30rpx;
}
.u-checkbox__label--disabled {
color: #c8c9cc;
}
.u-checkbox__label:empty {
margin: 0;
}
</style>
<template>
<view class="u-circle-progress" :style="{
width: widthPx + 'px',
height: widthPx + 'px',
backgroundColor: bgColor
}">
<canvas class="u-canvas-bg" :canvas-id="elBgId" :style="{
width: widthPx + 'px',
height: widthPx + 'px'
}"></canvas>
<canvas class="u-canvas" :canvas-id="elId" :style="{
width: widthPx + 'px',
height: widthPx + 'px'
}"></canvas>
<slot></slot>
</view>
</template>
<script>
/**
* circleProgress 环形进度条
* @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度条。注意:此组件的percent值只能动态增加,不能动态减少。
* @tutorial https://www.uviewui.com/components/circleProgress.html
* @property {String Number} percent 圆环进度百分比值,为数值类型,0-100
* @property {String} inactive-color 圆环的底色,默认为灰色(该值无法动态变更)(默认#ececec)
* @property {String} active-color 圆环激活部分的颜色(该值无法动态变更)(默认#19be6b)
* @property {String Number} width 整个圆环组件的宽度,高度默认等于宽度值,单位rpx(默认200)
* @property {String Number} border-width 圆环的边框宽度,单位rpx(默认14)
* @property {String Number} duration 整个圆环执行一圈的时间,单位ms(默认呢1500)
* @property {String} type 如设置,active-color值将会失效
* @property {String} bg-color 整个组件背景颜色,默认为白色
* @example <u-circle-progress active-color="#2979ff" :percent="80"></u-circle-progress>
*/
export default {
name: "u-circle-progress",
props: {
// 圆环进度百分比值
percent: {
type: Number,
default: 0,
// 限制值在0到100之间
validator: val => {
return val >= 0 && val <= 100;
}
},
// 底部圆环的颜色(灰色的圆环)
inactiveColor: {
type: String,
default: "#ececec"
},
// 圆环激活部分的颜色
activeColor: {
type: String,
default: '#19be6b'
},
// 圆环线条的宽度,单位rpx
borderWidth: {
type: [Number, String],
default: 14
},
// 整个圆形的宽度,单位rpx
width: {
type: [Number, String],
default: 200
},
// 整个圆环执行一圈的时间,单位ms
duration: {
type: [Number, String],
default: 1500
},
// 主题类型
type: {
type: String,
default: ''
},
// 整个圆环进度区域的背景色
bgColor: {
type: String,
default: "#ffffff"
}
},
data() {
return {
elBgId: this.$u.guid(),
elId: this.$u.guid(),
ctxBg: '', // 背景canvas实例
ctx: '', // 前景(激活时候)canvas的实例
count: 0, // 计数器
timer: null, // 定时器
times: 0, // 总共要执行的动画次数,setInterval的次数
time: 0, // 执行整个动画的时间
widthPx: uni.upx2px(this.width), // 转成px后的整个组件的背景宽度
borderWidthPx: uni.upx2px(this.borderWidth), // 转成px后的圆环的宽度
mode: 'more', // more-percent增加,less-percent减少
}
},
watch: {
percent: {
immediate: true,
handler(nVal, oVal = 0) {
this.mode = nVal > oVal ? 'more' : 'less';
this.times = Math.ceil(nVal * 3.6);
this.time = Math.ceil(this.duration / 360 * this.times);
setTimeout(() => {
this.countInterval();
}, 50)
}
}
},
computed: {
// 有type主题时,优先起作用
circleColor() {
if (['success', 'error', 'info', 'primary', 'warning'].indexOf(this.type) >= 0) return this.$u.color[this.type];
else return this.activeColor;
}
},
mounted() {
this.ctxBg = uni.createCanvasContext(this.elBgId, this);
this.ctx = uni.createCanvasContext(this.elId, this);
// 在h5端,必须要做一点延时才起作用,this.$nextTick()无效(HX2.4.7)
setTimeout(() => {
this.drawProgressBg();
}, 50)
},
methods: {
drawProgressBg() {
this.ctxBg.setLineWidth(this.borderWidthPx); // 设置圆环宽度
this.ctxBg.setStrokeStyle(this.inactiveColor); // 线条颜色
this.ctxBg.setLineCap('round'); // 圆环端点的形状为圆形
this.ctxBg.beginPath(); // 开始描绘路径
// 设置一个原点(110,110),半径为100的圆的路径到当前路径
this.ctxBg.arc(this.widthPx / 2, this.widthPx / 2, this.widthPx / 2 - this.borderWidthPx / 2 - 1, 0, 2 * Math.PI,
false);
this.ctxBg.stroke(); // 对路径进行描绘
this.ctxBg.draw();
},
drawCircle(step) {
this.ctx.setLineWidth(this.borderWidthPx);
this.ctx.setStrokeStyle(this.circleColor);
this.ctx.setLineCap('round');
this.ctx.beginPath();
// 参数step 为绘制的圆环周长,从0到2为一周 。 -Math.PI / 2 将起始角设在12点钟位置 ,结束角 通过改变 step 的值确定
if (this.mode == 'more') {
this.ctx.arc(this.widthPx / 2, this.widthPx / 2, this.widthPx / 2 - this.borderWidthPx / 2 - 1, -Math.PI / 2, step *
Math.PI - Math.PI / 2, false);
} else {
this.ctx.arc(this.widthPx / 2, this.widthPx / 2, this.widthPx / 2 - this.borderWidthPx / 2 - 1, -Math.PI / 2, Math
.PI / 2 - step *
Math.PI, false);
}
this.ctx.stroke();
this.ctx.draw()
},
countInterval() {
this.countTimer = setInterval(() => {
if (this.count <= this.times) {
// 全一个圆时候,值为2,这里求出每一份的值为2/360
this.drawCircle(this.count * 2 / 360);
this.count++;
} else {
clearInterval(this.countTimer);
}
}, Math.ceil(this.duration / 360)); // 总过渡时间分为360份,这里为每一份的时间
},
}
}
</script>
<style lang="scss" scoped>
.u-circle-progress {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
}
.u-canvas-bg {
position: absolute;
}
.u-canvas {
position: absolute;
}
<template>
<view class="u-circle-progress" :style="{
width: widthPx + 'px',
height: widthPx + 'px',
backgroundColor: bgColor
}">
<canvas class="u-canvas-bg" :canvas-id="elBgId" :style="{
width: widthPx + 'px',
height: widthPx + 'px'
}"></canvas>
<canvas class="u-canvas" :canvas-id="elId" :style="{
width: widthPx + 'px',
height: widthPx + 'px'
}"></canvas>
<slot></slot>
</view>
</template>
<script>
/**
* circleProgress 环形进度条
* @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度条。注意:此组件的percent值只能动态增加,不能动态减少。
* @tutorial https://www.uviewui.com/components/circleProgress.html
* @property {String Number} percent 圆环进度百分比值,为数值类型,0-100
* @property {String} inactive-color 圆环的底色,默认为灰色(该值无法动态变更)(默认#ececec)
* @property {String} active-color 圆环激活部分的颜色(该值无法动态变更)(默认#19be6b)
* @property {String Number} width 整个圆环组件的宽度,高度默认等于宽度值,单位rpx(默认200)
* @property {String Number} border-width 圆环的边框宽度,单位rpx(默认14)
* @property {String Number} duration 整个圆环执行一圈的时间,单位ms(默认呢1500)
* @property {String} type 如设置,active-color值将会失效
* @property {String} bg-color 整个组件背景颜色,默认为白色
* @example <u-circle-progress active-color="#2979ff" :percent="80"></u-circle-progress>
*/
export default {
name: "u-circle-progress",
props: {
// 圆环进度百分比值
percent: {
type: Number,
default: 0,
// 限制值在0到100之间
validator: val => {
return val >= 0 && val <= 100;
}
},
// 底部圆环的颜色(灰色的圆环)
inactiveColor: {
type: String,
default: "#ececec"
},
// 圆环激活部分的颜色
activeColor: {
type: String,
default: '#19be6b'
},
// 圆环线条的宽度,单位rpx
borderWidth: {
type: [Number, String],
default: 14
},
// 整个圆形的宽度,单位rpx
width: {
type: [Number, String],
default: 200
},
// 整个圆环执行一圈的时间,单位ms
duration: {
type: [Number, String],
default: 1500
},
// 主题类型
type: {
type: String,
default: ''
},
// 整个圆环进度区域的背景色
bgColor: {
type: String,
default: "#ffffff"
}
},
data() {
return {
elBgId: this.$u.guid(),
elId: this.$u.guid(),
ctxBg: '', // 背景canvas实例
ctx: '', // 前景(激活时候)canvas的实例
count: 0, // 计数器
timer: null, // 定时器
times: 0, // 总共要执行的动画次数,setInterval的次数
time: 0, // 执行整个动画的时间
widthPx: uni.upx2px(this.width), // 转成px后的整个组件的背景宽度
borderWidthPx: uni.upx2px(this.borderWidth), // 转成px后的圆环的宽度
mode: 'more', // more-percent增加,less-percent减少
}
},
watch: {
percent: {
immediate: true,
handler(nVal, oVal = 0) {
this.mode = nVal > oVal ? 'more' : 'less';
this.times = Math.ceil(nVal * 3.6);
this.time = Math.ceil(this.duration / 360 * this.times);
setTimeout(() => {
this.countInterval();
}, 50)
}
}
},
computed: {
// 有type主题时,优先起作用
circleColor() {
if (['success', 'error', 'info', 'primary', 'warning'].indexOf(this.type) >= 0) return this.$u.color[this.type];
else return this.activeColor;
}
},
mounted() {
this.ctxBg = uni.createCanvasContext(this.elBgId, this);
this.ctx = uni.createCanvasContext(this.elId, this);
// 在h5端,必须要做一点延时才起作用,this.$nextTick()无效(HX2.4.7)
setTimeout(() => {
this.drawProgressBg();
}, 50)
},
methods: {
drawProgressBg() {
this.ctxBg.setLineWidth(this.borderWidthPx); // 设置圆环宽度
this.ctxBg.setStrokeStyle(this.inactiveColor); // 线条颜色
this.ctxBg.setLineCap('round'); // 圆环端点的形状为圆形
this.ctxBg.beginPath(); // 开始描绘路径
// 设置一个原点(110,110),半径为100的圆的路径到当前路径
this.ctxBg.arc(this.widthPx / 2, this.widthPx / 2, this.widthPx / 2 - this.borderWidthPx / 2 - 1, 0, 2 * Math.PI,
false);
this.ctxBg.stroke(); // 对路径进行描绘
this.ctxBg.draw();
},
drawCircle(step) {
this.ctx.setLineWidth(this.borderWidthPx);
this.ctx.setStrokeStyle(this.circleColor);
this.ctx.setLineCap('round');
this.ctx.beginPath();
// 参数step 为绘制的圆环周长,从0到2为一周 。 -Math.PI / 2 将起始角设在12点钟位置 ,结束角 通过改变 step 的值确定
if (this.mode == 'more') {
this.ctx.arc(this.widthPx / 2, this.widthPx / 2, this.widthPx / 2 - this.borderWidthPx / 2 - 1, -Math.PI / 2, step *
Math.PI - Math.PI / 2, false);
} else {
this.ctx.arc(this.widthPx / 2, this.widthPx / 2, this.widthPx / 2 - this.borderWidthPx / 2 - 1, -Math.PI / 2, Math
.PI / 2 - step *
Math.PI, false);
}
this.ctx.stroke();
this.ctx.draw()
},
countInterval() {
this.countTimer = setInterval(() => {
if (this.count <= this.times) {
// 全一个圆时候,值为2,这里求出每一份的值为2/360
this.drawCircle(this.count * 2 / 360);
this.count++;
} else {
clearInterval(this.countTimer);
}
}, Math.ceil(this.duration / 360)); // 总过渡时间分为360份,这里为每一份的时间
},
}
}
</script>
<style lang="scss" scoped>
.u-circle-progress {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
}
.u-canvas-bg {
position: absolute;
}
.u-canvas {
position: absolute;
}
</style>
<template>
<view class="u-collapse-item">
<view :hover-stay-time="200" class="u-collapse-head" @tap.stop="headClick" :hover-class="hoverClass" :style="[headStyle]">
<view class="u-collapse-title u-line-1" :style="[{ textAlign: align ? align : 'left' },
isShow && activeStyle && !arrow ? activeStyle : '']">
{{ title }}
</view>
<view class="u-icon-wrap">
<u-icon v-if="arrow" :color="arrowColor ? arrowColor : $u.color.tipsColor" :class="{ 'u-arrow-down-icon-active': isShow }"
class="u-arrow-down-icon" name="arrow-down"></u-icon>
</view>
</view>
<view class="u-collapse-body" :style="[{
height: isShow ? height + 'px' : '0'
}, bodyStyle]">
<view class="u-collapse-content" :id="elId">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
/**
* collapseItem 手风琴Item
* @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
* @tutorial https://www.uviewui.com/components/collapse.html
* @property {String} title 面板标题
* @property {String Number} index 主要用于事件的回调,标识那个Item被点击
* @property {Boolean} disabled 面板是否可以打开或收起(默认false)
* @property {Boolean} open 设置某个面板的初始状态是否打开(默认false)
* @property {String Number} name 唯一标识符,如不设置,默认用当前collapse-item的索引值
* @property {String} align 标题的对齐方式(默认left)
* @property {Object} active-style 不显示箭头时,可以添加当前选择的collapse-item活动样式,对象形式
* @event {Function} change 某个item被打开或者收起时触发
* @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
*/
export default {
name: "u-collapse-item",
props: {
// 标题
title: {
type: String,
default: ''
},
// 标题的对齐方式
align: {
type: String,
default: 'left'
},
// 是否可以点击收起
disabled: {
type: Boolean,
default: false
},
// collapse显示与否
open: {
type: Boolean,
default: false
},
// 唯一标识符
name: {
type: [Number, String],
default: ''
},
//活动样式
activeStyle: {
type: Object,
default () {
return {}
}
},
// 标识当前为第几个
index: {
type: [String, Number],
default: ''
}
},
inject: ['uCollapse'],
data() {
return {
isShow: false,
elId: this.$u.guid(),
height: 0, // body内容的高度
headStyle: {}, // 头部样式,对象形式
bodyStyle: {}, // 主体部分样式
arrowColor: '',
hoverClass: '', // 头部按下时的效果样式类
};
},
mounted() {
this.$nextTick(() => {
this.queryRect();
});
},
watch: {
open(val) {
this.isShow = val;
}
},
computed: {
arrow() {
return this.uCollapse.arrow;
},
},
created() {
this.isShow = this.open;
this.nameSync = this.name ? this.name : this.uCollapse.childrens.length;
this.uCollapse.childrens.push(this);
this.headStyle = this.uCollapse.headStyle;
this.bodyStyle = this.uCollapse.bodyStyle;
this.arrowColor = this.uCollapse.arrowColor;
this.hoverClass = this.uCollapse.hoverClass;
},
methods: {
// 点击collapsehead头部
headClick() {
if (this.disabled) return;
if (this.uCollapse.accordion == true) {
this.uCollapse.childrens.map(val => {
// 自身不设置为false,因为后面有this.isShow = !this.isShow;处理了
if (this != val) {
val.isShow = false;
}
});
}
this.isShow = !this.isShow;
// 触发本组件的事件
this.$emit('change', {
index: this.index,
show: this.isShow
})
// 只有在打开时才发出事件
if (this.isShow) this.uCollapse.onChange();
this.$forceUpdate();
},
// 查询内容高度
queryRect() {
const query = uni.createSelectorQuery().in(this);
query
.select('#' + this.elId)
.boundingClientRect(data => {
if (!data.height) {
setTimeout(() => {
this.queryRect();
}, 10);
return;
}
this.height = data.height;
})
.exec();
}
}
};
</script>
<style lang="scss" scoped>
.u-collapse-head {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
color: $u-main-color;
}
.u-collapse-title {
flex: 1;
overflow: hidden;
margin-right: 14rpx;
font-size: 30rpx;
color: $u-main-color;
line-height: 1;
padding: 24rpx 0;
text-align: left;
}
.u-arrow-down-icon {
transition: all 0.3s;
margin-right: 24rpx;
}
.u-arrow-down-icon-active {
transform: rotate(180deg);
transform-origin: center center;
}
.u-collapse-body {
overflow: hidden;
transition: all 0.3s;
}
.u-collapse-content {
overflow: hidden;
font-size: 28rpx;
color: $u-tips-color;
text-align: left;
}
<template>
<view class="u-collapse-item">
<view :hover-stay-time="200" class="u-collapse-head" @tap.stop="headClick" :hover-class="hoverClass" :style="[headStyle]">
<view class="u-collapse-title u-line-1" :style="[{ textAlign: align ? align : 'left' },
isShow && activeStyle && !arrow ? activeStyle : '']">
{{ title }}
</view>
<view class="u-icon-wrap">
<u-icon v-if="arrow" :color="arrowColor ? arrowColor : $u.color.tipsColor" :class="{ 'u-arrow-down-icon-active': isShow }"
class="u-arrow-down-icon" name="arrow-down"></u-icon>
</view>
</view>
<view class="u-collapse-body" :style="[{
height: isShow ? height + 'px' : '0'
}, bodyStyle]">
<view class="u-collapse-content" :id="elId">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
/**
* collapseItem 手风琴Item
* @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
* @tutorial https://www.uviewui.com/components/collapse.html
* @property {String} title 面板标题
* @property {String Number} index 主要用于事件的回调,标识那个Item被点击
* @property {Boolean} disabled 面板是否可以打开或收起(默认false)
* @property {Boolean} open 设置某个面板的初始状态是否打开(默认false)
* @property {String Number} name 唯一标识符,如不设置,默认用当前collapse-item的索引值
* @property {String} align 标题的对齐方式(默认left)
* @property {Object} active-style 不显示箭头时,可以添加当前选择的collapse-item活动样式,对象形式
* @event {Function} change 某个item被打开或者收起时触发
* @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
*/
export default {
name: "u-collapse-item",
props: {
// 标题
title: {
type: String,
default: ''
},
// 标题的对齐方式
align: {
type: String,
default: 'left'
},
// 是否可以点击收起
disabled: {
type: Boolean,
default: false
},
// collapse显示与否
open: {
type: Boolean,
default: false
},
// 唯一标识符
name: {
type: [Number, String],
default: ''
},
//活动样式
activeStyle: {
type: Object,
default () {
return {}
}
},
// 标识当前为第几个
index: {
type: [String, Number],
default: ''
}
},
inject: ['uCollapse'],
data() {
return {
isShow: false,
elId: this.$u.guid(),
height: 0, // body内容的高度
headStyle: {}, // 头部样式,对象形式
bodyStyle: {}, // 主体部分样式
arrowColor: '',
hoverClass: '', // 头部按下时的效果样式类
};
},
mounted() {
this.$nextTick(() => {
this.queryRect();
});
},
watch: {
open(val) {
this.isShow = val;
}
},
computed: {
arrow() {
return this.uCollapse.arrow;
},
},
created() {
this.isShow = this.open;
this.nameSync = this.name ? this.name : this.uCollapse.childrens.length;
this.uCollapse.childrens.push(this);
this.headStyle = this.uCollapse.headStyle;
this.bodyStyle = this.uCollapse.bodyStyle;
this.arrowColor = this.uCollapse.arrowColor;
this.hoverClass = this.uCollapse.hoverClass;
},
methods: {
// 点击collapsehead头部
headClick() {
if (this.disabled) return;
if (this.uCollapse.accordion == true) {
this.uCollapse.childrens.map(val => {
// 自身不设置为false,因为后面有this.isShow = !this.isShow;处理了
if (this != val) {
val.isShow = false;
}
});
}
this.isShow = !this.isShow;
// 触发本组件的事件
this.$emit('change', {
index: this.index,
show: this.isShow
})
// 只有在打开时才发出事件
if (this.isShow) this.uCollapse.onChange();
this.$forceUpdate();
},
// 查询内容高度
queryRect() {
const query = uni.createSelectorQuery().in(this);
query
.select('#' + this.elId)
.boundingClientRect(data => {
if (!data.height) {
setTimeout(() => {
this.queryRect();
}, 10);
return;
}
this.height = data.height;
})
.exec();
}
}
};
</script>
<style lang="scss" scoped>
.u-collapse-head {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
color: $u-main-color;
}
.u-collapse-title {
flex: 1;
overflow: hidden;
margin-right: 14rpx;
font-size: 30rpx;
color: $u-main-color;
line-height: 1;
padding: 24rpx 0;
text-align: left;
}
.u-arrow-down-icon {
transition: all 0.3s;
margin-right: 24rpx;
}
.u-arrow-down-icon-active {
transform: rotate(180deg);
transform-origin: center center;
}
.u-collapse-body {
overflow: hidden;
transition: all 0.3s;
}
.u-collapse-content {
overflow: hidden;
font-size: 28rpx;
color: $u-tips-color;
text-align: left;
}
</style>
<template>
<view class="u-collapse">
<slot />
</view>
</template>
<script>
/**
* collapse 手风琴
* @description 通过折叠面板收纳内容区域
* @tutorial https://www.uviewui.com/components/collapse.html
* @property {Boolean} accordion 是否手风琴模式(默认true)
* @property {Boolean} arrow 是否显示标题右侧的箭头(默认true)
* @property {String} arrow-color 标题右侧箭头的颜色(默认#909399)
* @property {String} head-bg-color 标题的背景颜色(默认#ffffff)
* @property {String} body-bg-color 主体内容的背景颜色(默认#ffffff)
* @property {String} hover-class 样式类名,按下时有效(默认u-hover-class)
* @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
* @example <u-collapse></u-collapse>
*/
<template>
<view class="u-collapse">
<slot />
</view>
</template>
<script>
/**
* collapse 手风琴
* @description 通过折叠面板收纳内容区域
* @tutorial https://www.uviewui.com/components/collapse.html
* @property {Boolean} accordion 是否手风琴模式(默认true)
* @property {Boolean} arrow 是否显示标题右侧的箭头(默认true)
* @property {String} arrow-color 标题右侧箭头的颜色(默认#909399)
* @property {String} head-bg-color 标题的背景颜色(默认#ffffff)
* @property {String} body-bg-color 主体内容的背景颜色(默认#ffffff)
* @property {String} hover-class 样式类名,按下时有效(默认u-hover-class)
* @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
* @example <u-collapse></u-collapse>
*/
export default {
name:"u-collapse",
props: {
// 是否手风琴模式
accordion: {
type: Boolean,
default: true
},
// 头部的样式
headStyle: {
type: Object,
default () {
return {}
}
},
// 主体的样式
bodyStyle: {
type: Object,
default () {
return {}
}
},
// 是否显示右侧的箭头
arrow: {
type: Boolean,
default: true
},
// 箭头的颜色
arrowColor: {
type: String,
default: ''
},
// 标题部分按压时的样式类,"none"为无效果
hoverClass: {
type: String,
default: 'u-hover-class'
}
},
provide() {
return {
uCollapse: this
}
},
created() {
this.childrens = []
},
data() {
return {
}
},
methods: {
// collapse item被点击,由collapse item调用父组件方法
onChange() {
let activeItem = [];
this.childrens.forEach((vm, index) => {
if (vm.isShow) {
activeItem.push(vm.nameSync);
}
})
// 如果是手风琴模式,只有一个匹配结果,也即activeItem长度为1,将其转为字符串
if (this.accordion) activeItem = activeItem.join('');
this.$emit('change', activeItem);
}
}
}
</script>
<style lang="scss" scoped>
name:"u-collapse",
props: {
// 是否手风琴模式
accordion: {
type: Boolean,
default: true
},
// 头部的样式
headStyle: {
type: Object,
default () {
return {}
}
},
// 主体的样式
bodyStyle: {
type: Object,
default () {
return {}
}
},
// 是否显示右侧的箭头
arrow: {
type: Boolean,
default: true
},
// 箭头的颜色
arrowColor: {
type: String,
default: ''
},
// 标题部分按压时的样式类,"none"为无效果
hoverClass: {
type: String,
default: 'u-hover-class'
}
},
provide() {
return {
uCollapse: this
}
},
created() {
this.childrens = []
},
data() {
return {
}
},
methods: {
// collapse item被点击,由collapse item调用父组件方法
onChange() {
let activeItem = [];
this.childrens.forEach((vm, index) => {
if (vm.isShow) {
activeItem.push(vm.nameSync);
}
})
// 如果是手风琴模式,只有一个匹配结果,也即activeItem长度为1,将其转为字符串
if (this.accordion) activeItem = activeItem.join('');
this.$emit('change', activeItem);
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<view class="u-empty" v-if="show" :style="{
marginTop: marginTop + 'rpx'
}">
<image class="u-image" :src="src ? src : icons[mode].image" mode="widthFix" :style="{
width: imgWidth + 'rpx',
height: imgHeight == 'auto' ? 'auto' : imgHeight + 'rpx'
}"></image>
<text :style="{
color: color,
fontSize: fontSize + 'rpx',
}">
{{text ? text : icons[mode].text}}
</text>
<view class="u-slot-wrap">
<slot name="bottom"></slot>
</view>
</view>
</template>
<script>
import icon from "./icon.js";
/**
* empty 内容为空
* @description 该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。
* @tutorial https://www.uviewui.com/components/empty.html
* @property {String} color 文字颜色(默认#c0c4cc)
* @property {String} text 文字提示(默认“无内容”)
* @property {String} src 自定义图标路径,如定义,mode参数会失效
* @property {String Number} font-size 提示文字的大小,单位rpx(默认28)
* @property {String} mode 内置的图标,见官网说明(默认data)
* @property {String Number} img-width 图标的宽度,单位rpx(默认240)
* @property {String} img-height 图标的高度,单位rpx(默认auto)
* @property {String Number} margin-top 组件距离上一个元素之间的距离(默认0)
* @property {Boolean} show 是否显示组件(默认true)
* @event {Function} click 点击组件时触发
* @event {Function} close 点击关闭按钮时触发
* @example <u-empty text="所谓伊人,在水一方" mode="list"></u-empty>
*/
export default {
name: "u-empty",
props: {
// 图标路径
src: {
type: String,
default: ''
},
// 提示文字
text: {
type: String,
default: ''
},
// 文字颜色
color: {
type: String,
default: '#c0c4cc'
},
// 文字大小,单位rpx
fontSize: {
type: [String, Number],
default: 26
},
// 选择预置的图标类型
mode: {
type: String,
default: 'data'
},
// 图标宽度,单位rpx
imgWidth: {
type: [String, Number],
default: 240
},
// 图标高度,单位rpx
imgHeight: {
type: [String, Number],
default: 'auto'
},
// 是否显示组件
show: {
type: Boolean,
default: true
},
// 组件距离上一个元素之间的距离
marginTop: {
type: [String, Number],
default: 0
}
},
data() {
return {
icons: icon
}
}
}
</script>
<style lang="scss" scoped>
.u-empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-top: 30%;
}
.u-image {
margin-bottom: 20rpx;
}
.u-slot-wrap {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
}
<template>
<view class="u-empty" v-if="show" :style="{
marginTop: marginTop + 'rpx'
}">
<image class="u-image" :src="src ? src : icons[mode].image" mode="widthFix" :style="{
width: imgWidth + 'rpx',
height: imgHeight == 'auto' ? 'auto' : imgHeight + 'rpx'
}"></image>
<text :style="{
color: color,
fontSize: fontSize + 'rpx',
}">
{{text ? text : icons[mode].text}}
</text>
<view class="u-slot-wrap">
<slot name="bottom"></slot>
</view>
</view>
</template>
<script>
import icon from "./icon.js";
/**
* empty 内容为空
* @description 该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。
* @tutorial https://www.uviewui.com/components/empty.html
* @property {String} color 文字颜色(默认#c0c4cc)
* @property {String} text 文字提示(默认“无内容”)
* @property {String} src 自定义图标路径,如定义,mode参数会失效
* @property {String Number} font-size 提示文字的大小,单位rpx(默认28)
* @property {String} mode 内置的图标,见官网说明(默认data)
* @property {String Number} img-width 图标的宽度,单位rpx(默认240)
* @property {String} img-height 图标的高度,单位rpx(默认auto)
* @property {String Number} margin-top 组件距离上一个元素之间的距离(默认0)
* @property {Boolean} show 是否显示组件(默认true)
* @event {Function} click 点击组件时触发
* @event {Function} close 点击关闭按钮时触发
* @example <u-empty text="所谓伊人,在水一方" mode="list"></u-empty>
*/
export default {
name: "u-empty",
props: {
// 图标路径
src: {
type: String,
default: ''
},
// 提示文字
text: {
type: String,
default: ''
},
// 文字颜色
color: {
type: String,
default: '#c0c4cc'
},
// 文字大小,单位rpx
fontSize: {
type: [String, Number],
default: 26
},
// 选择预置的图标类型
mode: {
type: String,
default: 'data'
},
// 图标宽度,单位rpx
imgWidth: {
type: [String, Number],
default: 240
},
// 图标高度,单位rpx
imgHeight: {
type: [String, Number],
default: 'auto'
},
// 是否显示组件
show: {
type: Boolean,
default: true
},
// 组件距离上一个元素之间的距离
marginTop: {
type: [String, Number],
default: 0
}
},
data() {
return {
icons: icon
}
}
}
</script>
<style lang="scss" scoped>
.u-empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-top: 30%;
}
.u-image {
margin-bottom: 20rpx;
}
.u-slot-wrap {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
}
</style>
......@@ -12,7 +12,7 @@
}" @tap="rightClick">
{{subTitle}}
<view class="u-icon-arrow">
<u-icon name="arrow-right" size="22" :color="subColor"></u-icon>
<u-icon name="arrow-right" size="24" :color="subColor"></u-icon>
</view>
</view>
</view>
......@@ -101,8 +101,7 @@
.u-section-title:after {
position: absolute;
width: 4px;
top: -1px;
height: 16px;
height: 100%;
content: '';
left: 0;
border-radius: 10px;
......
This diff is collapsed.
......@@ -52,6 +52,11 @@
value: {
type: Boolean,
default: false
},
// 是否使手机发生短促震动,目前只在iOS的微信小程序有效(2020-05-06)
vibrateShort: {
type: Boolean,
default: false
}
},
data() {
......@@ -74,7 +79,7 @@
onClick() {
if (!this.disabled && !this.loading) {
// 使手机产生短促震动,微信小程序有效,APP(HX 2.6.8)和H5无效
uni.vibrateShort();
if(this.vibrateShort) uni.vibrateShort();
this.$emit('input', !this.value);
// 放到下一个生命周期,因为双向绑定的value修改父组件状态需要时间,且是异步的
this.$nextTick(function() {
......
This diff is collapsed.
// 此版本发布于2020-04-30
let version = '1.1.5';
// 此版本发布于2020-05-05
let version = '1.1.7';
export default {
v: version,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment