Commit ed38b1a6 authored by 郝聪敏's avatar 郝聪敏

替换vant版本;新增分享、抽奖弹窗

parent 36b4ed06
...@@ -6248,11 +6248,6 @@ ...@@ -6248,11 +6248,6 @@
"builtins": "^1.0.3" "builtins": "^1.0.3"
} }
}, },
"vant-weapp": {
"version": "0.5.28",
"resolved": "http://npmprivate.quantgroups.com/vant-weapp/-/vant-weapp-0.5.28.tgz",
"integrity": "sha512-GAJ2PTLuhXHWpAD5B7DdRQdkEFMdjdduuMzKkThUjIiQ63ESnaJvIEUbW3RgiUNNV7PYXwhOFOd6woR/JsTFLA=="
},
"verror": { "verror": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "http://npmprivate.quantgroups.com/verror/-/verror-1.10.0.tgz", "resolved": "http://npmprivate.quantgroups.com/verror/-/verror-1.10.0.tgz",
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@wepy/core": "^2.0.0-alpha.16", "@wepy/core": "^2.0.0-alpha.16",
"@wepy/x": "^2.0.2", "@wepy/x": "^2.0.2"
"vant-weapp": "^0.5.28"
}, },
"devDependencies": { "devDependencies": {
"@wepy/cli": "^2.0.0-alpha.28", "@wepy/cli": "^2.0.0-alpha.28",
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</style> </style>
<script> <script>
import wepy from '@wepy/core'; import wepy from '@wepy/core';
import eventHub from './common/eventHub'; import http from './common/wxRequest';
import vuex from '@wepy/x'; import vuex from '@wepy/x';
wepy.use(vuex); wepy.use(vuex);
...@@ -18,13 +18,25 @@ wepy.app({ ...@@ -18,13 +18,25 @@ wepy.app({
statusBarHeight: '' statusBarHeight: ''
}, },
onLaunch() { onLaunch() {
// this.$options.globalData.info = '333';
let that = this; let that = this;
wx.getSystemInfo({ wx.getSystemInfo({
success: function (res) { success: function (res) {
that.$options.globalData.statusBarHeight = res.statusBarHeight; that.$options.globalData.statusBarHeight = res.statusBarHeight;
} }
}); });
if (!wx.getStorageSync('openId')) {
wx.login({
success (res) {
if (res.code) {
// 发起网络请求,告诉后端
http.post('/');
wx.setStorageSync('wxCode', res.code);
} else {
console.log('登录失败!' + res.errMsg);
}
}
});
}
wx.checkSession({ wx.checkSession({
success () { success () {
console.log('已登录'); console.log('已登录');
...@@ -56,7 +68,10 @@ wepy.app({ ...@@ -56,7 +68,10 @@ wepy.app({
{ {
pages: [ pages: [
'pages/index', 'pages/index',
'pages/raffle' 'pages/raffle',
'pages/awards',
'pages/help',
'pages/feedback'
], ],
window: { window: {
backgroundTextStyle: 'light', backgroundTextStyle: 'light',
......
import http from './wxRequest';
module.exports = {
login() {
return http.post();
}
};
import wepy from 'wepy'; import wepy from '@wepy/core';
const baseUrl = 'localhost:8000';
const request = (url, options) => {
const defaultOptions = {
method: 'post',
header: { 'content-type': 'applicction/x-www-form-urlencoded' }
};
options = { ...defaultOptions, ...options };
url = baseUrl + url;
const wxRequest = async (params = {}, url) => {
console.log('wxRequest', params);
const isConnected = wx.getStorageSync('onNetworkStatusChange'); const isConnected = wx.getStorageSync('onNetworkStatusChange');
if (!isConnected) { if (!isConnected) {
wx.showToast({ wx.showToast({
...@@ -11,20 +19,49 @@ const wxRequest = async (params = {}, url) => { ...@@ -11,20 +19,49 @@ const wxRequest = async (params = {}, url) => {
}); });
return; return;
} }
// tip.loading()
let data = params.query || {}; const promise = new Promise((resolve, reject) => {
const header = params.header || {}; wepy.request({
let res = await wepy.request({
url: url, url: url,
method: params.method || 'GET', data: options.data,
data: data, method: options.method,
header: header header: options.header,
success: res => {
if (res.statusCode == 200) {
if (res.data.code == '2000') {
resolve(res.data.data);
}
}
reject(res);
},
fail: res => {
reject(res);
}
}); });
// tip.loaded() });
console.log('wxRequest', res); return promise;
return res; };
const post = (url, data, header) => {
const options = {
method: 'post',
data,
header
};
if (!header) delete options.header;
return request(url, options);
};
const get = (url, data) => {
const options = {
method: 'get',
data
};
return request(url, options);
}; };
module.exports = { module.exports = {
wxRequest post: post,
get: get,
request
}; };
This diff is collapsed.
<template>
<div v-if="show" class="{{hide ? 'popup-container popup-container_hide' : 'popup-container popup-container_show'}}" @tap="hideMenu" >
<div style="{{popupStyle}}" class="{{hide ? 'popup-wrapper popup-wrapper_hide': 'popup-wrapper popup-wrapper_show'}}">
<div class="popup-item" v-for="item in menus" @tap.stop="goNextPage(item.path)">
<image class="image" :src="item.img"></image>
<span class="desc">{{item.title}}</span>
</div>
</div>
</div>
</template>
<script>
import wepy from '@wepy/core';
wepy.component({
props: {
showMenus: {
type: Boolean,
default: false
}
},
data: {
menus: [
{ img: '/static/images/awards@2x.png', title: '我的抽奖', path: '/pages/awards' },
{ img: '/static/images/feedback@2x.png', title: '规则与帮助', path: '/pages/feedback' },
{ img: '/static/images/help@2x.png', title: '问题反馈', path: '/pages/help' }
],
show: false,
popupStyle: ''
},
watch: {
showMenus(v) {
if (!v) {
setTimeout(() => {
this.show = false;
}, 300);
} else {
this.show = true;
}
}
},
computed: {
hide() {
return !this.showMenus;
}
},
methods: {
hideMenu: function() {
this.$emit('showMenu', false);
},
goNextPage: function(path) {
this.$emit('showMenu', false);
wx.navigateTo({
url: path
});
}
},
created() {
let statusHeight = this.$app.$options.globalData.statusBarHeight || '';
statusHeight && (this.popupStyle = 'top:' + (statusHeight + 56) + 'px');
}
});
</script>
<style lang="less">
.popup-container {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 9;
// animation: menuEnter .3s linear forwards;
.popup-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
width: 350rpx;
height: 114rpx;
position: absolute;
left: 20rpx;
top: 155rpx;
background: #fff;
border-radius: 10rpx;
padding: 10rpx 19rpx;
box-sizing: border-box;
// animation: menuShow .3s linear forwards;
&:before {
position: absolute;
top: -29rpx;
left: 35rpx;
content: "";
width: 0;
height: 0;
border-top: 0;
border-left: 15rpx solid transparent;
border-right: 15rpx solid transparent;
border-bottom: 30rpx solid #fff;
}
.popup-item {
display: flex;
flex-direction: column;
align-items: center;
.image {
width: 50rpx;
height: 50rpx;
}
.desc {
color: #FF5D15;
font-size: 20rpx;
margin-top: 9rpx
}
}
}
.popup-wrapper_show{
animation: menuShow .3s linear forwards;
}
.popup-wrapper_hide {
animation: menuHides .3s linear forwards;
}
}
.popup-container_hide {
animation: menuLeave .3s linear forwards;
}
.popup-container_show {
animation: menuEnter .3s linear forwards;
}
@keyframes menuLeave {
from { background: rgba(0, 0, 0, 0.7); }
to { background: rgba(0, 0, 0, 0); }
}
@keyframes menuHides {
0% {
transform: none;
opacity: 1;
}
100% {
transform: translate3d(0, -5%, 0);
opacity: 0;
}
}
@keyframes menuEnter {
from { background: rgba(0, 0, 0, 0); }
to { background: rgba(0, 0, 0, 0.7); }
}
@keyframes menuShow {
0% {
transform: translate3d(0, -5%, 0);
opacity: 0;
}
100% {
transform: none;
opacity: 1;
}
}
</style>
<template>
<div class="share-container" @tap="hideMenu" >
<div class="dialog">
<div class="star">
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
<image class="star-image" src="/static/images/star@2x.png"></image>
</div>
<div class="gold">
<image class="gold-image" src="/static/images/gold-bg@2x.png"></image>
<image class="gold-image" src="/static/images/gold-bg@2x.png"></image>
<image class="gold-image" src="/static/images/gold-bg@2x.png"></image>
<image class="gold-image" src="/static/images/gold-bg@2x.png"></image>
</div>
<div class="content">
<div class="des">恭喜您!</div>
<image class="image" src="/static/images/gold@2x.png"></image>
<div class="info">通过邀请以下好友,您获得15克币</div>
<div class="user">
<image class="user-img" src="/static/images/test1.jpg"></image>
<image class="user-img" src="/static/images/test1.jpg"></image>
<image class="user-img" src="/static/images/test1.jpg"></image>
</div>
</div>
<div class="dialog-footer">
<button class="btn" @tap="go">立即领取</button>
</div>
</div>
</div>
</template>
<script>
import wepy from '@wepy/core';
wepy.component({
props: {
showMenus: {
type: Boolean,
default: false
}
},
data: {
menus: [
{ img: '/static/images/awards@2x.png', title: '我的抽奖', path: '/pages/awards' },
{ img: '/static/images/feedback@2x.png', title: '规则与帮助', path: '/pages/feedback' },
{ img: '/static/images/help@2x.png', title: '问题反馈', path: '/pages/help' }
],
show: false,
popupStyle: ''
},
watch: {
showMenus(v) {
if (!v) {
setTimeout(() => {
this.show = false;
}, 300);
} else {
this.show = true;
}
}
},
computed: {
hide() {
return !this.showMenus;
}
},
methods: {
getAwards: function() {
this.show = false;
}
}
});
</script>
<style lang="less">
.share-container {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
.dialog {
position: relative;
width: 530rpx;
height: 530rpx;
border-radius: 20rpx;
color: #fff;
background: linear-gradient(#E6401F, #FDA13E),
;
padding: 39rpx 40rpx 0rpx 40rpx;
z-index: 10;
.star {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: url('http://activitystatic.xyqb.com/light-1@2x.png') 0% 0%/contain no-repeat;
.star-image {
&:nth-child(1) {
position: absolute;
top: 120rpx;
left: 32rpx;
width: 86rpx;
height: 86rpx;
}
&:nth-child(2) {
position: absolute;
top: 70rpx;
left: 121rpx;
width: 55rpx;
height: 55rpx;
transform: rotateZ(20deg);
filter: blur(5rpx);
}
&:nth-child(3) {
position: absolute;
top: 110rpx;
left: 349rpx;
width: 58rpx;
height: 58rpx;
transform: rotateZ(30deg);
filter: blur(3rpx);
}
&:nth-child(4) {
position: absolute;
top: 89rpx;
left: 471rpx;
width: 50rpx;
height: 50rpx;
transform: rotateZ(15deg);
filter: blur(5rpx);
}
&:nth-child(5) {
position: absolute;
top: 250rpx;
left: 14rpx;
width: 50rpx;
height: 50rpx;
transform: rotateZ(25deg);
filter: blur(6rpx);
}
&:nth-child(6) {
position: absolute;
top: 223rpx;
left: 145rpx;
width: 57rpx;
height: 57rpx;
transform: rotateZ(23deg);
filter: blur(3rpx);
}
&:nth-child(7) {
position: absolute;
top: 223rpx;
left: 391rpx;
width: 68rpx;
height: 68rpx;
transform: rotateZ(20deg);
filter: blur(2rpx);
}
&:nth-child(8) {
position: absolute;
top: 318rpx;
left: 494rpx;
width: 51rpx;
height: 51rpx;
transform: rotateZ(15deg);
filter: blur(5rpx);
}
}
}
.gold {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
.gold-image {
&:nth-child(1) {
position: absolute;
top: 227rpx;
left: -51rpx;
width: 78rpx;
height: 78rpx;
}
&:nth-child(2) {
position: absolute;
top: -38rpx;
left: 180rpx;
width: 56rpx;
height: 56rpx;
filter: blur(3rpx);
}
&:nth-child(3) {
position: absolute;
top: 85rpx;
left: 580rpx;
width: 86rpx;
height: 86rpx;
filter: blur(2px);
}
&:nth-child(4) {
position: absolute;
top: 380rpx;
left: 560rpx;
width: 98rpx;
height: 98rpx;
filter: blur(2rpx);
}
}
}
.content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.des {
font-size: 40rpx;
}
.image {
width: 150rpx;
height: 164rpx;
margin: 29rpx auto;
z-index: 11;
}
.info {
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 28rpx;
text-align: center;
}
.user {
height: 84rpx;
width: 210rpx;
line-height: 84rpx;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
.user-img {
width: 50rpx;
height: 50rpx;
border-radius: 50%;
}
&:after {
content: '...';
position: absolute;
bottom: -5rpx;
right: -46rpx;
}
}
}
.dialog-footer {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 120rpx;
z-index: 11;
.btn {
font-size: 30rpx;
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
z-index: 11;
border-radius: 10rpx;
background: #FF5D15;
color: #FFF;
&:before {
content: '';
width: 73rpx;
height: 43rpx;
position: absolute;
background: url('http://activitystatic.xyqb.com/btn-shadow@2x.png') center center/contain no-repeat;
top: 3rpx;
left: 4rpx;
};
}
}
}
}
</style>
<template> <template>
<div class="icon-container"> <div style="{{containerStyle}}" class="icon-container">
<star-animation v-if='flyAnimation'></star-animation>
<div class="sign" v-if="type === 'sign'" @tap="signIn"> <div class="sign" v-if="type === 'sign'" @tap="signIn">
<image class="sign-in" :src="signNotCompletedUrl" v-if="!signComplete" :class="{'jump': !sign, 'fly': sign}" ></image> <image class="sign-in" :src="signNotCompletedUrl" v-if="!signComplete" :class="{'jump': !sign, 'fly': sign}" ></image>
<image class="sign-comlete" :src="signCompletedUrl" v-if="sign"></image> <image class="sign-comlete" :src="signCompletedUrl" v-if="sign"></image>
...@@ -10,7 +11,7 @@ ...@@ -10,7 +11,7 @@
<div v-if="type === 'gold'" class="gold"> <div v-if="type === 'gold'" class="gold">
<div class="add-gold" v-if="addGold"> <div class="add-gold" v-if="addGold">
<image class="add-gold-image" :src="addGoldUrl"></image> <image class="add-gold-image" :src="addGoldUrl"></image>
<span class="add-gold-num">+1</span> <span class="add-gold-num">+10</span>
</div> </div>
<div class="show-gold" @tap="showAnimation"> <div class="show-gold" @tap="showAnimation">
<div class="sunshine" v-if="addsunshine"></div> <div class="sunshine" v-if="addsunshine"></div>
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
<button open-type="share" plain="true" class="share-button"> <button open-type="share" plain="true" class="share-button">
<image class="share-image" :src="shareUrl"></image> <image class="share-image" :src="shareUrl"></image>
</button> </button>
<span class="title">{{des}}</span>
</div> </div>
<div v-if="type === 'lottery'" class="lottery"> <div v-if="type === 'lottery'" class="lottery">
<image class="lottery-image" :src="lotteryUrl"></image> <image class="lottery-image" :src="lotteryUrl"></image>
...@@ -60,7 +62,9 @@ ...@@ -60,7 +62,9 @@
signNotCompletedUrl: '/static/images/sign@2x.png', signNotCompletedUrl: '/static/images/sign@2x.png',
signCompletedUrl: '/static/images/sign-completed@2x-70_70px.png', signCompletedUrl: '/static/images/sign-completed@2x-70_70px.png',
shareUrl: '/static/images/share@2x.png', shareUrl: '/static/images/share@2x.png',
lotteryUrl: '/static/images/lottery@2x.png' lotteryUrl: '/static/images/lottery@2x.png',
containerStyle: '',
flyAnimation: false
}, },
props: { props: {
title: '', title: '',
...@@ -125,14 +129,16 @@ ...@@ -125,14 +129,16 @@
}, },
sign(v) { sign(v) {
this.signComplete = false; this.signComplete = false;
this.flyAnimation = false;
console.log(v, this.signComplete); console.log(v, this.signComplete);
if (!v) { if (!v) {
timeout = null; timeout = null;
} else { } else {
timeout = setTimeout(() => { timeout = setTimeout(() => {
this.signComplete = true; this.signComplete = true;
this.flyAnimation = true;
console.log('signComplete'); console.log('signComplete');
}, 1300); }, 1100);
} }
} }
}, },
...@@ -149,7 +155,9 @@ ...@@ -149,7 +155,9 @@
} }
}, },
created() { created() {
console.log(this.type); let statusHeight = this.$app.$options.globalData.statusBarHeight || '';
statusHeight && (this.containerStyle = 'position:relative; top:' + statusHeight + 'px');
console.log(this.type, this.$app.$options.globalData.statusBarHeight, this.containerStyle);
} }
}); });
</script> </script>
...@@ -158,8 +166,8 @@ ...@@ -158,8 +166,8 @@
.lottery { .lottery {
position: absolute; position: absolute;
top: 513rpx; top: 469rpx;
right: 30rpx; right: 32rpx;
.lottery-image { .lottery-image {
display: flex; display: flex;
width: 78rpx; width: 78rpx;
...@@ -176,8 +184,8 @@ ...@@ -176,8 +184,8 @@
.share { .share {
position: absolute; position: absolute;
top: 679rpx; top: 635rpx;
right: 33rpx; right: 32rpx;
.share-button { .share-button {
width: 78rpx; width: 78rpx;
height: 70rpx; height: 70rpx;
...@@ -188,11 +196,18 @@ ...@@ -188,11 +196,18 @@
height: 70rpx; height: 70rpx;
} }
} }
.title {
width: 100%;
text-align: center;
display: block;
color: #fff;
font-size: 22rpx;
}
} }
.sign { .sign {
position: absolute; position: absolute;
top: 356rpx; top: 312rpx;
right: 32rpx; right: 32rpx;
width: 78rpx; width: 78rpx;
height: 78rpx; height: 78rpx;
...@@ -213,7 +228,7 @@ ...@@ -213,7 +228,7 @@
animation: jump 1.2s infinite ease; animation: jump 1.2s infinite ease;
} }
.fly { .fly {
animation: fly1 1.2s forwards linear; animation: fly1 1s forwards linear;
} }
.sign-shine { .sign-shine {
overflow: hidden; overflow: hidden;
...@@ -247,7 +262,7 @@ ...@@ -247,7 +262,7 @@
top: 65rpx; top: 65rpx;
border-radius: 50%; border-radius: 50%;
z-index: -1; z-index: -1;
animation: swift 1.2s infinite ease; animation: swift 1s infinite ease;
} }
.title { .title {
...@@ -318,8 +333,8 @@ ...@@ -318,8 +333,8 @@
.gold { .gold {
position: absolute; position: absolute;
top: 270rpx; top: 130rpx;
left: 39rpx; left: 40rpx;
.add-gold{ .add-gold{
position: absolute; position: absolute;
display: flex; display: flex;
...@@ -329,19 +344,21 @@ ...@@ -329,19 +344,21 @@
// transform: translateY(-50rpx); // transform: translateY(-50rpx);
animation:addGold .6s ease-in forwards; animation:addGold .6s ease-in forwards;
.add-gold-image { .add-gold-image {
width: 35rpx; width: 20rpx;
height: 35rpx; height: 20rpx;
vertical-align: middle;
animation:addGoldRotate .6s linear infinite; animation:addGoldRotate .6s linear infinite;
} }
.add-gold-num { .add-gold-num {
color: #fff; color: #fff;
font-size: 24rpx; font-size: 16rpx;
vertical-align: middle;
} }
} }
@keyframes addGold { @keyframes addGold {
0% { transform: translateY(-90rpx);} 0% { transform: translateY(-45rpx);}
99% { transform: translateY(-30rpx);opacity: 1;} 99% { transform: translateY(-20rpx);opacity: 1;}
100% { opacity: 0; } 100% { opacity: 0; }
} }
...@@ -401,7 +418,8 @@ ...@@ -401,7 +418,8 @@
<config> <config>
{ {
usingComponents: { usingComponents: {
'van-icon': '~@/components/vant/icon/index' 'van-icon': '~@/components/vant/icon/index',
'star-animation': '~@/components/custom/starAnimation'
} }
} }
</config> </config>
<template> <template>
<div class="loading-container"> <!-- <div class="loading-container"> -->
<!-- <van-loading size="24px" vertical>加载中...</van-loading> --> <!-- <van-loading size="24px" vertical>加载中...</van-loading> -->
<div class="loader"> <div class="meteor">
<div class="face"> <div class="star"></div>
<div class="circle"></div>
</div>
</div>
</div> </div>
<!-- </div> -->
</template> </template>
<script> <script>
import wepy from '@wepy/core'; import wepy from '@wepy/core';
wepy.component({ wepy.component({
methods: {
onShareAppMessage: function(res) {
if (res.from === 'button') {
console.log('onShareAppMessage1', res.target);
}
}
}
}); });
</script> </script>
<style lang="less"> <style lang="less">
.loading-container { // .loading-container {
// position: absolute;
// width: 100%;
// height: 100%;
// display: flex;
// justify-content: center;
// align-items: center;
// z-index: 1;
.meteor {
position: absolute; position: absolute;
width: 100%; top: 153rpx;
height: 100%; left: 94rpx;
background: grey; width: calc(100% - 170rpx);;
display: flex; height: 0;
justify-content: center; // border: 2rpx solid #000;
align-items: center; z-index: 10;
z-index: 1; transform: rotateZ(-2deg)
.loader {
width: 20em;
height: 20em;
font-size: 10px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
.face {
position: absolute;
border-radius: 50%;
border-style: solid;
animation: animate 3s linear infinite;
&:nth-child(1) {
width: 100%;
height: 100%;
color: black;
border-color: currentColor transparent transparent currentColor;
border-width: 0.2em 0.2em 0 0;
--deg: -45deg;
animation-direction: normal;
} }
.circle { .star {
position: absolute; position: absolute;
width: 50%; left: -3rpx;
height: 0.1em; // bottom: -220rpx;
top: 50%; top: -4rpx;
left: 50%; // left: -43%;
background-color: transparent; height: 10rpx;
transform: rotate(var(--deg)); width: 150rpx;
transform-origin: left; background: linear-gradient(-45deg,rgba(255,255,255,0),yellow);
&::before { transform: translateX(605rpx);
// background: -webkit-linear-gradient(-45deg,rgba(255,255,255,0),yellow);
/*此处为下一步的添加动画*/
// -webkit-animation: tail 1s ease-in forwards, shooting 1s ease-in forwards;
// -o-animation: tail 1s ease-in forwards, shooting 1s ease-in forwards;
animation: tail .6s ease-in forwards, shooting .6s ease-in forwards;
}
.star::before{
content: "";
position: absolute; position: absolute;
top: -0.5em; top: -29rpx;
right: -0.5em; left: -52rpx;
content: ''; width: 78rpx;
width: 1em; height: 78rpx;
height: 1em; // top: calc(100% - 1px);
background-color: currentColor; // left: 100%;
border-radius: 50%; background: url('http://activitystatic.xyqb.com/sign@2x.png') 0 0/contain no-repeat;
box-shadow: 0 0 2em, // background: -webkit-linear-gradient(45deg,rgba(255,255,255,0),yellow,rgba(255,255,255,0));
0 0 4em, /*此处为下一步的添加动画*/
0 0 6em, // -webkit-animation: shining 3s ease-in-out infinite;
0 0 8em, // -o-animation: shining 3s ease-in-out infinite;
0 0 10em, animation: shining .6s ease-in-out forwards;
0 0 0.5em rgba(255, 255, 0, 0.1);
} }
.star:before {
@keyframes animate { transform: rotateZ(-2deg);
to { // transform: -webkit-translateX(-50%) -webkit-rotateZ(-45deg);
transform: rotate(1turn);
} }
.star:after {
// transform: translateX(-50%) rotateZ(45deg);
// transform: -webkit-translateX(-50%) -webkit-rotateZ(45deg);
}
// @-webkit-keyframes shining {
// 0% {width: 0;}
// 50% {width: 30px;}
// 100% {width: 0;}
// }
@keyframes shining {
0% {transform: scale(1);}
// 50% {transform: scale(0.8);}
99% {transform: scale(0.3);}
100% {transform: scale(0);}
} }
// @-webkit-keyframes tail {
// 0% {width: 0;}
// 30% {width: 50px;}
// 100% {width: 0;}
// }
@keyframes tail {
0% {width: 0;}
10% {width: 0;}
50% {width: 150rpx;}
65% {width: 50rpx;}
80% {width: 150rpx;}
100% {width: 0;}
} }
// @-webkit-keyframes shooting {
// 0% {
// -webkit-transform: translateX(0);
// transform: translateX(0);
// }
// 100% {
// -webkit-transform: translateX(350px);
// transform: translateX(350px);
// }
// }
@keyframes shooting {
0% {
// -webkit-transform: translateX(0);
transform: translateX(605rpx);
} }
100% {
// -webkit-transform: translateX(350px);
transform: translateX(30rpx);
} }
} }
// }
</style> </style>
<config> <config>
{ {
......
<template>
<!-- <div class="loading-container"> -->
<!-- <van-loading size="24px" vertical>加载中...</van-loading> -->
<div class="meteor">
<div class="star"></div>
</div>
<!-- </div> -->
</template>
<script>
import wepy from '@wepy/core';
wepy.component({
methods: {
onShareAppMessage: function(res) {
if (res.from === 'button') {
console.log('onShareAppMessage1', res.target);
}
}
}
});
</script>
<style lang="less">
// .loading-container {
// position: absolute;
// width: 100%;
// height: 100%;
// display: flex;
// justify-content: center;
// align-items: center;
// z-index: 1;
.meteor {
position: fixed;
top: 247rpx;
left: 94rpx;
width: calc(100% - 170rpx);;
height: 0;
// border: 2rpx solid #000;
z-index: 10;
transform: rotateZ(-10deg)
}
.star {
position: absolute;
left: -3rpx;
// bottom: -220rpx;
top: -7rpx;
// left: -43%;
height: 10rpx;
width: 150rpx;
background: linear-gradient(-45deg,rgba(255,255,255,0),yellow);
transform: translateX(300rpx);
// background: -webkit-linear-gradient(-45deg,rgba(255,255,255,0),yellow);
/*此处为下一步的添加动画*/
// -webkit-animation: tail 1s ease-in forwards, shooting 1s ease-in forwards;
// -o-animation: tail 1s ease-in forwards, shooting 1s ease-in forwards;
animation: tail 1s ease-in forwards, shooting 1s ease-in forwards;
}
.star::before{
content: "";
position: absolute;
top: -29rpx;
left: -52rpx;
width: 78rpx;
height: 78rpx;
// top: calc(100% - 1px);
// left: 100%;
background: url('http://activitystatic.xyqb.com/sign@2x.png') 0 0/contain no-repeat;
// background: -webkit-linear-gradient(45deg,rgba(255,255,255,0),yellow,rgba(255,255,255,0));
/*此处为下一步的添加动画*/
// -webkit-animation: shining 3s ease-in-out infinite;
// -o-animation: shining 3s ease-in-out infinite;
animation: shining 1s ease-in-out forwards;
}
.star:before {
transform: rotateZ(15deg);
// transform: -webkit-translateX(-50%) -webkit-rotateZ(-45deg);
}
.star:after {
// transform: translateX(-50%) rotateZ(45deg);
// transform: -webkit-translateX(-50%) -webkit-rotateZ(45deg);
}
// @-webkit-keyframes shining {
// 0% {width: 0;}
// 50% {width: 30px;}
// 100% {width: 0;}
// }
@keyframes shining {
0% {transform: scale(1);}
// 50% {transform: scale(0.8);}
99% {transform: scale(0.6);}
100% {transform: scale(0);}
}
// @-webkit-keyframes tail {
// 0% {width: 0;}
// 30% {width: 50px;}
// 100% {width: 0;}
// }
@keyframes tail {
0% {width: 0;}
10% {width: 0;}
50% {width: 150rpx;}
65% {width: 50rpx;}
80% {width: 150rpx;}
100% {width: 0;}
}
// @-webkit-keyframes shooting {
// 0% {
// -webkit-transform: translateX(0);
// transform: translateX(0);
// }
// 100% {
// -webkit-transform: translateX(350px);
// transform: translateX(350px);
// }
// }
@keyframes shooting {
0% {
// -webkit-transform: translateX(0);
transform: translateX(610rpx);
}
100% {
// -webkit-transform: translateX(350px);
transform: translateX(20rpx);
}
}
// }
</style>
<config>
{
usingComponents: {
'van-loading': '~@/components/vant/loading/index'
}
}
</config>
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { safeArea } from '../mixins/safe-area'; import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({ VantComponent({
mixins: [safeArea()], mixins: [button, openType],
props: { props: {
show: Boolean, show: Boolean,
title: String, title: String,
cancelText: String, cancelText: String,
customStyle: String, description: String,
overlayStyle: String, round: {
type: Boolean,
value: true,
},
zIndex: { zIndex: {
type: Number, type: Number,
value: 100 value: 100,
}, },
actions: { actions: {
type: Array, type: Array,
value: [] value: [],
}, },
overlay: { overlay: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
closeOnClickOverlay: { closeOnClickOverlay: {
type: Boolean, type: Boolean,
value: true value: true,
} },
closeOnClickAction: {
type: Boolean,
value: true,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
}, },
methods: { methods: {
onSelect(event) { onSelect(event) {
...@@ -31,6 +43,9 @@ VantComponent({ ...@@ -31,6 +43,9 @@ VantComponent({
const item = this.data.actions[index]; const item = this.data.actions[index];
if (item && !item.disabled && !item.loading) { if (item && !item.disabled && !item.loading) {
this.$emit('select', item); this.$emit('select', item);
if (this.data.closeOnClickAction) {
this.onClose();
}
} }
}, },
onCancel() { onCancel() {
...@@ -38,6 +53,10 @@ VantComponent({ ...@@ -38,6 +53,10 @@ VantComponent({
}, },
onClose() { onClose() {
this.$emit('close'); this.$emit('close');
} },
} onClickOverlay() {
this.$emit('click-overlay');
this.onClose();
},
},
}); });
...@@ -3,14 +3,13 @@ ...@@ -3,14 +3,13 @@
<van-popup <van-popup
show="{{ show }}" show="{{ show }}"
position="bottom" position="bottom"
round="{{ round }}"
z-index="{{ zIndex }}" z-index="{{ zIndex }}"
overlay="{{ overlay }}" overlay="{{ overlay }}"
custom-style="{{ customStyle }}"
overlay-style="{{ overlayStyle }}"
custom-class="van-action-sheet" custom-class="van-action-sheet"
safe-area-inset-bottom="{{ safeAreaInsetBottom }}" safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
close-on-click-overlay="{{ closeOnClickOverlay }}" close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClose" bind:close="onClickOverlay"
> >
<view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header"> <view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header">
{{ title }} {{ title }}
...@@ -20,22 +19,39 @@ ...@@ -20,22 +19,39 @@
bind:click="onClose" bind:click="onClose"
/> />
</view> </view>
<view wx:if="{{ description }}" class="van-action-sheet__description">
{{ description }}
</view>
<view wx:if="{{ actions && actions.length }}"> <view wx:if="{{ actions && actions.length }}">
<!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 --> <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
<button <button
wx:for="{{ actions }}" wx:for="{{ actions }}"
wx:key="index" wx:key="index"
open-type="{{ item.openType }}" open-type="{{ item.openType }}"
style="{{ item.color ? 'color: ' + item.color : '' }}"
class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}" class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}"
hover-class="van-action-sheet__item--hover" hover-class="van-action-sheet__item--hover"
data-index="{{ index }}" data-index="{{ index }}"
bind:tap="onSelect" bind:tap="onSelect"
bindgetuserinfo="bindGetUserInfo"
bindcontact="bindContact"
bindgetphonenumber="bindGetPhoneNumber"
binderror="bindError"
bindlaunchapp="bindLaunchApp"
bindopensetting="bindOpenSetting"
lang="{{ lang }}"
session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}"
send-message-path="{{ sendMessagePath }}"
send-message-img="{{ sendMessageImg }}"
show-message-card="{{ showMessageCard }}"
app-parameter="{{ appParameter }}"
> >
<block wx:if="{{ !item.loading }}"> <block wx:if="{{ !item.loading }}">
{{ item.name }} {{ item.name }}
<text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text> <text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text>
</block> </block>
<van-loading wx:else size="20px" /> <van-loading wx:else custom-class="van-action-sheet__loading" size="20px" />
</button> </button>
</view> </view>
<slot /> <slot />
......
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;color:#333}.van-action-sheet__cancel,.van-action-sheet__item{height:50px;font-size:16px;line-height:50px;text-align:center;background-color:#fff}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5}.van-action-sheet__cancel{height:60px}.van-action-sheet__cancel:before{display:block;height:10px;background-color:#f8f8f8;content:" "}.van-action-sheet__item--disabled{color:#c9c9c9}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff}.van-action-sheet__subname{margin-left:5px;font-size:12px;color:#7d7e80}.van-action-sheet__header{font-size:16px;font-weight:500;line-height:44px;text-align:center}.van-action-sheet__close{position:absolute!important;top:0;right:0;padding:0 15px;font-size:18px!important;line-height:inherit!important;color:#999} @import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:50px;line-height:var(--action-sheet-item-height,50px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:before{display:block;content:" ";height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f7f8fa;background-color:var(--action-sheet-cancel-padding-color,#f7f8fa)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-left:4px;margin-left:var(--padding-base,4px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#646566;color:var(--action-sheet-subname-color,#646566)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:44px;line-height:var(--action-sheet-header-height,44px)}.van-action-sheet__description{text-align:center;padding:16px;padding:var(--padding-md,16px);color:#646566;color:var(--action-sheet-description-color,#646566);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 12px;padding:var(--action-sheet-close-icon-padding,0 12px);font-size:18px!important;font-size:var(--action-sheet-close-icon-size,18px)!important;color:#969799;color:var(--action-sheet-close-icon-color,#969799)}.van-action-sheet__loading{display:-webkit-flex!important;display:flex!important;height:50px;height:var(--action-sheet-item-height,50px)}
\ No newline at end of file \ No newline at end of file
...@@ -3,13 +3,29 @@ import { pickerProps } from '../picker/shared'; ...@@ -3,13 +3,29 @@ import { pickerProps } from '../picker/shared';
const COLUMNSPLACEHOLDERCODE = '000000'; const COLUMNSPLACEHOLDERCODE = '000000';
VantComponent({ VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'], classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign({}, pickerProps, { value: String, areaList: { props: Object.assign(Object.assign({}, pickerProps), {
value: {
type: String,
observer(value) {
this.code = value;
this.setValues();
},
},
areaList: {
type: Object, type: Object,
value: {} value: {},
}, columnsNum: { observer: 'setValues',
type: [String, Number], },
value: 3 columnsNum: {
}, columnsPlaceholder: { type: null,
value: 3,
observer(value) {
this.setData({
displayColumns: this.data.columns.slice(0, +value),
});
},
},
columnsPlaceholder: {
type: Array, type: Array,
observer(val) { observer(val) {
this.setData({ this.setData({
...@@ -17,26 +33,15 @@ VantComponent({ ...@@ -17,26 +33,15 @@ VantComponent({
province: val[0] || '', province: val[0] || '',
city: val[1] || '', city: val[1] || '',
county: val[2] || '', county: val[2] || '',
} },
}); });
} },
} }), },
}),
data: { data: {
columns: [{ values: [] }, { values: [] }, { values: [] }], columns: [{ values: [] }, { values: [] }, { values: [] }],
displayColumns: [{ values: [] }, { values: [] }, { values: [] }], displayColumns: [{ values: [] }, { values: [] }, { values: [] }],
typeToColumnsPlaceholder: {} typeToColumnsPlaceholder: {},
},
watch: {
value(value) {
this.code = value;
this.setValues();
},
areaList: 'setValues',
columnsNum(value) {
this.set({
displayColumns: this.data.columns.slice(0, +value)
});
}
}, },
mounted() { mounted() {
setTimeout(() => { setTimeout(() => {
...@@ -69,8 +74,7 @@ VantComponent({ ...@@ -69,8 +74,7 @@ VantComponent({
const { columnsPlaceholder } = this.data; const { columnsPlaceholder } = this.data;
return values.map((value, index) => { return values.map((value, index) => {
// save undefined value // save undefined value
if (!value) if (!value) return value;
return value;
value = JSON.parse(JSON.stringify(value)); value = JSON.parse(JSON.stringify(value));
if (!value.code || value.name === columnsPlaceholder[index]) { if (!value.code || value.name === columnsPlaceholder[index]) {
value.code = ''; value.code = '';
...@@ -82,13 +86,11 @@ VantComponent({ ...@@ -82,13 +86,11 @@ VantComponent({
onChange(event) { onChange(event) {
const { index, picker, value } = event.detail; const { index, picker, value } = event.detail;
this.code = value[index].code; this.code = value[index].code;
let getValues = picker.getValues();
getValues = this.parseOutputValues(getValues);
this.setValues().then(() => { this.setValues().then(() => {
this.$emit('change', { this.$emit('change', {
picker, picker,
values: getValues, values: this.parseOutputValues(picker.getValues()),
index index,
}); });
}); });
}, },
...@@ -103,23 +105,28 @@ VantComponent({ ...@@ -103,23 +105,28 @@ VantComponent({
return result; return result;
} }
const list = this.getConfig(type); const list = this.getConfig(type);
result = Object.keys(list).map(code => ({ result = Object.keys(list).map((code) => ({
code, code,
name: list[code] name: list[code],
})); }));
if (code) { if (code) {
// oversea code // oversea code
if (code[0] === '9' && type === 'city') { if (code[0] === '9' && type === 'city') {
code = '9'; code = '9';
} }
result = result.filter(item => item.code.indexOf(code) === 0); result = result.filter((item) => item.code.indexOf(code) === 0);
} }
if (typeToColumnsPlaceholder[type] && result.length) { if (typeToColumnsPlaceholder[type] && result.length) {
// set columns placeholder // set columns placeholder
const codeFill = type === 'province' ? '' : type === 'city' ? COLUMNSPLACEHOLDERCODE.slice(2, 4) : COLUMNSPLACEHOLDERCODE.slice(4, 6); const codeFill =
type === 'province'
? ''
: type === 'city'
? COLUMNSPLACEHOLDERCODE.slice(2, 4)
: COLUMNSPLACEHOLDERCODE.slice(4, 6);
result.unshift({ result.unshift({
code: `${code}${codeFill}`, code: `${code}${codeFill}`,
name: typeToColumnsPlaceholder[type] name: typeToColumnsPlaceholder[type],
}); });
} }
return result; return result;
...@@ -145,11 +152,9 @@ VantComponent({ ...@@ -145,11 +152,9 @@ VantComponent({
if (!code) { if (!code) {
if (this.data.columnsPlaceholder.length) { if (this.data.columnsPlaceholder.length) {
code = COLUMNSPLACEHOLDERCODE; code = COLUMNSPLACEHOLDERCODE;
} } else if (Object.keys(county)[0]) {
else if (Object.keys(county)[0]) {
code = Object.keys(county)[0]; code = Object.keys(county)[0];
} } else {
else {
code = ''; code = '';
} }
} }
...@@ -165,19 +170,27 @@ VantComponent({ ...@@ -165,19 +170,27 @@ VantComponent({
if (city.length && code.slice(2, 4) === '00') { if (city.length && code.slice(2, 4) === '00') {
[{ code }] = city; [{ code }] = city;
} }
stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false)); stack.push(
picker.setColumnValues(
2,
this.getList('county', code.slice(0, 4)),
false
)
);
return Promise.all(stack) return Promise.all(stack)
.catch(() => { }) .catch(() => {})
.then(() => picker.setIndexes([ .then(() =>
picker.setIndexes([
this.getIndex('province', code), this.getIndex('province', code),
this.getIndex('city', code), this.getIndex('city', code),
this.getIndex('county', code) this.getIndex('county', code),
])) ])
.catch(() => { }); )
.catch(() => {});
}, },
getValues() { getValues() {
const picker = this.getPicker(); const picker = this.getPicker();
return picker ? picker.getValues().filter(value => !!value) : []; return picker ? picker.getValues().filter((value) => !!value) : [];
}, },
getDetail() { getDetail() {
const values = this.getValues(); const values = this.getValues();
...@@ -186,7 +199,7 @@ VantComponent({ ...@@ -186,7 +199,7 @@ VantComponent({
country: '', country: '',
province: '', province: '',
city: '', city: '',
county: '' county: '',
}; };
if (!values.length) { if (!values.length) {
return area; return area;
...@@ -196,17 +209,16 @@ VantComponent({ ...@@ -196,17 +209,16 @@ VantComponent({
if (area.code[0] === '9') { if (area.code[0] === '9') {
area.country = names[1] || ''; area.country = names[1] || '';
area.province = names[2] || ''; area.province = names[2] || '';
} } else {
else {
area.province = names[0] || ''; area.province = names[0] || '';
area.city = names[1] || ''; area.city = names[1] || '';
area.county = names[2] || ''; area.county = names[2] || '';
} }
return area; return area;
}, },
reset() { reset(code) {
this.code = ''; this.code = code || '';
return this.setValues(); return this.setValues();
} },
} },
}); });
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'badge',
type: 'descendant',
linked(target) {
this.badges.push(target);
this.setActive(this.data.active);
},
unlinked(target) {
this.badges = this.badges.filter(item => item !== target);
this.setActive(this.data.active);
}
},
props: {
active: {
type: Number,
value: 0,
observer: 'setActive'
}
},
beforeCreate() {
this.badges = [];
this.currentActive = -1;
},
methods: {
setActive(active) {
const { badges, currentActive } = this;
if (!badges.length) {
return Promise.resolve();
}
this.currentActive = active;
const stack = [];
if (currentActive !== active && badges[currentActive]) {
stack.push(badges[currentActive].setActive(false));
}
if (badges[active]) {
stack.push(badges[active].setActive(true));
}
return Promise.all(stack);
}
}
});
<view class="van-badge-group van-hairline--top-bottom custom-class">
<slot />
</view>
@import '../common/index.wxss';.van-badge-group{width:85px}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
relation: {
type: 'ancestor',
name: 'badge-group',
linked(target) {
this.parent = target;
}
},
props: {
info: null,
title: String
},
methods: {
onClick() {
const { parent } = this;
if (!parent) {
return;
}
const index = parent.badges.indexOf(this);
parent.setActive(index).then(() => {
this.$emit('click', index);
parent.$emit('change', index);
});
},
setActive(active) {
return this.set({ active });
}
}
});
@import '../common/index.wxss';.van-badge{display:block;padding:20px 12px 20px 9px;overflow:hidden;font-size:14px;line-height:1.4;color:#7d7e80;word-break:break-all;background-color:#f8f8f8;border-left:3px solid transparent;box-sizing:border-box;-webkit-user-select:none;user-select:none}.van-badge--hover{background-color:#f2f3f5}.van-badge:after{border-bottom-width:1px}.van-badge--active{font-weight:700;color:#333;border-color:#f44}.van-badge--active:after{border-right-width:1px}.van-badge--active,.van-badge--active.van-badge--hover{background-color:#fff}.van-badge__text{position:relative}
\ No newline at end of file
...@@ -4,9 +4,15 @@ import { openType } from '../mixins/open-type'; ...@@ -4,9 +4,15 @@ import { openType } from '../mixins/open-type';
VantComponent({ VantComponent({
mixins: [button, openType], mixins: [button, openType],
classes: ['hover-class', 'loading-class'], classes: ['hover-class', 'loading-class'],
data: {
baseStyle: '',
},
props: { props: {
icon: String, icon: String,
color: String, classPrefix: {
type: String,
value: 'van-icon',
},
plain: Boolean, plain: Boolean,
block: Boolean, block: Boolean,
round: Boolean, round: Boolean,
...@@ -15,24 +21,53 @@ VantComponent({ ...@@ -15,24 +21,53 @@ VantComponent({
hairline: Boolean, hairline: Boolean,
disabled: Boolean, disabled: Boolean,
loadingText: String, loadingText: String,
customStyle: String,
loadingType: {
type: String,
value: 'circular',
},
type: { type: {
type: String, type: String,
value: 'default' value: 'default',
}, },
dataset: null,
size: { size: {
type: String, type: String,
value: 'normal' value: 'normal',
}, },
loadingSize: { loadingSize: {
type: String, type: String,
value: '20px' value: '20px',
},
color: {
type: String,
observer(color) {
let style = '';
if (color) {
style += `color: ${this.data.plain ? color : 'white'};`;
if (!this.data.plain) {
// Use background instead of backgroundColor to make linear-gradient work
style += `background: ${color};`;
}
// hide border when color is linear-gradient
if (color.indexOf('gradient') !== -1) {
style += 'border: 0;';
} else {
style += `border-color: ${color};`;
} }
}
if (style !== this.data.baseStyle) {
this.setData({ baseStyle: style });
}
},
},
}, },
methods: { methods: {
onClick() { onClick() {
if (!this.data.disabled && !this.data.loading) { if (!this.data.loading) {
this.$emit('click'); this.$emit('click');
} }
} },
} noop() {},
},
}); });
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
<button <button
id="{{ id }}" id="{{ id }}"
data-detail="{{ dataset }}"
class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}" class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
open-type="{{ openType }}"
hover-class="van-button--active hover-class" hover-class="van-button--active hover-class"
style="{{ color ? 'border-color: ' + color + ';' + (plain ? 'color: ' + color : 'color: #fff; background-color: ' + color) : '' }}"
lang="{{ lang }}" lang="{{ lang }}"
style="{{ baseStyle }} {{ customStyle }}"
open-type="{{ disabled ? '' : openType }}"
business-id="{{ businessId }}" business-id="{{ businessId }}"
session-from="{{ sessionFrom }}" session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}" send-message-title="{{ sendMessageTitle }}"
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
show-message-card="{{ showMessageCard }}" show-message-card="{{ showMessageCard }}"
app-parameter="{{ appParameter }}" app-parameter="{{ appParameter }}"
aria-label="{{ ariaLabel }}" aria-label="{{ ariaLabel }}"
bindtap="onClick" bindtap="{{ !disabled ? 'onClick' : 'noop' }}"
bindgetuserinfo="bindGetUserInfo" bindgetuserinfo="bindGetUserInfo"
bindcontact="bindContact" bindcontact="bindContact"
bindgetphonenumber="bindGetPhoneNumber" bindgetphonenumber="bindGetPhoneNumber"
...@@ -27,12 +28,10 @@ ...@@ -27,12 +28,10 @@
<van-loading <van-loading
custom-class="loading-class" custom-class="loading-class"
size="{{ loadingSize }}" size="{{ loadingSize }}"
color="{{ type === 'default' ? '#c9c9c9' : '' }}" type="{{ loadingType }}"
color="{{ loadingColor(type,color,plain) }}"
/> />
<view <view wx:if="{{ loadingText }}" class="van-button__loading-text">
wx:if="{{ loadingText }}"
class="van-button__loading-text"
>
{{ loadingText }} {{ loadingText }}
</view> </view>
</block> </block>
...@@ -41,6 +40,7 @@ ...@@ -41,6 +40,7 @@
wx:if="{{ icon }}" wx:if="{{ icon }}"
size="1.2em" size="1.2em"
name="{{ icon }}" name="{{ icon }}"
class-prefix="{{ classPrefix }}"
class="van-button__icon" class="van-button__icon"
custom-style="line-height: inherit;" custom-style="line-height: inherit;"
/> />
...@@ -49,3 +49,19 @@ ...@@ -49,3 +49,19 @@
</view> </view>
</block> </block>
</button> </button>
<wxs module="loadingColor">
function get(type, color,plain) {
if(plain) {
return color ? color: '#c9c9c9';
}
if(type === 'default') {
return '#c9c9c9';
}
return 'white';
}
module.exports = get;
</wxs>
@import '../common/index.wxss';.van-button{position:relative;display:inline-block;height:44px;padding:0;font-size:16px;line-height:42px;text-align:center;vertical-align:middle;box-sizing:border-box;border-radius:2px;-webkit-appearance:none;-webkit-text-size-adjust:100%}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;content:" ";opacity:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#333;background-color:#fff;border:1px solid #eee}.van-button--primary{color:#fff;background-color:#07c160;border:1px solid #07c160}.van-button--info{color:#fff;background-color:#1989fa;border:1px solid #1989fa}.van-button--danger{color:#fff;background-color:#f44;border:1px solid #f44}.van-button--warning{color:#fff;background-color:#ff976a;border:1px solid #ff976a}.van-button--plain{background-color:#fff}.van-button--plain.van-button--primary{color:#07c160}.van-button--plain.van-button--info{color:#1989fa}.van-button--plain.van-button--danger{color:#f44}.van-button--plain.van-button--warning{color:#ff976a}.van-button--large{width:100%;height:50px;line-height:48px}.van-button--normal{padding:0 15px;font-size:14px}.van-button--small{height:30px;min-width:60px;padding:0 8px;font-size:12px;line-height:28px}.van-button--mini{display:inline-block;width:50px;height:22px;font-size:10px;line-height:20px}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:block;width:100%}.van-button--round{border-radius:10em}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5}.van-button__text{display:inline}.van-button__loading-text{margin-left:5px;display:inline-block;vertical-align:middle}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button__icon+.van-button__text:not(:empty){display:inline-block;margin-left:5px;vertical-align:top}.van-button--hairline{border-width:0;padding-top:1px}.van-button--hairline:after{border-width:1px;border-color:inherit;border-radius:4px}.van-button--hairline.van-button--round:after{border-radius:10em}.van-button--hairline.van-button--square:after{border-radius:0} @import '../common/index.wxss';.van-button{position:relative;display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:0;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);line-height:20px;line-height:var(--button-line-height,20px);font-size:16px;font-size:var(--button-default-font-size,16px);transition:opacity .2s;transition:opacity var(--animation-duration-fast,.2s);border-radius:2px;border-radius:var(--button-border-radius,2px)}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;border:inherit;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" ";background-color:#000;background-color:var(--black,#000);border-color:#000;border-color:var(--black,#000)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#323233;color:var(--button-default-color,#323233);background:#fff;background:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:var(--button-border-width,1px) solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background:#07c160;background:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:var(--button-border-width,1px) solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background:#1989fa;background:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:var(--button-border-width,1px) solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background:#ee0a24;background:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:var(--button-border-width,1px) solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background:#ff976a;background:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:var(--button-border-width,1px) solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background:#fff;background:var(--button-plain-background-color,#fff)}.van-button--plain.van-button--primary{color:#07c160;color:var(--button-primary-background-color,#07c160)}.van-button--plain.van-button--info{color:#1989fa;color:var(--button-info-background-color,#1989fa)}.van-button--plain.van-button--danger{color:#ee0a24;color:var(--button-danger-background-color,#ee0a24)}.van-button--plain.van-button--warning{color:#ff976a;color:var(--button-warning-background-color,#ff976a)}.van-button--large{width:100%;height:50px;height:var(--button-large-height,50px)}.van-button--normal{padding:0 15px;font-size:14px;font-size:var(--button-normal-font-size,14px)}.van-button--small{min-width:60px;min-width:var(--button-small-min-width,60px);height:30px;height:var(--button-small-height,30px);padding:0 8px;padding:0 var(--padding-xs,8px);font-size:12px;font-size:var(--button-small-font-size,12px)}.van-button--mini{display:inline-block;min-width:50px;min-width:var(--button-mini-min-width,50px);height:22px;height:var(--button-mini-height,22px);font-size:10px;font-size:var(--button-mini-font-size,10px)}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:-webkit-flex;display:flex;width:100%}.van-button--round{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5;opacity:var(--button-disabled-opacity,.5)}.van-button__text{display:inline}.van-button__icon+.van-button__text:not(:empty),.van-button__loading-text{margin-left:4px}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button--hairline{padding-top:1px;border-width:0}.van-button--hairline:after{border-color:inherit;border-width:1px;border-radius:4px;border-radius:calc(var(--button-border-radius, 2px)*2)}.van-button--hairline.van-button--round:after{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--hairline.van-button--square:after{border-radius:0}
\ No newline at end of file \ No newline at end of file
<wxs src="./index.wxs" module="computed"></wxs>
<template name="calendar">
<view class="van-calendar">
<header
title="{{ title }}"
showTitle="{{ showTitle }}"
subtitle="{{ subtitle }}"
showSubtitle="{{ showSubtitle }}"
>
<slot name="title" slot="title"></slot>
</header>
<scroll-view class="van-calendar__body" scroll-y scroll-into-view="{{ scrollIntoView }}">
<month
wx:for="{{ computed.getMonths(minDate, maxDate) }}"
wx:key="index"
id="month{{ index }}"
class="month"
data-date="{{ item }}"
date="{{ item }}"
type="{{ type }}"
color="{{ color }}"
minDate="{{ minDate }}"
maxDate="{{ maxDate }}"
showMark="{{ showMark }}"
formatter="{{ formatter }}"
rowHeight="{{ rowHeight }}"
currentDate="{{ currentDate }}"
showSubtitle="{{ showSubtitle }}"
allowSameDay="{{ allowSameDay }}"
showMonthTitle="{{ index !== 0 || !showSubtitle }}"
bind:click="onClickDay"
/>
</scroll-view>
<view class="van-calendar__footer {{ safeAreaInsetBottom ? 'van-calendar__footer--safe-area-inset-bottom' : '' }}">
<slot name="footer"></slot>
</view>
<view class="van-calendar__footer {{ safeAreaInsetBottom ? 'van-calendar__footer--safe-area-inset-bottom' : '' }}">
<van-button
wx:if="{{ showConfirm }}"
round
block
type="danger"
color="{{ color }}"
custom-class="van-calendar__confirm"
disabled="{{ computed.getButtonDisabled(type, currentDate) }}"
nativeType="text"
bind:click="onConfirm"
>
{{ computed.getButtonDisabled(type, currentDate) ? confirmDisabledText : confirmText }}
</van-button>
</view>
</view>
</template>
import { VantComponent } from '../../../common/component';
VantComponent({
props: {
title: {
type: String,
value: '日期选择',
},
subtitle: String,
showTitle: Boolean,
showSubtitle: Boolean,
},
data: {
weekdays: ['', '', '', '', '', '', ''],
},
methods: {},
});
<view class="van-calendar__header">
<block wx:if="{{ showTitle }}">
<view class="van-calendar__header-title"><slot name="title"></slot></view>
<view class="van-calendar__header-title">{{ title }}</view>
</block>
<view wx:if="{{ showSubtitle }}" class="van-calendar__header-subtitle">
{{ subtitle }}
</view>
<view class="van-calendar__weekdays">
<view wx:for="{{ weekdays }}" wx:key="index" class="van-calendar__weekday">
{{ item }}
</view>
</view>
</view>
@import '../../../common/index.wxss';.van-calendar__header{-webkit-flex-shrink:0;flex-shrink:0;box-shadow:0 2px 10px rgba(125,126,128,.16);box-shadow:var(--calendar-header-box-shadow,0 2px 10px rgba(125,126,128,.16))}.van-calendar__header-subtitle,.van-calendar__header-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:-webkit-flex;display:flex}.van-calendar__weekday{-webkit-flex:1;flex:1;text-align:center;font-size:12px;font-size:var(--calendar-weekdays-font-size,12px);line-height:30px;line-height:var(--calendar-weekdays-height,30px)}
\ No newline at end of file
import { VantComponent } from '../../../common/component';
import {
getMonthEndDay,
compareDay,
getPrevDay,
getNextDay,
} from '../../utils';
VantComponent({
props: {
date: {
type: null,
observer: 'setDays',
},
type: {
type: String,
observer: 'setDays',
},
color: String,
minDate: {
type: null,
observer: 'setDays',
},
maxDate: {
type: null,
observer: 'setDays',
},
showMark: Boolean,
rowHeight: [Number, String],
formatter: {
type: null,
observer: 'setDays',
},
currentDate: {
type: [null, Array],
observer: 'setDays',
},
allowSameDay: Boolean,
showSubtitle: Boolean,
showMonthTitle: Boolean,
},
data: {
visible: true,
days: [],
},
methods: {
onClick(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.days[index];
if (item.type !== 'disabled') {
this.$emit('click', item);
}
},
setDays() {
const days = [];
const startDate = new Date(this.data.date);
const year = startDate.getFullYear();
const month = startDate.getMonth();
const totalDay = getMonthEndDay(
startDate.getFullYear(),
startDate.getMonth() + 1
);
for (let day = 1; day <= totalDay; day++) {
const date = new Date(year, month, day);
const type = this.getDayType(date);
let config = {
date,
type,
text: day,
bottomInfo: this.getBottomInfo(type),
};
if (this.data.formatter) {
config = this.data.formatter(config);
}
days.push(config);
}
this.setData({ days });
},
getMultipleDayType(day) {
const { currentDate } = this.data;
if (!Array.isArray(currentDate)) {
return '';
}
const isSelected = (date) =>
currentDate.some((item) => compareDay(item, date) === 0);
if (isSelected(day)) {
const prevDay = getPrevDay(day);
const nextDay = getNextDay(day);
const prevSelected = isSelected(prevDay);
const nextSelected = isSelected(nextDay);
if (prevSelected && nextSelected) {
return 'multiple-middle';
}
if (prevSelected) {
return 'end';
}
return nextSelected ? 'start' : 'multiple-selected';
}
return '';
},
getRangeDayType(day) {
const { currentDate, allowSameDay } = this.data;
if (!Array.isArray(currentDate)) {
return;
}
const [startDay, endDay] = currentDate;
if (!startDay) {
return;
}
const compareToStart = compareDay(day, startDay);
if (!endDay) {
return compareToStart === 0 ? 'start' : '';
}
const compareToEnd = compareDay(day, endDay);
if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
return 'start-end';
}
if (compareToStart === 0) {
return 'start';
}
if (compareToEnd === 0) {
return 'end';
}
if (compareToStart > 0 && compareToEnd < 0) {
return 'middle';
}
},
getDayType(day) {
const { type, minDate, maxDate, currentDate } = this.data;
if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
return 'disabled';
}
if (type === 'single') {
return compareDay(day, currentDate) === 0 ? 'selected' : '';
}
if (type === 'multiple') {
return this.getMultipleDayType(day);
}
/* istanbul ignore else */
if (type === 'range') {
return this.getRangeDayType(day);
}
},
getBottomInfo(type) {
if (this.data.type === 'range') {
if (type === 'start') {
return '开始';
}
if (type === 'end') {
return '结束';
}
if (type === 'start-end') {
return '开始/结束';
}
}
},
},
});
<wxs src="./index.wxs" module="computed"></wxs>
<wxs src="../../../wxs/utils.wxs" module="utils" />
<view class="van-calendar__month" style="{{ computed.getMonthStyle(visible, date, rowHeight) }}">
<view wx:if="{{ showMonthTitle }}" class="van-calendar__month-title">
{{ computed.formatMonthTitle(date) }}
</view>
<view wx:if="{{ visible }}" class="van-calendar__days">
<view wx:if="{{ showMark }}" class="van-calendar__month-mark">
{{ computed.getMark(date) }}
</view>
<view
wx:for="{{ days }}"
wx:key="index"
style="{{ computed.getDayStyle(item.type, index, date, rowHeight, color) }}"
class="{{ utils.bem('calendar__day', [item.type]) }} {{ item.className }}"
data-index="{{ index }}"
bindtap="onClick"
>
<view wx:if="{{ item.type === 'selected' }}" class="van-calendar__selected-day" style="background: {{ color }}">
<view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
{{ item.text }}
<view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
{{ item.bottomInfo }}
</view>
</view>
<view wx:else>
<view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
{{ item.text }}
<view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
{{ item.bottomInfo }}
</view>
</view>
</view>
</view>
</view>
/* eslint-disable */
var utils = require('../../utils.wxs');
function getMark(date) {
return getDate(date).getMonth() + 1;
}
var ROW_HEIGHT = 64;
function getDayStyle(type, index, date, rowHeight, color) {
var style = [];
var offset = getDate(date).getDay();
if (index === 0) {
style.push(['margin-left', (100 * offset) / 7 + '%']);
}
if (rowHeight !== ROW_HEIGHT) {
style.push(['height', rowHeight + 'px']);
}
if (color) {
if (
type === 'start' ||
type === 'end' ||
type === 'multiple-selected' ||
type === 'multiple-middle'
) {
style.push(['background', color]);
} else if (type === 'middle') {
style.push(['color', color]);
}
}
return style
.map(function(item) {
return item.join(':');
})
.join(';');
}
function formatMonthTitle(date) {
date = getDate(date);
return date.getFullYear() + '年' + (date.getMonth() + 1) + '月';
}
function getMonthStyle(visible, date, rowHeight) {
if (!visible) {
date = getDate(date);
var totalDay = utils.getMonthEndDay(
date.getFullYear(),
date.getMonth() + 1
);
var offset = getDate(date).getDay();
var padding = Math.ceil((totalDay + offset) / 7) * rowHeight;
return 'padding-bottom:' + padding + 'px';
}
}
module.exports = {
getMark: getMark,
getDayStyle: getDayStyle,
formatMonthTitle: formatMonthTitle,
getMonthStyle: getMonthStyle
};
@import '../../../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__month-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:14px;font-size:var(--calendar-month-title-font-size,14px);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__days{position:relative;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-user-select:none;user-select:none}.van-calendar__month-mark{position:absolute;top:50%;left:50%;z-index:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);pointer-events:none;color:rgba(242,243,245,.8);color:var(--calendar-month-mark-color,rgba(242,243,245,.8));font-size:160px;font-size:var(--calendar-month-mark-font-size,160px)}.van-calendar__day,.van-calendar__selected-day{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;text-align:center}.van-calendar__day{position:relative;width:14.285%;height:64px;height:var(--calendar-day-height,64px);font-size:16px;font-size:var(--calendar-day-font-size,16px)}.van-calendar__day--end,.van-calendar__day--multiple-middle,.van-calendar__day--multiple-selected,.van-calendar__day--start,.van-calendar__day--start-end{color:#fff;color:var(--calendar-range-edge-color,#fff);background-color:#ee0a24;background-color:var(--calendar-range-edge-background-color,#ee0a24)}.van-calendar__day--start{border-radius:4px 0 0 4px;border-radius:var(--border-radius-md,4px) 0 0 var(--border-radius-md,4px)}.van-calendar__day--end{border-radius:0 4px 4px 0;border-radius:0 var(--border-radius-md,4px) var(--border-radius-md,4px) 0}.van-calendar__day--multiple-selected,.van-calendar__day--start-end{border-radius:4px;border-radius:var(--border-radius-md,4px)}.van-calendar__day--middle{color:#ee0a24;color:var(--calendar-range-middle-color,#ee0a24)}.van-calendar__day--middle:after{position:absolute;top:0;right:0;bottom:0;left:0;background-color:currentColor;content:"";opacity:.1;opacity:var(--calendar-range-middle-background-opacity,.1)}.van-calendar__day--disabled{cursor:default;color:#c8c9cc;color:var(--calendar-day-disabled-color,#c8c9cc)}.van-calendar__bottom-info,.van-calendar__top-info{position:absolute;right:0;left:0;font-size:10px;font-size:var(--calendar-info-font-size,10px);line-height:14px;line-height:var(--calendar-info-line-height,14px)}@media (max-width:350px){.van-calendar__bottom-info,.van-calendar__top-info{font-size:9px}}.van-calendar__top-info{top:6px}.van-calendar__bottom-info{bottom:6px}.van-calendar__selected-day{width:54px;width:var(--calendar-selected-day-size,54px);height:54px;height:var(--calendar-selected-day-size,54px);color:#fff;color:var(--calendar-selected-day-color,#fff);background-color:#ee0a24;background-color:var(--calendar-selected-day-background-color,#ee0a24);border-radius:4px;border-radius:var(--border-radius-md,4px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import {
ROW_HEIGHT,
getNextDay,
compareDay,
copyDates,
calcDateNum,
formatMonthTitle,
compareMonth,
getMonths,
getDayByOffset,
} from './utils';
import Toast from '../toast/toast';
VantComponent({
props: {
title: {
type: String,
value: '日期选择',
},
color: String,
show: {
type: Boolean,
observer(val) {
if (val) {
this.initRect();
this.scrollIntoView();
}
},
},
formatter: null,
confirmText: {
type: String,
value: '确定',
},
rangePrompt: String,
defaultDate: {
type: [Number, Array],
observer(val) {
this.setData({ currentDate: val });
this.scrollIntoView();
},
},
allowSameDay: Boolean,
confirmDisabledText: String,
type: {
type: String,
value: 'single',
observer: 'reset',
},
minDate: {
type: null,
value: Date.now(),
},
maxDate: {
type: null,
value: new Date(
new Date().getFullYear(),
new Date().getMonth() + 6,
new Date().getDate()
).getTime(),
},
position: {
type: String,
value: 'bottom',
},
rowHeight: {
type: [Number, String],
value: ROW_HEIGHT,
},
round: {
type: Boolean,
value: true,
},
poppable: {
type: Boolean,
value: true,
},
showMark: {
type: Boolean,
value: true,
},
showTitle: {
type: Boolean,
value: true,
},
showConfirm: {
type: Boolean,
value: true,
},
showSubtitle: {
type: Boolean,
value: true,
},
safeAreaInsetBottom: {
type: Boolean,
value: true,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
},
maxRange: {
type: [Number, String],
value: null,
},
},
data: {
subtitle: '',
currentDate: null,
scrollIntoView: '',
},
created() {
this.setData({
currentDate: this.getInitialDate(),
});
},
mounted() {
if (this.data.show || !this.data.poppable) {
this.initRect();
this.scrollIntoView();
}
},
methods: {
reset() {
this.setData({ currentDate: this.getInitialDate() });
this.scrollIntoView();
},
initRect() {
if (this.contentObserver != null) {
this.contentObserver.disconnect();
}
const contentObserver = this.createIntersectionObserver({
thresholds: [0, 0.1, 0.9, 1],
observeAll: true,
});
this.contentObserver = contentObserver;
contentObserver.relativeTo('.van-calendar__body');
contentObserver.observe('.month', (res) => {
if (res.boundingClientRect.top <= res.relativeRect.top) {
// @ts-ignore
this.setData({ subtitle: formatMonthTitle(res.dataset.date) });
}
});
},
getInitialDate() {
const { type, defaultDate, minDate } = this.data;
if (type === 'range') {
const [startDay, endDay] = defaultDate || [];
return [
startDay || minDate,
endDay || getNextDay(new Date(minDate)).getTime(),
];
}
if (type === 'multiple') {
return [defaultDate || minDate];
}
return defaultDate || minDate;
},
scrollIntoView() {
setTimeout(() => {
const {
currentDate,
type,
show,
poppable,
minDate,
maxDate,
} = this.data;
const targetDate = type === 'single' ? currentDate : currentDate[0];
const displayed = show || !poppable;
if (!targetDate || !displayed) {
return;
}
const months = getMonths(minDate, maxDate);
months.some((month, index) => {
if (compareMonth(month, targetDate) === 0) {
this.setData({ scrollIntoView: `month${index}` });
return true;
}
return false;
});
}, 100);
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
},
onClickDay(event) {
const { date } = event.detail;
const { type, currentDate, allowSameDay } = this.data;
if (type === 'range') {
const [startDay, endDay] = currentDate;
if (startDay && !endDay) {
const compareToStart = compareDay(date, startDay);
if (compareToStart === 1) {
this.select([startDay, date], true);
} else if (compareToStart === -1) {
this.select([date, null]);
} else if (allowSameDay) {
this.select([date, date]);
}
} else {
this.select([date, null]);
}
} else if (type === 'multiple') {
let selectedIndex;
const selected = currentDate.some((dateItem, index) => {
const equal = compareDay(dateItem, date) === 0;
if (equal) {
selectedIndex = index;
}
return equal;
});
if (selected) {
const cancelDate = currentDate.splice(selectedIndex, 1);
this.setData({ currentDate });
this.unselect(cancelDate);
} else {
this.select([...currentDate, date]);
}
} else {
this.select(date, true);
}
},
unselect(dateArray) {
const date = dateArray[0];
if (date) {
this.$emit('unselect', copyDates(date));
}
},
select(date, complete) {
if (complete && this.data.type === 'range') {
const valid = this.checkRange(date);
if (!valid) {
// auto selected to max range if showConfirm
if (this.data.showConfirm) {
this.emit([
date[0],
getDayByOffset(date[0], this.data.maxRange - 1),
]);
} else {
this.emit(date);
}
return;
}
}
this.emit(date);
if (complete && !this.data.showConfirm) {
this.onConfirm();
}
},
emit(date) {
const getTime = (date) => (date instanceof Date ? date.getTime() : date);
this.setData({
currentDate: Array.isArray(date) ? date.map(getTime) : getTime(date),
});
this.$emit('select', copyDates(date));
},
checkRange(date) {
const { maxRange, rangePrompt } = this.data;
if (maxRange && calcDateNum(date) > maxRange) {
Toast({
context: this,
message: rangePrompt || `选择天数不能超过 ${maxRange} 天`,
});
return false;
}
return true;
},
onConfirm() {
if (this.data.type === 'range' && !this.checkRange()) {
return;
}
wx.nextTick(() => {
this.$emit('confirm', copyDates(this.data.currentDate));
});
},
},
});
{
"component": true,
"usingComponents": {
"header": "./components/header/index",
"month": "./components/month/index",
"van-button": "../button/index",
"van-popup": "../popup/index"
}
}
<wxs src="./index.wxs" module="computed" />
<import src="./calendar.wxml" />
<van-popup
wx:if="{{ poppable }}"
custom-class="van-calendar__popup--{{ position }}"
close-icon-class="van-calendar__close-icon"
show="{{ show }}"
round="{{ round }}"
position="{{ position }}"
closeable="{{ showTitle || showSubtitle }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:enter="onOpen"
bind:close="onClose"
bind:after-enter="onOpened"
bind:after-leave="onClosed"
>
<template
is="calendar"
data="{{ title, subtitle, showTitle, showSubtitle, minDate, maxDate, type, color, showMark, formatter, rowHeight, currentDate, safeAreaInsetBottom, showConfirm, confirmDisabledText, confirmText, scrollIntoView, allowSameDay }}"
/>
</van-popup>
<template
wx:else
is="calendar"
data="{{ title, subtitle, showTitle, showSubtitle, minDate, maxDate, type, color, showMark, formatter, rowHeight, currentDate, safeAreaInsetBottom, showConfirm, confirmDisabledText, confirmText, scrollIntoView, allowSameDay }}"
/>
<van-toast id="van-toast" />
/* eslint-disable */
var utils = require('./utils.wxs');
function getMonths(minDate, maxDate) {
var months = [];
var cursor = getDate(minDate);
cursor.setDate(1);
do {
months.push(cursor.getTime());
cursor.setMonth(cursor.getMonth() + 1);
} while (utils.compareMonth(cursor, getDate(maxDate)) !== 1);
return months;
}
function getButtonDisabled(type, currentDate) {
if (currentDate == null) {
return true;
}
if (type === 'range') {
return !currentDate[0] || !currentDate[1];
}
if (type === 'multiple') {
return !currentDate.length;
}
return !currentDate;
}
module.exports = {
getMonths: getMonths,
getButtonDisabled: getButtonDisabled
};
@import '../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;height:var(--calendar-height,100%);background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:80%;height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-flex:1;flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__footer{-webkit-flex-shrink:0;flex-shrink:0;padding:0 16px;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:36px!important;height:var(--calendar-confirm-button-height,36px)!important;margin:7px 0!important;margin:var(--calendar-confirm-button-margin,7px 0)!important;line-height:34px!important;line-height:var(--calendar-confirm-button-line-height,34px)!important}
\ No newline at end of file
export declare const ROW_HEIGHT = 64;
export declare function formatMonthTitle(date: Date): string;
export declare function compareMonth(
date1: Date | number,
date2: Date | number
): 0 | 1 | -1;
export declare function compareDay(
day1: Date | number,
day2: Date | number
): 0 | 1 | -1;
export declare function getDayByOffset(date: Date, offset: number): Date;
export declare function getPrevDay(date: Date): Date;
export declare function getNextDay(date: Date): Date;
export declare function calcDateNum(date: [Date, Date]): number;
export declare function copyDates(dates: Date | Date[]): Date | Date[];
export declare function getMonthEndDay(year: number, month: number): number;
export declare function getMonths(minDate: number, maxDate: number): any[];
export const ROW_HEIGHT = 64;
export function formatMonthTitle(date) {
if (!(date instanceof Date)) {
date = new Date(date);
}
return `${date.getFullYear()}${date.getMonth() + 1}月`;
}
export function compareMonth(date1, date2) {
if (!(date1 instanceof Date)) {
date1 = new Date(date1);
}
if (!(date2 instanceof Date)) {
date2 = new Date(date2);
}
const year1 = date1.getFullYear();
const year2 = date2.getFullYear();
const month1 = date1.getMonth();
const month2 = date2.getMonth();
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
}
return year1 > year2 ? 1 : -1;
}
export function compareDay(day1, day2) {
if (!(day1 instanceof Date)) {
day1 = new Date(day1);
}
if (!(day2 instanceof Date)) {
day2 = new Date(day2);
}
const compareMonthResult = compareMonth(day1, day2);
if (compareMonthResult === 0) {
const date1 = day1.getDate();
const date2 = day2.getDate();
return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
}
return compareMonthResult;
}
export function getDayByOffset(date, offset) {
date = new Date(date);
date.setDate(date.getDate() + offset);
return date;
}
export function getPrevDay(date) {
return getDayByOffset(date, -1);
}
export function getNextDay(date) {
return getDayByOffset(date, 1);
}
export function calcDateNum(date) {
const day1 = new Date(date[0]).getTime();
const day2 = new Date(date[1]).getTime();
return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
}
export function copyDates(dates) {
if (Array.isArray(dates)) {
return dates.map((date) => {
if (date === null) {
return date;
}
return new Date(date);
});
}
return new Date(dates);
}
export function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
export function getMonths(minDate, maxDate) {
const months = [];
const cursor = new Date(minDate);
cursor.setDate(1);
do {
months.push(cursor.getTime());
cursor.setMonth(cursor.getMonth() + 1);
} while (compareMonth(cursor, maxDate) !== 1);
return months;
}
/* eslint-disable */
function getMonthEndDay(year, month) {
return 32 - getDate(year, month - 1, 32).getDate();
}
function compareMonth(date1, date2) {
date1 = getDate(date1);
date2 = getDate(date2);
var year1 = date1.getFullYear();
var year2 = date2.getFullYear();
var month1 = date1.getMonth();
var month2 = date2.getMonth();
if (year1 === year2) {
return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
}
return year1 > year2 ? 1 : -1;
}
module.exports = {
getMonthEndDay: getMonthEndDay,
compareMonth: compareMonth
};
...@@ -16,23 +16,34 @@ VantComponent({ ...@@ -16,23 +16,34 @@ VantComponent({
desc: String, desc: String,
thumb: String, thumb: String,
title: String, title: String,
price: String, price: {
type: String,
observer: 'updatePrice',
},
centered: Boolean, centered: Boolean,
lazyLoad: Boolean, lazyLoad: Boolean,
thumbLink: String, thumbLink: String,
originPrice: String, originPrice: String,
thumbMode: { thumbMode: {
type: String, type: String,
value: 'aspectFit' value: 'aspectFit',
}, },
currency: { currency: {
type: String, type: String,
value: '¥' value: '¥',
} },
}, },
methods: { methods: {
updatePrice() {
const { price } = this.data;
const priceArr = price.toString().split('.');
this.setData({
integerStr: priceArr[0],
decimalStr: priceArr[1] ? `.${priceArr[1]}` : '',
});
},
onClickThumb() { onClickThumb() {
this.jumpLink('thumbLink'); this.jumpLink('thumbLink');
} },
} },
}); });
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
</van-tag> </van-tag>
</view> </view>
<view class="van-card__content"> <view class="van-card__content {{ utils.bem('card__content', { center: centered }) }}">
<view>
<view wx:if="{{ title }}" class="van-card__title title-class">{{ title }}</view> <view wx:if="{{ title }}" class="van-card__title title-class">{{ title }}</view>
<slot wx:else name="title" /> <slot wx:else name="title" />
...@@ -29,11 +30,15 @@ ...@@ -29,11 +30,15 @@
<slot wx:else name="desc" /> <slot wx:else name="desc" />
<slot name="tags" /> <slot name="tags" />
</view>
<view class="van-card__bottom"> <view class="van-card__bottom">
<view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">{{ currency }} {{ price }}</view> <slot name="price-top" />
<view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">{{ currency }}<text class="van-card__price-integer">{{ integerStr }}</text><text class="van-card__price-decimal">{{ decimalStr }}</text></view>
<slot wx:else name="price" />
<view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view> <view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
<view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view> <view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
<slot wx:else name="num" />
<slot name="bottom" /> <slot name="bottom" />
</view> </view>
</view> </view>
......
@import '../common/index.wxss';.van-card{position:relative;padding:5px 15px;font-size:12px;color:#333;background-color:#fafafa;box-sizing:border-box}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;width:90px;height:90px;margin-right:10px;-webkit-flex:none;flex:none}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%}.van-card__content{position:relative;min-width:0;-webkit-flex:1;flex:1}.van-card__desc,.van-card__title{word-break:break-all}.van-card__title{font-weight:700;line-height:16px}.van-card__desc{color:#7d7e80}.van-card__bottom,.van-card__desc{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#f44}.van-card__origin-price{display:inline-block;margin-left:5px;font-size:10px;color:#7d7e80;text-decoration:line-through}.van-card__num{float:right}.van-card__tag{position:absolute;top:2px;left:0}.van-card__footer{width:100%;text-align:right;-webkit-flex:none;flex:none} @import '../common/index.wxss';.van-card{position:relative;box-sizing:border-box;padding:8px 16px;padding:var(--card-padding,8px 16px);font-size:12px;font-size:var(--card-font-size,12px);color:#323233;color:var(--card-text-color,#323233);background-color:#fafafa;background-color:var(--card-background-color,#fafafa)}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;-webkit-flex:none;flex:none;width:88px;width:var(--card-thumb-size,88px);height:88px;height:var(--card-thumb-size,88px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%;border-radius:8px;border-radius:var(--border-radius-lg,8px)}.van-card__content{position:relative;display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:space-between;justify-content:space-between;min-width:0;min-height:88px;min-height:var(--card-thumb-size,88px)}.van-card__content--center{-webkit-justify-content:center;justify-content:center}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:16px;line-height:var(--card-title-line-height,16px)}.van-card__desc{line-height:20px;line-height:var(--card-desc-line-height,20px);color:#646566;color:var(--card-desc-color,#646566)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24);font-size:12px;font-size:var(--card-price-font-size,12px)}.van-card__price-integer{font-size:16px;font-size:var(--card-price-integer-font-size,16px)}.van-card__price-decimal,.van-card__price-integer{font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--card-price-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif)}.van-card__origin-price{display:inline-block;margin-left:5px;text-decoration:line-through;font-size:10px;font-size:var(--card-origin-price-font-size,10px);color:#646566;color:var(--card-origin-price-color,#646566)}.van-card__num{float:right}.van-card__tag{position:absolute;top:2px;left:0}.van-card__footer{-webkit-flex:none;flex:none;width:100%;text-align:right}
\ No newline at end of file \ No newline at end of file
...@@ -4,7 +4,7 @@ VantComponent({ ...@@ -4,7 +4,7 @@ VantComponent({
title: String, title: String,
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
} },
} },
}); });
@import '../common/index.wxss';.van-cell-group__title{font-size:14px;padding:15px 15px 5px;color:#999;line-height:16px} @import '../common/index.wxss';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}
\ No newline at end of file \ No newline at end of file
...@@ -6,7 +6,7 @@ VantComponent({ ...@@ -6,7 +6,7 @@ VantComponent({
'label-class', 'label-class',
'value-class', 'value-class',
'right-icon-class', 'right-icon-class',
'hover-class' 'hover-class',
], ],
mixins: [link], mixins: [link],
props: { props: {
...@@ -25,13 +25,13 @@ VantComponent({ ...@@ -25,13 +25,13 @@ VantComponent({
useLabelSlot: Boolean, useLabelSlot: Boolean,
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
methods: { methods: {
onClick(event) { onClick(event) {
this.$emit('click', event.detail); this.$emit('click', event.detail);
this.jumpLink(); this.jumpLink();
} },
} },
}); });
@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;width:100%;padding:10px 15px;font-size:14px;line-height:24px;color:#333;background-color:#fff;box-sizing:border-box}.van-cell:after{content:" ";position:absolute;pointer-events:none;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;top:auto;left:15px;right:0;bottom:0;-webkit-transform:scaleY(.5);transform:scaleY(.5);border-bottom:1px solid #eee}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff}.van-cell__label{margin-top:3px;font-size:12px;line-height:18px;color:#999}.van-cell__value{overflow:hidden;color:#999;text-align:right;vertical-align:middle}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;height:24px;font-size:16px;-webkit-align-items:center;align-items:center}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#999}.van-cell__left-icon{line-height:24px;vertical-align:middle}.van-cell__right-icon{line-height:24px}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;left:7px;font-size:14px;color:#f44;content:"*"}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-bottom:12px}.van-cell--large .van-cell__title{font-size:16px}.van-cell--large .van-cell__label{font-size:14px} @import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:auto;right:0;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__value{font-size:16px;font-size:var(--cell-large-value-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)}
\ No newline at end of file \ No newline at end of file
...@@ -4,25 +4,21 @@ VantComponent({ ...@@ -4,25 +4,21 @@ VantComponent({
relation: { relation: {
name: 'checkbox', name: 'checkbox',
type: 'descendant', type: 'descendant',
current: 'checkbox-group',
linked(target) { linked(target) {
this.children = this.children || [];
this.children.push(target);
this.updateChild(target); this.updateChild(target);
}, },
unlinked(target) {
this.children = this.children.filter((child) => child !== target);
}
}, },
props: { props: {
max: Number, max: Number,
value: { value: {
type: Array, type: Array,
observer: 'updateChildren' observer: 'updateChildren',
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
observer: 'updateChildren' observer: 'updateChildren',
} },
}, },
methods: { methods: {
updateChildren() { updateChildren() {
...@@ -30,10 +26,10 @@ VantComponent({ ...@@ -30,10 +26,10 @@ VantComponent({
}, },
updateChild(child) { updateChild(child) {
const { value, disabled } = this.data; const { value, disabled } = this.data;
child.set({ child.setData({
value: value.indexOf(child.data.name) !== -1, value: value.indexOf(child.data.name) !== -1,
disabled: disabled || child.data.disabled parentDisabled: disabled,
}); });
} },
} },
}); });
...@@ -8,12 +8,7 @@ VantComponent({ ...@@ -8,12 +8,7 @@ VantComponent({
relation: { relation: {
name: 'checkbox-group', name: 'checkbox-group',
type: 'ancestor', type: 'ancestor',
linked(target) { current: 'checkbox',
this.parent = target;
},
unlinked() {
this.parent = null;
}
}, },
classes: ['icon-class', 'label-class'], classes: ['icon-class', 'label-class'],
props: { props: {
...@@ -25,27 +20,33 @@ VantComponent({ ...@@ -25,27 +20,33 @@ VantComponent({
labelDisabled: Boolean, labelDisabled: Boolean,
shape: { shape: {
type: String, type: String,
value: 'round' value: 'round',
} },
iconSize: {
type: null,
value: 20,
},
},
data: {
parentDisabled: false,
}, },
methods: { methods: {
emitChange(value) { emitChange(value) {
if (this.parent) { if (this.parent) {
this.setParentValue(this.parent, value); this.setParentValue(this.parent, value);
} } else {
else {
emit(this, value); emit(this, value);
} }
}, },
toggle() { toggle() {
const { disabled, value } = this.data; const { parentDisabled, disabled, value } = this.data;
if (!disabled) { if (!disabled && !parentDisabled) {
this.emitChange(!value); this.emitChange(!value);
} }
}, },
onClickLabel() { onClickLabel() {
const { labelDisabled, disabled, value } = this.data; const { labelDisabled, parentDisabled, disabled, value } = this.data;
if (!disabled && !labelDisabled) { if (!disabled && !labelDisabled && !parentDisabled) {
this.emitChange(!value); this.emitChange(!value);
} }
}, },
...@@ -61,14 +62,13 @@ VantComponent({ ...@@ -61,14 +62,13 @@ VantComponent({
parentValue.push(name); parentValue.push(name);
emit(parent, parentValue); emit(parent, parentValue);
} }
} } else {
else {
const index = parentValue.indexOf(name); const index = parentValue.indexOf(name);
if (index !== -1) { if (index !== -1) {
parentValue.splice(index, 1); parentValue.splice(index, 1);
emit(parent, parentValue); emit(parent, parentValue);
} }
} }
} },
} },
}); });
<wxs src="../wxs/utils.wxs" module="utils" /> <wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view class="van-checkbox custom-class"> <view class="van-checkbox custom-class">
<view class="van-checkbox__icon-wrap" bindtap="toggle"> <view class="van-checkbox__icon-wrap" bindtap="toggle">
...@@ -6,13 +7,14 @@ ...@@ -6,13 +7,14 @@
<van-icon <van-icon
wx:else wx:else
name="success" name="success"
class="{{ utils.bem('checkbox__icon', [shape, { disabled, checked: value }]) }}" size="0.8em"
style="{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}" class="{{ utils.bem('checkbox__icon', [shape, { disabled: disabled || parentDisabled, checked: value }]) }}"
style="{{ computed.iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) }}"
custom-class="icon-class" custom-class="icon-class"
custom-style="line-height: 20px;" custom-style="line-height: 1.25em;"
/> />
</view> </view>
<view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled }]) }}" bindtap="onClickLabel"> <view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}" bindtap="onClickLabel">
<slot /> <slot />
</view> </view>
</view> </view>
/* eslint-disable */
var utils = require('../wxs/utils.wxs');
function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) {
var styles = [['font-size', utils.addUnit(iconSize)]];
if (checkedColor && value && !disabled && !parentDisabled) {
styles.push(['border-color', checkedColor]);
styles.push(['background-color', checkedColor]);
}
return styles
.map(function(item) {
return item.join(':');
})
.join(';');
}
module.exports = {
iconStyle: iconStyle
};
@import '../common/index.wxss';.van-checkbox{display:-webkit-flex;display:flex;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-checkbox__icon{display:block;width:20px;height:20px;font-size:14px;color:transparent;text-align:center;border:1px solid #e5e5e5;box-sizing:border-box;transition:.2s}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;background-color:#1989fa;border-color:#1989fa}.van-checkbox__icon--disabled{background-color:#eee;border-color:#c9c9c9}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c9c9c9}.van-checkbox__label{margin-left:10px;color:#333;word-break:break-all}.van-checkbox__label--left{float:left;margin:0 10px 0 0}.van-checkbox__label--disabled{color:#c9c9c9}.van-checkbox__label:empty{margin:0} @import '../common/index.wxss';.van-checkbox{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px;line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-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:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;font-size:20px;font-size:var(--checkbox-size,20px);border:1px solid #c8c9cc;border:1px solid var(--checkbox-border-color,#c8c9cc);transition-duration:.2s;transition-duration:var(--checkbox-transition-duration,.2s)}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--checkbox-checked-icon-color,#1989fa)}.van-checkbox__icon--disabled{background-color:#ebedf0;background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c8c9cc;color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;margin-left:10px;margin-left:var(--checkbox-label-margin,10px);color:#323233;color:var(--checkbox-label-color,#323233)}.van-checkbox__label--left{float:left;margin:0 10px 0 0;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:#c8c9cc;color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0}
\ No newline at end of file \ No newline at end of file
import { VantComponent } from '../common/component';
import { isObj } from '../common/utils';
import { BLUE, WHITE } from '../common/color';
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
}
const PERIMETER = 2 * Math.PI;
const BEGIN_ANGLE = -Math.PI / 2;
const STEP = 1;
VantComponent({
props: {
text: String,
lineCap: {
type: String,
value: 'round',
},
value: {
type: Number,
value: 0,
observer: 'reRender',
},
speed: {
type: Number,
value: 50,
},
size: {
type: Number,
value: 100,
},
fill: String,
layerColor: {
type: String,
value: WHITE,
},
color: {
type: [String, Object],
value: BLUE,
observer: 'setHoverColor',
},
type: {
type: String,
value: '',
},
strokeWidth: {
type: Number,
value: 4,
},
clockwise: {
type: Boolean,
value: true,
},
},
data: {
hoverColor: BLUE,
},
methods: {
getContext() {
if (!this.ctx) {
this.ctx = wx.createCanvasContext('van-circle', this);
}
return this.ctx;
},
setHoverColor() {
const { color, size, type } = this.data;
const context = type ? this.getContext(type) : this.getContext();
let hoverColor = color;
if (isObj(color)) {
const LinearColor = context.createLinearGradient(size, 0, 0, 0);
Object.keys(color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map((key) =>
LinearColor.addColorStop(parseFloat(key) / 100, color[key])
);
hoverColor = LinearColor;
}
this.setData({ hoverColor });
},
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
const { strokeWidth, lineCap, clockwise, size } = this.data;
const position = size / 2;
const radius = position - strokeWidth / 2;
context.setStrokeStyle(strokeStyle);
context.setLineWidth(strokeWidth);
context.setLineCap(lineCap);
context.beginPath();
context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
context.stroke();
if (fill) {
context.setFillStyle(fill);
context.fill();
}
},
renderLayerCircle(context) {
const { layerColor, fill } = this.data;
this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
},
renderHoverCircle(context, formatValue) {
const { clockwise, hoverColor } = this.data;
// 结束角度
const progress = PERIMETER * (formatValue / 100);
const endAngle = clockwise
? BEGIN_ANGLE + progress
: 3 * Math.PI - (BEGIN_ANGLE + progress);
this.presetCanvas(context, hoverColor, BEGIN_ANGLE, endAngle);
},
drawCircle(currentValue) {
const { size, type } = this.data;
const context = type ? this.getContext(type) : this.getContext();
context.clearRect(0, 0, size, size);
this.renderLayerCircle(context);
const formatValue = format(currentValue);
if (formatValue !== 0) {
this.renderHoverCircle(context, formatValue);
}
context.draw();
},
reRender() {
// tofector 动画暂时没有想到好的解决方案
const { value, speed } = this.data;
if (speed <= 0 || speed > 1000) {
this.drawCircle(value);
return;
}
this.clearInterval();
this.currentValue = this.currentValue || 0;
this.interval = setInterval(() => {
if (this.currentValue !== value) {
if (this.currentValue < value) {
this.currentValue += STEP;
} else {
this.currentValue -= STEP;
}
this.drawCircle(this.currentValue);
} else {
this.clearInterval();
}
}, 1000 / speed);
},
clearInterval() {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
},
},
created() {
const { value } = this.data;
this.currentValue = value;
this.drawCircle(value);
},
destroyed() {
this.ctx = null;
this.clearInterval();
},
});
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-circle">
<canvas class="van-circle__canvas" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" canvas-id="van-circle"></canvas>
<view wx:if="{{ !text }}" class="van-circle__text">
<slot></slot>
</view>
<cover-view wx:else class="van-circle__text">{{ text }}</cover-view>
</view>
\ No newline at end of file
@import '../common/index.wxss';.van-circle{position:relative;display:inline-block;text-align:center}.van-circle__text{position:absolute;top:50%;left:0;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);color:#323233;color:var(--circle-text-color,#323233)}
\ No newline at end of file
...@@ -2,22 +2,25 @@ import { VantComponent } from '../common/component'; ...@@ -2,22 +2,25 @@ import { VantComponent } from '../common/component';
VantComponent({ VantComponent({
relation: { relation: {
name: 'row', name: 'row',
type: 'ancestor' type: 'ancestor',
current: 'col',
}, },
props: { props: {
span: Number, span: Number,
offset: Number offset: Number,
}, },
data: { data: {
style: '' viewStyle: '',
}, },
methods: { methods: {
setGutter(gutter) { setGutter(gutter) {
const padding = `${gutter / 2}px`; const padding = `${gutter / 2}px`;
const style = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : ''; const viewStyle = gutter
if (style !== this.data.style) { ? `padding-left: ${padding}; padding-right: ${padding};`
this.set({ style }); : '';
} if (viewStyle !== this.data.viewStyle) {
} this.setData({ viewStyle });
} }
},
},
}); });
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<view <view
class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}" class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}"
style="{{ style }}" style="{{ viewStyle }}"
> >
<slot /> <slot />
</view> </view>
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
const nextTick = () => new Promise(resolve => setTimeout(resolve, 20)); const nextTick = () => new Promise((resolve) => setTimeout(resolve, 20));
VantComponent({ VantComponent({
classes: ['title-class', 'content-class'], classes: ['title-class', 'content-class'],
relation: { relation: {
name: 'collapse', name: 'collapse',
type: 'ancestor', type: 'ancestor',
linked(parent) { current: 'collapse-item',
this.parent = parent;
}
}, },
props: { props: {
name: null, name: null,
...@@ -19,17 +17,17 @@ VantComponent({ ...@@ -19,17 +17,17 @@ VantComponent({
clickable: Boolean, clickable: Boolean,
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
isLink: { isLink: {
type: Boolean, type: Boolean,
value: true value: true,
} },
}, },
data: { data: {
contentHeight: 0, contentHeight: 0,
expanded: false, expanded: false,
transition: false transition: false,
}, },
mounted() { mounted() {
this.updateExpanded() this.updateExpanded()
...@@ -39,7 +37,7 @@ VantComponent({ ...@@ -39,7 +37,7 @@ VantComponent({
if (this.data.expanded) { if (this.data.expanded) {
data.contentHeight = 'auto'; data.contentHeight = 'auto';
} }
this.set(data); this.setData(data);
}); });
}, },
methods: { methods: {
...@@ -68,7 +66,7 @@ VantComponent({ ...@@ -68,7 +66,7 @@ VantComponent({
.then((height) => { .then((height) => {
if (expanded) { if (expanded) {
return this.set({ return this.set({
contentHeight: height ? `${height}px` : 'auto' contentHeight: height ? `${height}px` : 'auto',
}); });
} }
return this.set({ contentHeight: `${height}px` }) return this.set({ contentHeight: `${height}px` })
...@@ -87,10 +85,10 @@ VantComponent({ ...@@ -87,10 +85,10 @@ VantComponent({
}, },
onTransitionEnd() { onTransitionEnd() {
if (this.data.expanded) { if (this.data.expanded) {
this.set({ this.setData({
contentHeight: 'auto' contentHeight: 'auto',
}); });
} }
} },
} },
}); });
@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:.3s}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c9c9c9!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__wrapper--transition{transition:height .3s ease-in-out}.van-collapse-item__content{padding:15px;font-size:13px;line-height:1.5;color:#999;background-color:#fff} @import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__wrapper--transition{transition:height .3s ease-in-out}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)}
\ No newline at end of file \ No newline at end of file
...@@ -3,29 +3,21 @@ VantComponent({ ...@@ -3,29 +3,21 @@ VantComponent({
relation: { relation: {
name: 'collapse-item', name: 'collapse-item',
type: 'descendant', type: 'descendant',
linked(child) { current: 'collapse',
this.children.push(child);
},
unlinked(child) {
this.children = this.children.filter((item) => item !== child);
}
}, },
props: { props: {
value: { value: {
type: null, type: null,
observer: 'updateExpanded' observer: 'updateExpanded',
}, },
accordion: { accordion: {
type: Boolean, type: Boolean,
observer: 'updateExpanded' observer: 'updateExpanded',
}, },
border: { border: {
type: Boolean, type: Boolean,
value: true value: true,
}
}, },
beforeCreate() {
this.children = [];
}, },
methods: { methods: {
updateExpanded() { updateExpanded() {
...@@ -35,16 +27,21 @@ VantComponent({ ...@@ -35,16 +27,21 @@ VantComponent({
}, },
switch(name, expanded) { switch(name, expanded) {
const { accordion, value } = this.data; const { accordion, value } = this.data;
const changeItem = name;
if (!accordion) { if (!accordion) {
name = expanded name = expanded
? (value || []).concat(name) ? (value || []).concat(name)
: (value || []).filter((activeName) => activeName !== name); : (value || []).filter((activeName) => activeName !== name);
} } else {
else {
name = expanded ? name : ''; name = expanded ? name : '';
} }
if (expanded) {
this.$emit('open', changeItem);
} else {
this.$emit('close', changeItem);
}
this.$emit('change', name); this.$emit('change', name);
this.$emit('input', name); this.$emit('input', name);
} },
} },
}); });
export declare const RED = "#f44"; export declare const RED = "#ee0a24";
export declare const BLUE = "#1989fa"; export declare const BLUE = "#1989fa";
export declare const WHITE = "#fff";
export declare const GREEN = "#07c160"; export declare const GREEN = "#07c160";
export declare const ORANGE = "#ff976a"; export declare const ORANGE = "#ff976a";
export declare const GRAY = "#323233";
export declare const GRAY_DARK = "#969799";
export const RED = '#f44'; export const RED = '#ee0a24';
export const BLUE = '#1989fa'; export const BLUE = '#1989fa';
export const WHITE = '#fff';
export const GREEN = '#07c160'; export const GREEN = '#07c160';
export const ORANGE = '#ff976a'; export const ORANGE = '#ff976a';
export const GRAY = '#323233';
export const GRAY_DARK = '#969799';
import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index'; import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
declare function VantComponent<Data, Props, Methods, Computed>(vantOptions?: VantComponentOptions<Data, Props, Methods, Computed, CombinedComponentInstance<Data, Props, Methods, Computed>>): void; declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
export { VantComponent }; export { VantComponent };
import { basic } from '../mixins/basic'; import { basic } from '../mixins/basic';
import { observe } from '../mixins/observer/index'; const relationFunctions = {
ancestor: {
linked(parent) {
this.parent = parent;
},
unlinked() {
this.parent = null;
},
},
descendant: {
linked(child) {
this.children = this.children || [];
this.children.push(child);
},
unlinked(child) {
this.children = (this.children || []).filter((it) => it !== child);
},
},
};
function mapKeys(source, target, map) { function mapKeys(source, target, map) {
Object.keys(map).forEach(key => { Object.keys(map).forEach((key) => {
if (source[key]) { if (source[key]) {
target[map[key]] = source[key]; target[map[key]] = source[key];
} }
}); });
} }
function makeRelation(options, vantOptions, relation) {
const { type, name, linked, unlinked, linkChanged } = relation;
const { beforeCreate, destroyed } = vantOptions;
if (type === 'descendant') {
options.created = function () {
beforeCreate && beforeCreate.bind(this)();
this.children = this.children || [];
};
options.detached = function () {
this.children = [];
destroyed && destroyed.bind(this)();
};
}
options.relations = Object.assign(options.relations || {}, {
[`../${name}/index`]: {
type,
linked(node) {
relationFunctions[type].linked.bind(this)(node);
linked && linked.bind(this)(node);
},
linkChanged(node) {
linkChanged && linkChanged.bind(this)(node);
},
unlinked(node) {
relationFunctions[type].unlinked.bind(this)(node);
unlinked && unlinked.bind(this)(node);
},
},
});
}
function VantComponent(vantOptions = {}) { function VantComponent(vantOptions = {}) {
const options = {}; const options = {};
mapKeys(vantOptions, options, { mapKeys(vantOptions, options, {
...@@ -19,13 +67,11 @@ function VantComponent(vantOptions = {}) { ...@@ -19,13 +67,11 @@ function VantComponent(vantOptions = {}) {
mounted: 'ready', mounted: 'ready',
relations: 'relations', relations: 'relations',
destroyed: 'detached', destroyed: 'detached',
classes: 'externalClasses' classes: 'externalClasses',
}); });
const { relation } = vantOptions; const { relation } = vantOptions;
if (relation) { if (relation) {
options.relations = Object.assign(options.relations || {}, { makeRelation(options, vantOptions, relation);
[`../${relation.name}/index`]: relation
});
} }
// add default externalClasses // add default externalClasses
options.externalClasses = options.externalClasses || []; options.externalClasses = options.externalClasses || [];
...@@ -37,12 +83,19 @@ function VantComponent(vantOptions = {}) { ...@@ -37,12 +83,19 @@ function VantComponent(vantOptions = {}) {
if (vantOptions.field) { if (vantOptions.field) {
options.behaviors.push('wx://form-field'); options.behaviors.push('wx://form-field');
} }
if (options.properties) {
Object.keys(options.properties).forEach((name) => {
if (Array.isArray(options.properties[name])) {
// miniprogram do not allow multi type
options.properties[name] = null;
}
});
}
// add default options // add default options
options.options = { options.options = {
multipleSlots: true, multipleSlots: true,
addGlobalClass: true addGlobalClass: true,
}; };
observe(vantOptions, options);
Component(options); Component(options);
} }
export { VantComponent }; export { VantComponent };
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{content:"";display:table;clear:both}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{content:" ";position:absolute;pointer-events:none;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;top:-50%;left:-50%;right:-50%;bottom:-50%;-webkit-transform:scale(.5);transform:scale(.5);border:0 solid #eee}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px} .van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file \ No newline at end of file
.van-clearfix:after{content:"";display:table;clear:both} .van-clearfix:after{display:table;clear:both;content:""}
\ No newline at end of file \ No newline at end of file
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3} .van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}
\ No newline at end of file \ No newline at end of file
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{content:" ";position:absolute;pointer-events:none;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;top:-50%;left:-50%;right:-50%;bottom:-50%;-webkit-transform:scale(.5);transform:scale(.5);border:0 solid #eee}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px} .van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file \ No newline at end of file
...@@ -4,4 +4,5 @@ export declare function isObj(x: any): boolean; ...@@ -4,4 +4,5 @@ export declare function isObj(x: any): boolean;
export declare function isNumber(value: any): boolean; export declare function isNumber(value: any): boolean;
export declare function range(num: number, min: number, max: number): number; export declare function range(num: number, min: number, max: number): number;
export declare function nextTick(fn: Function): void; export declare function nextTick(fn: Function): void;
export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSuccessCallbackResult; export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSyncResult;
export declare function addUnit(value?: string | number): string | undefined;
...@@ -6,7 +6,7 @@ export function isObj(x) { ...@@ -6,7 +6,7 @@ export function isObj(x) {
return x !== null && (type === 'object' || type === 'function'); return x !== null && (type === 'object' || type === 'function');
} }
export function isNumber(value) { export function isNumber(value) {
return /^\d+$/.test(value); return /^\d+(\.\d+)?$/.test(value);
} }
export function range(num, min, max) { export function range(num, min, max) {
return Math.min(Math.max(num, min), max); return Math.min(Math.max(num, min), max);
...@@ -23,3 +23,10 @@ export function getSystemInfoSync() { ...@@ -23,3 +23,10 @@ export function getSystemInfoSync() {
} }
return systemInfo; return systemInfo;
} }
export function addUnit(value) {
if (!isDef(value)) {
return undefined;
}
value = String(value);
return isNumber(value) ? `${value}px` : value;
}
export declare function canIUseModel(): boolean;
import { getSystemInfoSync } from './utils';
function compareVersion(v1, v2) {
v1 = v1.split('.');
v2 = v2.split('.');
const len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push('0');
}
while (v2.length < len) {
v2.push('0');
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i], 10);
const num2 = parseInt(v2[i], 10);
if (num1 > num2) {
return 1;
}
if (num1 < num2) {
return -1;
}
}
return 0;
}
export function canIUseModel() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.9.3') >= 0;
}
import { VantComponent } from '../common/component';
import { isSameSecond, parseFormat, parseTimeData } from './utils';
function simpleTick(fn) {
return setTimeout(fn, 30);
}
VantComponent({
props: {
useSlot: Boolean,
millisecond: Boolean,
time: {
type: Number,
observer: 'reset',
},
format: {
type: String,
value: 'HH:mm:ss',
},
autoStart: {
type: Boolean,
value: true,
},
},
data: {
timeData: parseTimeData(0),
formattedTime: '0',
},
destroyed() {
clearTimeout(this.tid);
this.tid = null;
},
methods: {
// 开始
start() {
if (this.counting) {
return;
}
this.counting = true;
this.endTime = Date.now() + this.remain;
this.tick();
},
// 暂停
pause() {
this.counting = false;
clearTimeout(this.tid);
},
// 重置
reset() {
this.pause();
this.remain = this.data.time;
this.setRemain(this.remain);
if (this.data.autoStart) {
this.start();
}
},
tick() {
if (this.data.millisecond) {
this.microTick();
} else {
this.macroTick();
}
},
microTick() {
this.tid = simpleTick(() => {
this.setRemain(this.getRemain());
if (this.remain !== 0) {
this.microTick();
}
});
},
macroTick() {
this.tid = simpleTick(() => {
const remain = this.getRemain();
if (!isSameSecond(remain, this.remain) || remain === 0) {
this.setRemain(remain);
}
if (this.remain !== 0) {
this.macroTick();
}
});
},
getRemain() {
return Math.max(this.endTime - Date.now(), 0);
},
setRemain(remain) {
this.remain = remain;
const timeData = parseTimeData(remain);
if (this.data.useSlot) {
this.$emit('change', timeData);
}
this.setData({
formattedTime: parseFormat(this.data.format, timeData),
});
if (remain === 0) {
this.pause();
this.$emit('finish');
}
},
},
});
<view class="van-count-down">
<slot wx:if="{{ useSlot }}"/>
<block wx:else>{{ formattedTime }}</block>
</view>
@import '../common/index.wxss';.van-count-down{color:#323233;color:var(--count-down-text-color,#323233);font-size:14px;font-size:var(--count-down-font-size,14px);line-height:20px;line-height:var(--count-down-line-height,20px)}
\ No newline at end of file
export declare type TimeData = {
days: number;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
};
export declare function parseTimeData(time: number): TimeData;
export declare function parseFormat(format: string, timeData: TimeData): string;
export declare function isSameSecond(time1: number, time2: number): boolean;
function padZero(num, targetLength = 2) {
let str = num + '';
while (str.length < targetLength) {
str = '0' + str;
}
return str;
}
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
export function parseTimeData(time) {
const days = Math.floor(time / DAY);
const hours = Math.floor((time % DAY) / HOUR);
const minutes = Math.floor((time % HOUR) / MINUTE);
const seconds = Math.floor((time % MINUTE) / SECOND);
const milliseconds = Math.floor(time % SECOND);
return {
days,
hours,
minutes,
seconds,
milliseconds,
};
}
export function parseFormat(format, timeData) {
const { days } = timeData;
let { hours, minutes, seconds, milliseconds } = timeData;
if (format.indexOf('DD') === -1) {
hours += days * 24;
} else {
format = format.replace('DD', padZero(days));
}
if (format.indexOf('HH') === -1) {
minutes += hours * 60;
} else {
format = format.replace('HH', padZero(hours));
}
if (format.indexOf('mm') === -1) {
seconds += minutes * 60;
} else {
format = format.replace('mm', padZero(minutes));
}
if (format.indexOf('ss') === -1) {
milliseconds += seconds * 1000;
} else {
format = format.replace('ss', padZero(seconds));
}
return format.replace('SSS', padZero(milliseconds, 3));
}
export function isSameSecond(time1, time2) {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000);
}
...@@ -20,8 +20,7 @@ function times(n, iteratee) { ...@@ -20,8 +20,7 @@ function times(n, iteratee) {
return result; return result;
} }
function getTrueValue(formattedValue) { function getTrueValue(formattedValue) {
if (!formattedValue) if (!formattedValue) return;
return;
while (isNaN(parseInt(formattedValue, 10))) { while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1); formattedValue = formattedValue.slice(1);
} }
...@@ -33,47 +32,59 @@ function getMonthEndDay(year, month) { ...@@ -33,47 +32,59 @@ function getMonthEndDay(year, month) {
const defaultFormatter = (_, value) => value; const defaultFormatter = (_, value) => value;
VantComponent({ VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'], classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign({}, pickerProps, { formatter: { props: Object.assign(Object.assign({}, pickerProps), {
type: Function, value: {
value: defaultFormatter type: null,
}, value: null, type: { observer: 'updateValue',
},
filter: null,
type: {
type: String, type: String,
value: 'datetime' value: 'datetime',
}, showToolbar: { observer: 'updateValue',
},
showToolbar: {
type: Boolean, type: Boolean,
value: true value: true,
}, minDate: { },
formatter: {
type: null,
value: defaultFormatter,
},
minDate: {
type: Number, type: Number,
value: new Date(currentYear - 10, 0, 1).getTime() value: new Date(currentYear - 10, 0, 1).getTime(),
}, maxDate: { observer: 'updateValue',
},
maxDate: {
type: Number, type: Number,
value: new Date(currentYear + 10, 11, 31).getTime() value: new Date(currentYear + 10, 11, 31).getTime(),
}, minHour: { observer: 'updateValue',
},
minHour: {
type: Number, type: Number,
value: 0 value: 0,
}, maxHour: { observer: 'updateValue',
},
maxHour: {
type: Number, type: Number,
value: 23 value: 23,
}, minMinute: { observer: 'updateValue',
},
minMinute: {
type: Number, type: Number,
value: 0 value: 0,
}, maxMinute: { observer: 'updateValue',
},
maxMinute: {
type: Number, type: Number,
value: 59 value: 59,
} }), observer: 'updateValue',
},
}),
data: { data: {
innerValue: Date.now(), innerValue: Date.now(),
columns: [] columns: [],
},
watch: {
value: 'updateValue',
type: 'updateValue',
minDate: 'updateValue',
maxDate: 'updateValue',
minHour: 'updateValue',
maxHour: 'updateValue',
minMinute: 'updateValue',
maxMinute: 'updateValue'
}, },
methods: { methods: {
updateValue() { updateValue() {
...@@ -84,8 +95,7 @@ VantComponent({ ...@@ -84,8 +95,7 @@ VantComponent({
this.updateColumnValue(val).then(() => { this.updateColumnValue(val).then(() => {
this.$emit('input', val); this.$emit('input', val);
}); });
} } else {
else {
this.updateColumns(); this.updateColumns();
} }
}, },
...@@ -94,21 +104,32 @@ VantComponent({ ...@@ -94,21 +104,32 @@ VantComponent({
this.picker = this.selectComponent('.van-datetime-picker'); this.picker = this.selectComponent('.van-datetime-picker');
const { picker } = this; const { picker } = this;
const { setColumnValues } = picker; const { setColumnValues } = picker;
picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]); picker.setColumnValues = (...args) =>
setColumnValues.apply(picker, [...args, false]);
} }
return this.picker; return this.picker;
}, },
updateColumns() { updateColumns() {
const { formatter = defaultFormatter } = this.data; const { formatter = defaultFormatter } = this.data;
const results = this.getOriginColumns().map((column) => ({
values: column.values.map((value) => formatter(column.type, value)),
}));
return this.set({ columns: results });
},
getOriginColumns() {
const { filter } = this.data;
const results = this.getRanges().map(({ type, range }) => { const results = this.getRanges().map(({ type, range }) => {
const values = times(range[1] - range[0] + 1, index => { let values = times(range[1] - range[0] + 1, (index) => {
let value = range[0] + index; let value = range[0] + index;
value = type === 'year' ? `${value}` : padZero(value); value = type === 'year' ? `${value}` : padZero(value);
return formatter(type, value); return value;
}); });
return { values }; if (filter) {
values = filter(type, values);
}
return { type, values };
}); });
return this.set({ columns: results }); return results;
}, },
getRanges() { getRanges() {
const { data } = this; const { data } = this;
...@@ -116,42 +137,52 @@ VantComponent({ ...@@ -116,42 +137,52 @@ VantComponent({
return [ return [
{ {
type: 'hour', type: 'hour',
range: [data.minHour, data.maxHour] range: [data.minHour, data.maxHour],
}, },
{ {
type: 'minute', type: 'minute',
range: [data.minMinute, data.maxMinute] range: [data.minMinute, data.maxMinute],
} },
]; ];
} }
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', data.innerValue); const {
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', data.innerValue); maxYear,
maxDate,
maxMonth,
maxHour,
maxMinute,
} = this.getBoundary('max', data.innerValue);
const {
minYear,
minDate,
minMonth,
minHour,
minMinute,
} = this.getBoundary('min', data.innerValue);
const result = [ const result = [
{ {
type: 'year', type: 'year',
range: [minYear, maxYear] range: [minYear, maxYear],
}, },
{ {
type: 'month', type: 'month',
range: [minMonth, maxMonth] range: [minMonth, maxMonth],
}, },
{ {
type: 'day', type: 'day',
range: [minDate, maxDate] range: [minDate, maxDate],
}, },
{ {
type: 'hour', type: 'hour',
range: [minHour, maxHour] range: [minHour, maxHour],
}, },
{ {
type: 'minute', type: 'minute',
range: [minMinute, maxMinute] range: [minMinute, maxMinute],
} },
]; ];
if (data.type === 'date') if (data.type === 'date') result.splice(3, 2);
result.splice(3, 2); if (data.type === 'year-month') result.splice(2, 3);
if (data.type === 'year-month')
result.splice(2, 3);
return result; return result;
}, },
correctValue(value) { correctValue(value) {
...@@ -160,8 +191,7 @@ VantComponent({ ...@@ -160,8 +191,7 @@ VantComponent({
const isDateType = data.type !== 'time'; const isDateType = data.type !== 'time';
if (isDateType && !isValidDate(value)) { if (isDateType && !isValidDate(value)) {
value = data.minDate; value = data.minDate;
} } else if (!isDateType && !value) {
else if (!isDateType && !value) {
const { minHour } = data; const { minHour } = data;
value = `${padZero(minHour)}:00`; value = `${padZero(minHour)}:00`;
} }
...@@ -208,7 +238,7 @@ VantComponent({ ...@@ -208,7 +238,7 @@ VantComponent({
[`${type}Month`]: month, [`${type}Month`]: month,
[`${type}Date`]: date, [`${type}Date`]: date,
[`${type}Hour`]: hour, [`${type}Hour`]: hour,
[`${type}Minute`]: minute [`${type}Minute`]: minute,
}; };
}, },
onCancel() { onCancel() {
...@@ -223,9 +253,9 @@ VantComponent({ ...@@ -223,9 +253,9 @@ VantComponent({
const picker = this.getPicker(); const picker = this.getPicker();
if (data.type === 'time') { if (data.type === 'time') {
const indexes = picker.getIndexes(); const indexes = picker.getIndexes();
value = `${indexes[0] + data.minHour}:${indexes[1] + data.minMinute}`; value = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1]
} .values[indexes[1]]}`;
else { } else {
const values = picker.getValues(); const values = picker.getValues();
const year = getTrueValue(values[0]); const year = getTrueValue(values[0]);
const month = getTrueValue(values[1]); const month = getTrueValue(values[1]);
...@@ -255,33 +285,33 @@ VantComponent({ ...@@ -255,33 +285,33 @@ VantComponent({
const picker = this.getPicker(); const picker = this.getPicker();
if (type === 'time') { if (type === 'time') {
const pair = value.split(':'); const pair = value.split(':');
values = [ values = [formatter('hour', pair[0]), formatter('minute', pair[1])];
formatter('hour', pair[0]), } else {
formatter('minute', pair[1])
];
}
else {
const date = new Date(value); const date = new Date(value);
values = [ values = [
formatter('year', `${date.getFullYear()}`), formatter('year', `${date.getFullYear()}`),
formatter('month', padZero(date.getMonth() + 1)) formatter('month', padZero(date.getMonth() + 1)),
]; ];
if (type === 'date') { if (type === 'date') {
values.push(formatter('day', padZero(date.getDate()))); values.push(formatter('day', padZero(date.getDate())));
} }
if (type === 'datetime') { if (type === 'datetime') {
values.push(formatter('day', padZero(date.getDate())), formatter('hour', padZero(date.getHours())), formatter('minute', padZero(date.getMinutes()))); values.push(
formatter('day', padZero(date.getDate())),
formatter('hour', padZero(date.getHours())),
formatter('minute', padZero(date.getMinutes()))
);
} }
} }
return this.set({ innerValue: value }) return this.set({ innerValue: value })
.then(() => this.updateColumns()) .then(() => this.updateColumns())
.then(() => picker.setValues(values)); .then(() => picker.setValues(values));
} },
}, },
created() { created() {
const innerValue = this.correctValue(this.data.value); const innerValue = this.correctValue(this.data.value);
this.updateColumnValue(innerValue).then(() => { this.updateColumnValue(innerValue).then(() => {
this.$emit('input', innerValue); this.$emit('input', innerValue);
}); });
} },
}); });
...@@ -3,22 +3,19 @@ import { Weapp } from './weapp'; ...@@ -3,22 +3,19 @@ import { Weapp } from './weapp';
declare type RecordToAny<T> = { declare type RecordToAny<T> = {
[K in keyof T]: any; [K in keyof T]: any;
}; };
declare type RecordToReturn<T> = { export declare type CombinedComponentInstance<Data, Props, Methods> = Methods & WechatMiniprogram.Component.TrivialInstance & Weapp.FormField & {
[P in keyof T]: T[P] extends (...args: any[]) => any ? ReturnType<T[P]> : T[P]; data: Data & RecordToAny<Props>;
}; };
export declare type CombinedComponentInstance<Data, Props, Methods, Computed> = Methods & WechatMiniprogram.Component.TrivialInstance & Weapp.FormField & { export interface VantComponentOptions<Data, Props, Methods, Instance> {
data: Data & RecordToReturn<Computed> & RecordToAny<Props>;
};
export interface VantComponentOptions<Data, Props, Methods, Computed, Instance> {
data?: Data; data?: Data;
field?: boolean; field?: boolean;
classes?: string[]; classes?: string[];
mixins?: string[]; mixins?: string[];
props?: Props & Weapp.PropertyOption; props?: Props & Weapp.PropertyOption;
watch?: Weapp.WatchOption<Instance>;
computed?: Computed & Weapp.ComputedOption<Instance>;
relation?: Weapp.RelationOption<Instance> & { relation?: Weapp.RelationOption<Instance> & {
type: 'ancestor' | 'descendant';
name: string; name: string;
current: string;
}; };
relations?: { relations?: {
[componentName: string]: Weapp.RelationOption<Instance>; [componentName: string]: Weapp.RelationOption<Instance>;
......
/// <reference types="miniprogram-api-typings" /> /// <reference types="miniprogram-api-typings" />
export declare namespace Weapp { export declare namespace Weapp {
interface FormField { export interface FormField {
data: { data: {
name: string; name: string;
value: any; value: any;
...@@ -13,7 +13,7 @@ export declare namespace Weapp { ...@@ -13,7 +13,7 @@ export declare namespace Weapp {
[key: string]: any; [key: string]: any;
}; };
} }
interface Event { export interface Event {
/** /**
* 代表事件的类型。 * 代表事件的类型。
*/ */
...@@ -57,14 +57,14 @@ export declare namespace Weapp { ...@@ -57,14 +57,14 @@ export declare namespace Weapp {
*/ */
clientY: number; clientY: number;
} }
interface TouchEvent extends Event { export interface TouchEvent extends Event {
touches: Array<Touch>; touches: Array<Touch>;
changedTouches: Array<Touch>; changedTouches: Array<Touch>;
} }
/** /**
* relation定义,miniprogram-api-typings缺少this定义 * relation定义,miniprogram-api-typings缺少this定义
*/ */
interface RelationOption<Instance> { export interface RelationOption<Instance> {
/** 目标组件的相对关系 */ /** 目标组件的相对关系 */
type: 'parent' | 'child' | 'ancestor' | 'descendant'; type: 'parent' | 'child' | 'ancestor' | 'descendant';
/** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */ /** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */
...@@ -80,23 +80,17 @@ export declare namespace Weapp { ...@@ -80,23 +80,17 @@ export declare namespace Weapp {
* obverser定义,miniprogram-api-typings缺少this定义 * obverser定义,miniprogram-api-typings缺少this定义
*/ */
type Observer<Instance, T> = (this: Instance, newVal: T, oldVal: T, changedPath: Array<string | number>) => void; type Observer<Instance, T> = (this: Instance, newVal: T, oldVal: T, changedPath: Array<string | number>) => void;
/**
* watch定义
*/
interface WatchOption<Instance> {
[name: string]: string | Observer<Instance, any>;
}
/** /**
* methods定义,miniprogram-api-typings缺少this定义 * methods定义,miniprogram-api-typings缺少this定义
*/ */
interface MethodOption<Instance> { export interface MethodOption<Instance> {
[name: string]: (this: Instance, ...args: any[]) => any; [name: string]: (this: Instance, ...args: any[]) => any;
} }
interface ComputedOption<Instance> { export interface ComputedOption<Instance> {
[name: string]: (this: Instance) => any; [name: string]: (this: Instance) => any;
} }
type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | null; type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | null;
interface PropertyOption { export interface PropertyOption {
[name: string]: PropertyType | PropertyType[] | { [name: string]: PropertyType | PropertyType[] | {
/** 属性类型 */ /** 属性类型 */
type: PropertyType | PropertyType[]; type: PropertyType | PropertyType[];
...@@ -108,4 +102,5 @@ export declare namespace Weapp { ...@@ -108,4 +102,5 @@ export declare namespace Weapp {
optionalTypes?: PropertyType[]; optionalTypes?: PropertyType[];
}; };
} }
export {};
} }
...@@ -4,6 +4,7 @@ declare type DialogOptions = { ...@@ -4,6 +4,7 @@ declare type DialogOptions = {
lang?: string; lang?: string;
show?: boolean; show?: boolean;
title?: string; title?: string;
width?: string | number;
zIndex?: number; zIndex?: number;
context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance; context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
message?: string; message?: string;
...@@ -16,6 +17,7 @@ declare type DialogOptions = { ...@@ -16,6 +17,7 @@ declare type DialogOptions = {
asyncClose?: boolean; asyncClose?: boolean;
businessId?: number; businessId?: number;
sessionFrom?: string; sessionFrom?: string;
overlayStyle?: string;
appParameter?: string; appParameter?: string;
messageAlign?: string; messageAlign?: string;
sendMessageImg?: string; sendMessageImg?: string;
......
...@@ -3,55 +3,61 @@ function getContext() { ...@@ -3,55 +3,61 @@ function getContext() {
const pages = getCurrentPages(); const pages = getCurrentPages();
return pages[pages.length - 1]; return pages[pages.length - 1];
} }
const Dialog = options => { const Dialog = (options) => {
options = Object.assign({}, Dialog.currentOptions, options); options = Object.assign(Object.assign({}, Dialog.currentOptions), options);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const context = options.context || getContext(); const context = options.context || getContext();
const dialog = context.selectComponent(options.selector); const dialog = context.selectComponent(options.selector);
delete options.context; delete options.context;
delete options.selector; delete options.selector;
if (dialog) { if (dialog) {
dialog.set(Object.assign({ onCancel: reject, onConfirm: resolve }, options)); dialog.setData(
Object.assign({ onCancel: reject, onConfirm: resolve }, options)
);
queue.push(dialog); queue.push(dialog);
} } else {
else { console.warn(
console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确'); '未找到 van-dialog 节点,请确认 selector 及 context 是否正确'
);
} }
}); });
}; };
Dialog.defaultOptions = { Dialog.defaultOptions = {
show: true, show: true,
title: '', title: '',
width: null,
message: '', message: '',
zIndex: 100, zIndex: 100,
overlay: true, overlay: true,
selector: '#van-dialog',
className: '', className: '',
customStyle: '',
asyncClose: false, asyncClose: false,
messageAlign: '',
transition: 'scale', transition: 'scale',
selector: '#van-dialog', customStyle: '',
messageAlign: '',
overlayStyle: '',
confirmButtonText: '确认', confirmButtonText: '确认',
cancelButtonText: '取消', cancelButtonText: '取消',
showConfirmButton: true, showConfirmButton: true,
showCancelButton: false, showCancelButton: false,
closeOnClickOverlay: false, closeOnClickOverlay: false,
confirmButtonOpenType: '' confirmButtonOpenType: '',
}; };
Dialog.alert = Dialog; Dialog.alert = Dialog;
Dialog.confirm = options => Dialog(Object.assign({ showCancelButton: true }, options)); Dialog.confirm = (options) =>
Dialog(Object.assign({ showCancelButton: true }, options));
Dialog.close = () => { Dialog.close = () => {
queue.forEach(dialog => { queue.forEach((dialog) => {
dialog.close(); dialog.close();
}); });
queue = []; queue = [];
}; };
Dialog.stopLoading = () => { Dialog.stopLoading = () => {
queue.forEach(dialog => { queue.forEach((dialog) => {
dialog.stopLoading(); dialog.stopLoading();
}); });
}; };
Dialog.setDefaultOptions = options => { Dialog.setDefaultOptions = (options) => {
Object.assign(Dialog.currentOptions, options); Object.assign(Dialog.currentOptions, options);
}; };
Dialog.resetDefaultOptions = () => { Dialog.resetDefaultOptions = () => {
......
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { button } from '../mixins/button'; import { button } from '../mixins/button';
import { openType } from '../mixins/open-type'; import { openType } from '../mixins/open-type';
import { GRAY, BLUE } from '../common/color';
VantComponent({ VantComponent({
mixins: [button, openType], mixins: [button, openType],
props: { props: {
show: Boolean, show: {
type: Boolean,
observer(show) {
!show && this.stopLoading();
},
},
title: String, title: String,
message: String, message: String,
useSlot: Boolean, useSlot: Boolean,
...@@ -12,44 +18,50 @@ VantComponent({ ...@@ -12,44 +18,50 @@ VantComponent({
customStyle: String, customStyle: String,
asyncClose: Boolean, asyncClose: Boolean,
messageAlign: String, messageAlign: String,
overlayStyle: String,
useTitleSlot: Boolean,
showCancelButton: Boolean, showCancelButton: Boolean,
closeOnClickOverlay: Boolean, closeOnClickOverlay: Boolean,
confirmButtonOpenType: String, confirmButtonOpenType: String,
width: null,
zIndex: { zIndex: {
type: Number, type: Number,
value: 2000 value: 2000,
}, },
confirmButtonText: { confirmButtonText: {
type: String, type: String,
value: '确认' value: '确认',
}, },
cancelButtonText: { cancelButtonText: {
type: String, type: String,
value: '取消' value: '取消',
},
confirmButtonColor: {
type: String,
value: BLUE,
},
cancelButtonColor: {
type: String,
value: GRAY,
}, },
showConfirmButton: { showConfirmButton: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
overlay: { overlay: {
type: Boolean, type: Boolean,
value: true value: true,
}, },
transition: { transition: {
type: String, type: String,
value: 'scale' value: 'scale',
} },
}, },
data: { data: {
loading: { loading: {
confirm: false, confirm: false,
cancel: false cancel: false,
}
}, },
watch: {
show(show) {
!show && this.stopLoading();
}
}, },
methods: { methods: {
onConfirm() { onConfirm() {
...@@ -63,23 +75,23 @@ VantComponent({ ...@@ -63,23 +75,23 @@ VantComponent({
}, },
handleAction(action) { handleAction(action) {
if (this.data.asyncClose) { if (this.data.asyncClose) {
this.set({ this.setData({
[`loading.${action}`]: true [`loading.${action}`]: true,
}); });
} }
this.onClose(action); this.onClose(action);
}, },
close() { close() {
this.set({ this.setData({
show: false show: false,
}); });
}, },
stopLoading() { stopLoading() {
this.set({ this.setData({
loading: { loading: {
confirm: false, confirm: false,
cancel: false cancel: false,
} },
}); });
}, },
onClose(action) { onClose(action) {
...@@ -89,10 +101,12 @@ VantComponent({ ...@@ -89,10 +101,12 @@ VantComponent({
this.$emit('close', action); this.$emit('close', action);
// 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading // 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
this.$emit(action, { dialog: this }); this.$emit(action, { dialog: this });
const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel']; const callback = this.data[
action === 'confirm' ? 'onConfirm' : 'onCancel'
];
if (callback) { if (callback) {
callback(this); callback(this);
} }
} },
} },
}); });
<wxs src="../wxs/utils.wxs" module="utils" />
<van-popup <van-popup
show="{{ show }}" show="{{ show }}"
z-index="{{ zIndex }}" z-index="{{ zIndex }}"
overlay="{{ overlay }}" overlay="{{ overlay }}"
custom-class="van-dialog {{ className }}"
transition="{{ transition }}" transition="{{ transition }}"
custom-style="{{ customStyle }}" custom-class="van-dialog {{ className }}"
custom-style="width: {{ utils.addUnit(width) }};{{ customStyle }}"
overlay-style="{{ overlayStyle }}"
close-on-click-overlay="{{ closeOnClickOverlay }}" close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClickOverlay" bind:close="onClickOverlay"
> >
<view <view
wx:if="{{ title }}" wx:if="{{ title || useTitleSlot }}"
class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}" class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}"
> >
{{ title }} <slot wx:if="{{ useTitleSlot }}" name="title" />
<block wx:elif="{{ title }}">{{ title }}</block>
</view> </view>
<slot wx:if="{{ useSlot }}" /> <slot wx:if="{{ useSlot }}" />
...@@ -20,7 +24,7 @@ ...@@ -20,7 +24,7 @@
wx:elif="{{ message }}" wx:elif="{{ message }}"
class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}" class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}"
> >
<text>{{ message }}</text> <text class="van-dialog__message-text">{{ message }}</text>
</view> </view>
<view class="van-hairline--top van-dialog__footer"> <view class="van-hairline--top van-dialog__footer">
...@@ -30,6 +34,7 @@ ...@@ -30,6 +34,7 @@
loading="{{ loading.cancel }}" loading="{{ loading.cancel }}"
class="van-dialog__button van-hairline--right" class="van-dialog__button van-hairline--right"
custom-class="van-dialog__cancel" custom-class="van-dialog__cancel"
custom-style="color: {{ cancelButtonColor }}"
bind:click="onCancel" bind:click="onCancel"
> >
{{ cancelButtonText }} {{ cancelButtonText }}
...@@ -40,6 +45,7 @@ ...@@ -40,6 +45,7 @@
class="van-dialog__button" class="van-dialog__button"
loading="{{ loading.confirm }}" loading="{{ loading.confirm }}"
custom-class="van-dialog__confirm" custom-class="van-dialog__confirm"
custom-style="color: {{ confirmButtonColor }}"
open-type="{{ confirmButtonOpenType }}" open-type="{{ confirmButtonOpenType }}"
lang="{{ lang }}" lang="{{ lang }}"
......
@import '../common/index.wxss';.van-dialog{top:45%!important;width:85%;overflow:hidden;font-size:16px;background-color:#fff;border-radius:4px}.van-dialog__header{padding-top:25px;font-weight:500;line-height:24px;text-align:center}.van-dialog__header--isolated{padding:25px 0}.van-dialog__message{max-height:60vh;padding:25px;overflow-y:auto;font-size:14px;line-height:20px;text-align:center;-webkit-overflow-scrolling:touch}.van-dialog__message--has-title{padding-top:12px;color:#7d7e80}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog__confirm{color:#1989fa!important}.van-dialog-bounce-enter{opacity:0;-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7)}.van-dialog-bounce-leave-active{opacity:0;-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9)} @import '../common/index.wxss';.van-dialog{top:45%!important;overflow:hidden;width:320px;width:var(--dialog-width,320px);font-size:16px;font-size:var(--dialog-font-size,16px);border-radius:16px;border-radius:var(--dialog-border-radius,16px);background-color:#fff;background-color:var(--dialog-background-color,#fff)}@media (max-width:321px){.van-dialog{width:90%;width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{text-align:center;padding-top:24px;padding-top:var(--dialog-header-padding-top,24px);font-weight:500;font-weight:var(--dialog-header-font-weight,500);line-height:24px;line-height:var(--dialog-header-line-height,24px)}.van-dialog__header--isolated{padding:24px 0;padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{overflow-y:auto;text-align:center;-webkit-overflow-scrolling:touch;font-size:14px;font-size:var(--dialog-message-font-size,14px);line-height:20px;line-height:var(--dialog-message-line-height,20px);max-height:60vh;max-height:var(--dialog-message-max-height,60vh);padding:24px;padding:var(--dialog-message-padding,24px)}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--has-title{padding-top:12px;padding-top:var(--dialog-has-title-message-padding-top,12px);color:#646566;color:var(--dialog-has-title-message-text-color,#646566)}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-dialog-bounce-leave-active{-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9);opacity:0}
\ No newline at end of file \ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
dashed: {
type: Boolean,
value: false,
},
hairline: {
type: Boolean,
value: false,
},
contentPosition: {
type: String,
value: '',
},
fontSize: {
type: Number,
value: '',
},
borderColor: {
type: String,
value: '',
},
textColor: {
type: String,
value: '',
},
customStyle: {
type: String,
value: '',
},
},
});
{
"component": true,
"usingComponents": {}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('divider', [{dashed, hairline}, contentPosition]) }}"
style="{{ borderColor ? 'border-color: ' + borderColor + ';' : '' }}{{ textColor ? 'color: ' + textColor + ';' : '' }} {{ fontSize ? 'font-size: ' + fontSize + 'px;' : '' }} {{ customStyle }}"
>
<slot />
</view>
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.
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.
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.
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.
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.
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.
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.
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.
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.
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