9f6b00c9 by simon

默认提交

1 parent 2632c460
Showing 258 changed files with 1819 additions and 511 deletions
...@@ -11,7 +11,7 @@ module.exports = { ...@@ -11,7 +11,7 @@ module.exports = {
11 "enabledQcloud": false, //是否开启腾讯云COS 上传功能 11 "enabledQcloud": false, //是否开启腾讯云COS 上传功能
12 // 腾讯云COS 上传功能配置表 12 // 腾讯云COS 上传功能配置表
13 "qcloud": { 13 "qcloud": {
14 "appid": "1111111", 14 "appid": "wxd5e3b4b2e7ce2c1a",
15 "secretId": "xxx", 15 "secretId": "xxx",
16 "secretKey": "xxxxx", 16 "secretKey": "xxxxx",
17 "bucket": "xxxx", 17 "bucket": "xxxx",
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
8 "minified": true, 8 "minified": true,
9 "newFeature": true 9 "newFeature": true
10 }, 10 },
11 "appid": "wxc57ed87f2569f701", 11 "appid": "wxd5e3b4b2e7ce2c1a",
12 "projectname": "gulp-example", 12 "projectname": "gulp-example",
13 "condition": {} 13 "condition": {}
14 } 14 }
......
1 { 1 {
2 "pages": [ 2 "pages": [
3 "pages/index/index", 3 "pages/index/index",
4 "pages/detail/detail",
4 "pages/more/more", 5 "pages/more/more",
5 "pages/poster-example/poster-example", 6 "pages/poster-example/poster-example",
6 "pages/authorize/authorize", 7 "pages/authorize/authorize",
...@@ -9,31 +10,15 @@ ...@@ -9,31 +10,15 @@
9 "window": { 10 "window": {
10 "backgroundTextStyle": "light", 11 "backgroundTextStyle": "light",
11 "navigationBarBackgroundColor": "#fff", 12 "navigationBarBackgroundColor": "#fff",
12 "navigationBarTitleText": "mp-gulp-framework", 13 "navigationBarTitleText": "家有儿孙",
13 "navigationBarTextStyle": "black" 14 "navigationBarTextStyle": "black"
14 }, 15 },
15 "tabBar": {
16 "color": "#7A7E83",
17 "selectedColor": "#CF4646",
18 "borderStyle": "black",
19 "backgroundColor": "#ffffff",
20 "list": [{
21 "pagePath": "pages/index/index",
22 "iconPath": "image/tabbar/home_D.png",
23 "selectedIconPath": "image/tabbar/home.png",
24 "text": "介绍"
25 },
26 {
27 "pagePath": "pages/more/more",
28 "iconPath": "image/tabbar/set_D.png",
29 "selectedIconPath": "image/tabbar/set.png",
30 "text": "更多"
31 }
32 ]
33 },
34 "usingComponents": { 16 "usingComponents": {
35 "authorize-comp": "../../component/authorize-comp/authorize-comp", 17 "authorize-comp": "../../component/authorize-comp/authorize-comp",
36 "empty-tips": "../../component/empty-tips/empty-tips", 18 "empty-tips": "../../component/empty-tips/empty-tips",
37 "van-popup": "../../ui/vant-weapp/popup/index" 19 "van-popup": "../../ui/vant-weapp/popup/index",
20 "van-sticky": "../../ui/vant-weapp/sticky/index",
21 "van-tab": "../../ui/vant-weapp/tab/index",
22 "van-tabs": "../../ui/vant-weapp/tabs/index"
38 } 23 }
39 } 24 }
......
1 @import "support"; 1 @import "support";
2 2
3 // // Margin
4 // .u-mt-smaller {
5 // margin-top: $marginTopSmaller;
6 // }
7
8 // .u-mt-small {
9 // margin-top: $marginTopSmall;
10 // }
11
12 // .u-mt-medium {
13 // margin-top: $marginTopMedium;
14 // }
15
16 // .u-mt-large {
17 // margin-top: $marginTopLarge;
18 // }
19
20 // .u-mt-larger {
21 // margin-top: $marginTopLarger;
22 // }
23
24 // .u-mb-smaller {
25 // margin-bottom: $marginTopSmaller;
26 // }
27
28 // .u-mb-small {
29 // margin-bottom: $marginTopSmall;
30 // }
31
32 // .u-mb-medium {
33 // margin-bottom: $marginTopMedium;
34 // }
35
36 // .u-mb-large {
37 // margin-bottom: $marginTopLarge;
38 // }
39
40 // .u-mb-larger {
41 // margin-bottom: $marginTopLarger;
42 // }
43
44 // // Padding
45 // .u-pt-smaller {
46 // padding-top: $paddingTopSmaller;
47 // }
48
49 // .u-pt-small {
50 // padding-top: $paddingTopSmall;
51 // }
52
53 // .u-pt-medium {
54 // padding-top: $paddingTopMedium;
55 // }
56
57 // .u-pt-large {
58 // padding-top: $paddingTopLarge;
59 // }
60
61 // .u-pt-larger {
62 // padding-top: $paddingTopLarger;
63 // }
64
65 // .u-pb-smaller {
66 // padding-bottom: $paddingTopSmaller;
67 // }
68
69 // .u-pb-small {
70 // padding-bottom: $paddingTopSmall;
71 // }
72
73 // .u-pb-medium {
74 // padding-bottom: $paddingTopMedium;
75 // }
76
77 // .u-pb-large {
78 // padding-bottom: $paddingTopLarge;
79 // }
80
81 // .u-pb-larger {
82 // padding-bottom: $paddingTopLarger;
83 // }
84
85 // // 布局方位
86 // .u-ta-c {
87 // text-align: center !important;
88 // }
89
90 // .u-ta-l {
91 // text-align: left !important;
92 // }
93
94 // .u-ta-r {
95 // text-align: right !important;
96 // }
97
98 // .u-fl-l {
99 // float: left;
100 // }
101
102 // .u-fl-n {
103 // float: none;
104 // }
105
106 // .u-fl-r {
107 // float: right;
108 // }
109
110 // .u-d-b {
111 // display: block;
112 // }
113
114 // .u-d-i {
115 // display: inline !important;
116 // }
117
118 // .u-d-ib {
119 // display: inline-block !important;
120 // }
121
122 // .u-d-n {
123 // display: none !important;
124 // }
125
126 // .u-d-t {
127 // display: table;
128 // table-layout: fixed;
129 // }
130
131 // .u-d-tc {
132 // display: table-cell;
133 // }
134
135 // .u-va-b {
136 // vertical-align: bottom;
137 // }
138
139 // .u-va-m {
140 // vertical-align: middle;
141 // }
142
143 // .u-va-t {
144 // vertical-align: top;
145 // }
146
147 // // clearfix
148 // .u-clearfix {
149 // @include clearfix;
150 // }
151
152 // // 虚拟格式
153 // .u-cur-d {
154 // cursor: default;
155 // }
156
157 // .u-cur-p {
158 // cursor: pointer;
159 // }
160
161 // // flex
162 // .u-flex {
163 // display: -webkit-box;
164 // display: -webkit-flex;
165 // display: flex;
166 // }
167
168 // .u-flex-item {
169 // -webkit-box-flex: 1;
170 // -webkit-flex: 1;
171 // flex: 1;
172 // }
173
174 // // 小程序中模拟ul、li
175 // .u-ul {
176 // padding-left: 30px;
177 // text-align: left;
178 // display: block;
179 // }
180
181 // .u-li {
182 // position: relative;
183 // font-size: $fontSizeSmall;
184 // line-height: $fontSizeSmall + 4px;
185 // margin-bottom: $marginTopSmall;
186 // &:before {
187 // position: absolute;
188 // content: " ";
189 // top: 14px;
190 // left: -20px;
191 // width: 8px;
192 // height: 8px;
193 // border-radius: 8px;
194 // background-color: $colorBlack;
195 // }
196 // }
197
198
199
200 .bis { 3 .bis {
201 background-repeat: no-repeat; 4 background-repeat: no-repeat;
202 background-size: 100% 100%; 5 background-size: 100% 100%;
...@@ -213,8 +16,6 @@ ...@@ -213,8 +16,6 @@
213 justify-content: space-between; 16 justify-content: space-between;
214 } 17 }
215 18
216
217
218 .fje { 19 .fje {
219 display: flex; 20 display: flex;
220 justify-content: flex-end; 21 justify-content: flex-end;
......
1 1 // Color
2
3 // // Margin
4 // $marginTopSmaller: 20px;
5 // $marginTopSmall: 30px;
6 // $marginTopMedium: 40px;
7 // $marginTopLarge: 60px;
8 // $marginTopLarger: 80px;
9
10 // // Padding
11 // $paddingTopSmaller: 20px;
12 // $paddingTopSmall: 30px;
13 // $paddingTopMedium: 40px;
14 // $paddingTopLarge: 60px;
15 // $paddingTopLarger: 80px;
16
17 // // Color
18 $colorBlue: #20A0FF; 2 $colorBlue: #20A0FF;
19 $colorGreen: #13CE66; 3 $colorGreen: #13CE66;
20 $colorGray: #475669; 4 $colorGray: #475669;
...@@ -39,3 +23,4 @@ $fontSizeLarger: 44px; ...@@ -39,3 +23,4 @@ $fontSizeLarger: 44px;
39 $colorMain:#3680EB; 23 $colorMain:#3680EB;
40 24
41 $pageBottom:80px; 25 $pageBottom:80px;
26 $contentWidth:690px;
......
1 import {
2 getBindtapData
3 } from '../../utils/util';
4
5 let app = getApp();
6 Page({
7 data: {
8 authorizeVisible: false,
9 total: 0,
10 page: 1,
11 size: 10,
12 productList: [], // 产品列表
13 indexInfo: {},
14 userInfo: {},
15 },
16 onShareAppMessage() {},
17 showAuth() {
18 this.setData({
19 authorizeVisible: true
20 })
21 },
22 onLoad(options) {},
23
24 /**
25 * 基础方法
26 * 授权完毕重拉数据用
27 */
28 initData() {
29
30 },
31 /**
32 * 到达底部
33 * 做加载更多操作
34 */
35 onReachBottom() {
36 if (this.data.dataList.length < this.data.total) {
37 this.setData({
38 page: this.data.page + 1
39 });
40 this.queryDataList();
41 }
42 },
43
44 // 重置页面列表 点击搜索条件时需要
45 resetPage() {
46 this.setData({
47 page: 1,
48 dataList: []
49 })
50 },
51
52 /**
53 * 请求DataList
54 */
55 queryDataList() {
56 return;
57 return new Promise((resolve, reject) => {
58 app.post({
59 sid: false,
60 url: app.api.dataList,
61 data: {
62 page: this.data.page,
63 size: this.data.size,
64 },
65 }).then((result) => {
66 let dataList = result.list;
67 dataList = this.data.dataList.concat(dataList);
68 this.setData({
69 dataList: dataList,
70 total: result.total
71 })
72 resolve();
73 })
74 });
75 },
76
77 /**
78 * 隐藏蒙层
79 */
80 hideMask() {
81 this.setData({
82 productDetailVisible: false,
83 authorizeVisible: false,
84 })
85 },
86 /**
87 * 子组件事件
88 * @param {*} evt
89 */
90 evtcomp(evt) {
91 let {
92 name,
93 data
94 } = evt.detail;
95 switch (name) {
96
97 // 隐藏蒙层
98 case "_evt_hide_mask":
99 this.hideMask();
100 break;
101
102 /**
103 * 重拉数据已在
104 */
105 case "_evt_auth_complete":
106 // this.initData();
107 this.hideMask();
108 break;
109
110 default:
111 break;
112 }
113 },
114 })
1 {
2 "navigationBarTitleText": ""
3 }
1 @import '../../assets/scss/mixins';
2 @import '../../assets/scss/utils';
3
4 .page {
5 .bgc {}
6
7 .bg {}
8
9 .main {
10 .top-space {
11 height: 0px;
12 }
13
14 .content {
15 position: relative;
16 }
17 }
18
19 .detail {
20 position: relative;
21 width: 100%;
22 height: 944px;
23 background-color: #333333;
24
25 .vid {
26 margin: 232px auto 0;
27 width: 100%;
28 height: 360px;
29 }
30
31 .btn-wrap {
32 color: #ffffff;
33 margin: 142px auto 0;
34 display: flex;
35
36 .btn {
37 width: 312px;
38 height: 94px;
39 font-size: 30px;
40 background-color: #3ec03c;
41 border-radius: 8px;
42 display: flex;
43 justify-content: center;
44 align-items: center;
45 color: #ffffff;
46
47 .iconfont {
48 font-size: 48px;
49 }
50
51 .t1 {
52 padding: 0 6px;
53 }
54 }
55
56 .btn2 {
57 background-color: #ae3f48;
58 }
59 }
60 }
61
62 .func {
63 position: relative;
64 @extend .bb;
65 padding: 24px 24px;
66 display: flex;
67 justify-content: space-between;
68 align-items: center;
69
70 .user {
71 display: flex;
72 align-items: center;
73 flex: 1;
74
75 .portrait {
76 width: 72px;
77 height: 72px;
78 border-radius: 72px;
79 }
80
81 .desc {
82 @extend .bb;
83 padding-left: 24px;
84 display: flex;
85 align-items: center;
86 align-content: center;
87 flex-wrap: wrap;
88
89 .t1 {
90 width: 100%;
91 }
92
93 .name {
94 font-size: 28px;
95 }
96
97 .num {
98 font-size: 24px;
99 color: #8d8d8d;
100 }
101 }
102
103 }
104
105 .btn-wrap {
106 display: flex;
107
108 .btn {
109 margin-right: 24px;
110 width: 180px;
111 height: 68px;
112 font-size: 24px;
113 background-color: #3ec03c;
114 border-radius: 8px;
115 display: flex;
116 justify-content: center;
117 align-items: center;
118 color: #ffffff;
119
120 .iconfont {
121 font-size: 32px;
122 }
123
124 .t1 {
125 padding: 0 6px;
126 }
127
128 &:last-child {
129 margin-right: 0;
130 }
131 }
132
133 .btn2 {
134 background-color: #fecd9f;
135 color: #7f776e;
136 }
137
138
139 }
140
141 }
142
143 .tit{
144 @extend .bb;
145 padding: 0 24px;
146 }
147 }
1 <view class="page">
2 <view class="app__bgc bgc"></view>
3 <view class="app__bg bg"></view>
4 <view class="app__content main">
5 <view class="top-space"></view>
6 <view class="content">
7 <view class="detail">
8 <video objectFit="cover" class="vid" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/7e91e8a4c7b84e6fa4bada7c8617c9cf.mp4" />
9 <view class="btn-wrap">
10 <button class="btn">
11 <span class="t1 iconfont iconplane"></span>
12 <span class="t1">分享给好友</span>
13 </button>
14 <button class="btn btn2">
15 <span class="t1 iconfont iconplane"></span>
16 <span class="t1">分享到群</span>
17 </button>
18 </view>
19 </view>
20 <view class="func">
21 <view class="user">
22 <image class="portrait" mode="aspectFill" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
23 <view class="desc">
24 <view class="t1 name">我爱我家</view>
25 <view class="t1 num">280个视频</view>
26 </view>
27 </view>
28 <view class="btn-wrap">
29 <view class="btn btn2">
30 <span>更多推荐</span>
31 </view>
32 <view class="btn">
33 <span class="t1 iconfont iconhome"></span>
34 <span>返回首页</span>
35 </view>
36 </view>
37 </view>
38 <view class="tit">超有创意的全家福,看了你也想拍!</view>
39 </view>
40 </view>
41 </view>
1 import {
2 getBindtapData
3 } from '../../utils/util'
4
1 let app = getApp(); 5 let app = getApp();
2 Page({ 6 Page({
3 data: {}, 7 data: {
4 onLoad(options) { 8 active: 0
9 },
10 onLoad(options) {},
11 initData() {
12
13 },
14 onChange(event) {
15 wx.showToast({
16 title: `切换到标签 ${event.detail.name}`,
17 icon: 'none'
18 });
19 },
20 onVanTabsHandler(event) {
21 console.log("event:", event);
22 let {
23 index,
24 title
25 } = event.detail;
26 },
27 onVideoHandler(evt) {
28 let curItem = getBindtapData(evt);
29 let curIndex = getBindtapData(evt, "index");
30 app.router.push({
31 path: "detail",
32 query: {
33 c: curIndex + ""
34 }
35 })
36 console.log("curItem:", curItem);
37 console.log("curIndex:", curIndex);
38 },
39 /**
40 * 获取列列表
41 */
42 queryList() {
43
5 } 44 }
6 }) 45 })
......
1 { 1 {
2 "navigationBarTitleText": "首页"
3 } 2 }
......
...@@ -2,7 +2,12 @@ ...@@ -2,7 +2,12 @@
2 @import '../../assets/scss/utils'; 2 @import '../../assets/scss/utils';
3 3
4 .page { 4 .page {
5 .bgc {} 5 color: #333333;
6 font-size: 24px;
7
8 .bgc {
9 background-color: #efefef;
10 }
6 11
7 .bg {} 12 .bg {}
8 13
...@@ -14,5 +19,101 @@ ...@@ -14,5 +19,101 @@
14 .content { 19 .content {
15 position: relative; 20 position: relative;
16 } 21 }
22
23 .list {
24 position: relative;
25 margin: 0 auto;
26 width: $contentWidth;
27
28 &-item {
29 position: relative;
30 background-color: #ffffff;
31 border-radius: 16px;
32 margin: 24px auto;
33
34 &-video {
35 display: flex;
36 justify-content: center;
37 position: relative;
38 width: $contentWidth;
39
40 .vid {
41 @include border-top-radius(16px);
42 width: $contentWidth;
43 pointer-events: none;
44 }
45
46 .tit {
47 color: #ffffff;
48 @extend .bb;
49 padding: 0 24px;
50 position: absolute;
51 width: 100%;
52 height: 64px;
53 line-height: 64px;
54 bottom: 0;
55 background-color: rgba($color: #000000, $alpha: 0.6);
56 @include border-top-radius(8px);
57 @include ellipsis(1);
58
59 }
60 }
61
62 &-func {
63 @extend .bb;
64 padding: 24px 24px;
65 height: 80px;
66 display: flex;
67 justify-content: space-between;
68 align-items: center;
69
70 .user {
71 display: flex;
72 align-items: center;
73
74 .portrait {
75 width: 48px;
76 height: 48px;
77 border-radius: 48px;
78 }
79
80 .name {
81 padding-left: 12px;
82 }
83 }
84
85 .share {
86 font-size: 24px;
87 display: flex;
88 justify-content: center;
89 align-items: center;
90 // width: 132px;
91 height: 48px;
92 color: #ffffff;
93 background-color: #3ec03c;
94 border-radius: 8px;
95 margin: 0;
96
97 .iconfont {
98 font-size: 32px;
99 }
100
101 .t1 {
102 padding: 0 6px;
103 }
104 }
105 }
106
107 }
108 }
109 }
110
111
112 .van-tab--active {
113 color: #fc464a;
114 }
115
116 .van-hairline--top-bottom:after {
117 border-width: 0;
17 } 118 }
18 } 119 }
......
...@@ -4,6 +4,33 @@ ...@@ -4,6 +4,33 @@
4 <!-- <view class="app__top-shadow"></view> --> 4 <!-- <view class="app__top-shadow"></view> -->
5 <view class="app__content main"> 5 <view class="app__content main">
6 <view class="top-space"></view> 6 <view class="top-space"></view>
7 <view class="content">index</view> 7 <van-sticky>
8 <van-tabs active="{{ active }}" bind:click="onVanTabsHandler">
9 <van-tab title="精彩推荐"></van-tab>
10 <van-tab title="一起旅行"></van-tab>
11 <van-tab title="齐家欢乐"></van-tab>
12 <van-tab title="童趣无限"></van-tab>
13 </van-tabs>
14 </van-sticky>
15 <view class="content">
16 <view class="list">
17 <view bindtap="onVideoHandler" wx:for="{{8}}" wx:key="index" data-data="{{item}}" data-index="{{index}}" class="list-item">
18 <view class="list-item-video">
19 <video objectFit="cover" class="vid" poster="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/7e91e8a4c7b84e6fa4bada7c8617c9cf.mp4" />
20 <view class="tit">这是一个视频</view>
21 </view>
22 <view class="list-item-func">
23 <view class="user">
24 <image class="portrait" mode="aspectFill" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
25 <text class="name">我爱我家</text>
26 </view>
27 <button class="share">
28 <span class="t1 iconfont iconwechat"></span>
29 <span class="t1">分享</span>
30 </button>
31 </view>
32 </view>
33 </view>
34 </view>
8 </view> 35 </view>
9 </view> 36 </view>
......
1 const routerPath = { 1 const routerPath = {
2 index: '/pages/index/index', 2 index: '/pages/index/index',
3 detail: '/pages/detail/detail',
3 authorize: '/pages/authorize/authorize', // 授权 4 authorize: '/pages/authorize/authorize', // 授权
4 example: '/pages/example/example', 5 example: '/pages/example/example',
5 more: '/pages/more/more', 6 more: '/pages/more/more',
......
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { safeArea } from '../mixins/safe-area';
3 VantComponent({ 2 VantComponent({
4 mixins: [safeArea()],
5 props: { 3 props: {
6 show: Boolean, 4 show: Boolean,
7 title: String, 5 title: String,
8 cancelText: String, 6 cancelText: String,
7 description: String,
8 round: {
9 type: Boolean,
10 value: true
11 },
9 zIndex: { 12 zIndex: {
10 type: Number, 13 type: Number,
11 value: 100 14 value: 100
...@@ -21,6 +24,14 @@ VantComponent({ ...@@ -21,6 +24,14 @@ VantComponent({
21 closeOnClickOverlay: { 24 closeOnClickOverlay: {
22 type: Boolean, 25 type: Boolean,
23 value: true 26 value: true
27 },
28 closeOnClickAction: {
29 type: Boolean,
30 value: true
31 },
32 safeAreaInsetBottom: {
33 type: Boolean,
34 value: true
24 } 35 }
25 }, 36 },
26 methods: { 37 methods: {
...@@ -29,6 +40,9 @@ VantComponent({ ...@@ -29,6 +40,9 @@ VantComponent({
29 const item = this.data.actions[index]; 40 const item = this.data.actions[index];
30 if (item && !item.disabled && !item.loading) { 41 if (item && !item.disabled && !item.loading) {
31 this.$emit('select', item); 42 this.$emit('select', item);
43 if (this.data.closeOnClickAction) {
44 this.onClose();
45 }
32 } 46 }
33 }, 47 },
34 onCancel() { 48 onCancel() {
...@@ -36,6 +50,10 @@ VantComponent({ ...@@ -36,6 +50,10 @@ VantComponent({
36 }, 50 },
37 onClose() { 51 onClose() {
38 this.$emit('close'); 52 this.$emit('close');
53 },
54 onClickOverlay() {
55 this.$emit('click-overlay');
56 this.onClose();
39 } 57 }
40 } 58 }
41 }); 59 });
......
...@@ -3,12 +3,13 @@ ...@@ -3,12 +3,13 @@
3 <van-popup 3 <van-popup
4 show="{{ show }}" 4 show="{{ show }}"
5 position="bottom" 5 position="bottom"
6 round="{{ round }}"
6 z-index="{{ zIndex }}" 7 z-index="{{ zIndex }}"
7 overlay="{{ overlay }}" 8 overlay="{{ overlay }}"
8 custom-class="van-action-sheet" 9 custom-class="van-action-sheet"
9 safe-area-inset-bottom="{{ safeAreaInsetBottom }}" 10 safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
10 close-on-click-overlay="{{ closeOnClickOverlay }}" 11 close-on-click-overlay="{{ closeOnClickOverlay }}"
11 bind:close="onClose" 12 bind:close="onClickOverlay"
12 > 13 >
13 <view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header"> 14 <view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header">
14 {{ title }} 15 {{ title }}
...@@ -18,12 +19,16 @@ ...@@ -18,12 +19,16 @@
18 bind:click="onClose" 19 bind:click="onClose"
19 /> 20 />
20 </view> 21 </view>
22 <view wx:if="{{ description }}" class="van-action-sheet__description">
23 {{ description }}
24 </view>
21 <view wx:if="{{ actions && actions.length }}"> 25 <view wx:if="{{ actions && actions.length }}">
22 <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 --> 26 <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
23 <button 27 <button
24 wx:for="{{ actions }}" 28 wx:for="{{ actions }}"
25 wx:key="index" 29 wx:key="index"
26 open-type="{{ item.openType }}" 30 open-type="{{ item.openType }}"
31 style="{{ item.color ? 'color: ' + item.color : '' }}"
27 class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}" 32 class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}"
28 hover-class="van-action-sheet__item--hover" 33 hover-class="van-action-sheet__item--hover"
29 data-index="{{ index }}" 34 data-index="{{ index }}"
...@@ -33,7 +38,7 @@ ...@@ -33,7 +38,7 @@
33 {{ item.name }} 38 {{ item.name }}
34 <text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text> 39 <text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text>
35 </block> 40 </block>
36 <van-loading wx:else size="20px" /> 41 <van-loading wx:else custom-class="van-action-sheet__loading" size="20px" />
37 </button> 42 </button>
38 </view> 43 </view>
39 <slot /> 44 <slot />
......
1 @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}
...\ No newline at end of file ...\ No newline at end of file
1 @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:#f8f8f8;background-color:var(--action-sheet-cancel-padding-color,#f8f8f8)}.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:#7d7e80;color:var(--action-sheet-subname-color,#7d7e80)}.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:#7d7e80;color:var(--action-sheet-description-color,#7d7e80);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
......
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { pickerProps } from '../picker/shared';
3 const COLUMNSPLACEHOLDERCODE = '000000';
2 VantComponent({ 4 VantComponent({
3 classes: ['active-class', 'toolbar-class', 'column-class'], 5 classes: ['active-class', 'toolbar-class', 'column-class'],
4 props: { 6 props: Object.assign(Object.assign({}, pickerProps), { value: String, areaList: {
5 title: String,
6 value: String,
7 loading: Boolean,
8 cancelButtonText: String,
9 confirmButtonText: String,
10 itemHeight: {
11 type: Number,
12 value: 44
13 },
14 visibleItemCount: {
15 type: Number,
16 value: 5
17 },
18 columnsNum: {
19 type: [String, Number],
20 value: 3
21 },
22 areaList: {
23 type: Object, 7 type: Object,
24 value: {} 8 value: {}
9 }, columnsNum: {
10 type: null,
11 value: 3
12 }, columnsPlaceholder: {
13 type: Array,
14 observer(val) {
15 this.setData({
16 typeToColumnsPlaceholder: {
17 province: val[0] || '',
18 city: val[1] || '',
19 county: val[2] || '',
25 } 20 }
26 }, 21 });
22 }
23 } }),
27 data: { 24 data: {
28 columns: [{ values: [] }, { values: [] }, { values: [] }], 25 columns: [{ values: [] }, { values: [] }, { values: [] }],
29 displayColumns: [{ values: [] }, { values: [] }, { values: [] }] 26 displayColumns: [{ values: [] }, { values: [] }, { values: [] }],
27 typeToColumnsPlaceholder: {}
30 }, 28 },
31 watch: { 29 watch: {
32 value(value) { 30 value(value) {
...@@ -35,11 +33,16 @@ VantComponent({ ...@@ -35,11 +33,16 @@ VantComponent({
35 }, 33 },
36 areaList: 'setValues', 34 areaList: 'setValues',
37 columnsNum(value) { 35 columnsNum(value) {
38 this.set({ 36 this.setData({
39 displayColumns: this.data.columns.slice(0, +value) 37 displayColumns: this.data.columns.slice(0, +value)
40 }); 38 });
41 } 39 }
42 }, 40 },
41 mounted() {
42 setTimeout(() => {
43 this.setValues();
44 }, 0);
45 },
43 methods: { 46 methods: {
44 getPicker() { 47 getPicker() {
45 if (this.picker == null) { 48 if (this.picker == null) {
...@@ -51,20 +54,40 @@ VantComponent({ ...@@ -51,20 +54,40 @@ VantComponent({
51 this.emit('cancel', event.detail); 54 this.emit('cancel', event.detail);
52 }, 55 },
53 onConfirm(event) { 56 onConfirm(event) {
54 this.emit('confirm', event.detail); 57 const { index } = event.detail;
58 let { value } = event.detail;
59 value = this.parseOutputValues(value);
60 this.emit('confirm', { value, index });
55 }, 61 },
56 emit(type, detail) { 62 emit(type, detail) {
57 detail.values = detail.value; 63 detail.values = detail.value;
58 delete detail.value; 64 delete detail.value;
59 this.$emit(type, detail); 65 this.$emit(type, detail);
60 }, 66 },
67 // parse output columns data
68 parseOutputValues(values) {
69 const { columnsPlaceholder } = this.data;
70 return values.map((value, index) => {
71 // save undefined value
72 if (!value)
73 return value;
74 value = JSON.parse(JSON.stringify(value));
75 if (!value.code || value.name === columnsPlaceholder[index]) {
76 value.code = '';
77 value.name = '';
78 }
79 return value;
80 });
81 },
61 onChange(event) { 82 onChange(event) {
62 const { index, picker, value } = event.detail; 83 const { index, picker, value } = event.detail;
63 this.code = value[index].code; 84 this.code = value[index].code;
85 let getValues = picker.getValues();
86 getValues = this.parseOutputValues(getValues);
64 this.setValues().then(() => { 87 this.setValues().then(() => {
65 this.$emit('change', { 88 this.$emit('change', {
66 picker, 89 picker,
67 values: picker.getValues(), 90 values: getValues,
68 index 91 index
69 }); 92 });
70 }); 93 });
...@@ -74,6 +97,7 @@ VantComponent({ ...@@ -74,6 +97,7 @@ VantComponent({
74 return (areaList && areaList[`${type}_list`]) || {}; 97 return (areaList && areaList[`${type}_list`]) || {};
75 }, 98 },
76 getList(type, code) { 99 getList(type, code) {
100 const { typeToColumnsPlaceholder } = this.data;
77 let result = []; 101 let result = [];
78 if (type !== 'province' && !code) { 102 if (type !== 'province' && !code) {
79 return result; 103 return result;
...@@ -90,6 +114,14 @@ VantComponent({ ...@@ -90,6 +114,14 @@ VantComponent({
90 } 114 }
91 result = result.filter(item => item.code.indexOf(code) === 0); 115 result = result.filter(item => item.code.indexOf(code) === 0);
92 } 116 }
117 if (typeToColumnsPlaceholder[type] && result.length) {
118 // set columns placeholder
119 const codeFill = type === 'province' ? '' : type === 'city' ? COLUMNSPLACEHOLDERCODE.slice(2, 4) : COLUMNSPLACEHOLDERCODE.slice(4, 6);
120 result.unshift({
121 code: `${code}${codeFill}`,
122 name: typeToColumnsPlaceholder[type]
123 });
124 }
93 return result; 125 return result;
94 }, 126 },
95 getIndex(type, code) { 127 getIndex(type, code) {
...@@ -109,7 +141,18 @@ VantComponent({ ...@@ -109,7 +141,18 @@ VantComponent({
109 }, 141 },
110 setValues() { 142 setValues() {
111 const county = this.getConfig('county'); 143 const county = this.getConfig('county');
112 let code = this.code || Object.keys(county)[0] || ''; 144 let { code } = this;
145 if (!code) {
146 if (this.data.columnsPlaceholder.length) {
147 code = COLUMNSPLACEHOLDERCODE;
148 }
149 else if (Object.keys(county)[0]) {
150 code = Object.keys(county)[0];
151 }
152 else {
153 code = '';
154 }
155 }
113 const province = this.getList('province'); 156 const province = this.getList('province');
114 const city = this.getList('city', code.slice(0, 2)); 157 const city = this.getList('city', code.slice(0, 2));
115 const picker = this.getPicker(); 158 const picker = this.getPicker();
...@@ -120,7 +163,6 @@ VantComponent({ ...@@ -120,7 +163,6 @@ VantComponent({
120 stack.push(picker.setColumnValues(0, province, false)); 163 stack.push(picker.setColumnValues(0, province, false));
121 stack.push(picker.setColumnValues(1, city, false)); 164 stack.push(picker.setColumnValues(1, city, false));
122 if (city.length && code.slice(2, 4) === '00') { 165 if (city.length && code.slice(2, 4) === '00') {
123 ;
124 [{ code }] = city; 166 [{ code }] = city;
125 } 167 }
126 stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false)); 168 stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false));
...@@ -162,8 +204,8 @@ VantComponent({ ...@@ -162,8 +204,8 @@ VantComponent({
162 } 204 }
163 return area; 205 return area;
164 }, 206 },
165 reset() { 207 reset(code) {
166 this.code = ''; 208 this.code = code || '';
167 return this.setValues(); 209 return this.setValues();
168 } 210 }
169 } 211 }
......
1 @import '../common/index.wxss';.van-badge-group{width:85px}
...\ No newline at end of file ...\ No newline at end of file
1 @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 ...\ No newline at end of file
...@@ -4,7 +4,11 @@ import { openType } from '../mixins/open-type'; ...@@ -4,7 +4,11 @@ import { openType } from '../mixins/open-type';
4 VantComponent({ 4 VantComponent({
5 mixins: [button, openType], 5 mixins: [button, openType],
6 classes: ['hover-class', 'loading-class'], 6 classes: ['hover-class', 'loading-class'],
7 data: {
8 style: ''
9 },
7 props: { 10 props: {
11 icon: String,
8 plain: Boolean, 12 plain: Boolean,
9 block: Boolean, 13 block: Boolean,
10 round: Boolean, 14 round: Boolean,
...@@ -13,6 +17,11 @@ VantComponent({ ...@@ -13,6 +17,11 @@ VantComponent({
13 hairline: Boolean, 17 hairline: Boolean,
14 disabled: Boolean, 18 disabled: Boolean,
15 loadingText: String, 19 loadingText: String,
20 customStyle: String,
21 loadingType: {
22 type: String,
23 value: 'circular'
24 },
16 type: { 25 type: {
17 type: String, 26 type: String,
18 value: 'default' 27 value: 'default'
...@@ -24,6 +33,29 @@ VantComponent({ ...@@ -24,6 +33,29 @@ VantComponent({
24 loadingSize: { 33 loadingSize: {
25 type: String, 34 type: String,
26 value: '20px' 35 value: '20px'
36 },
37 color: {
38 type: String,
39 observer(color) {
40 let style = '';
41 if (color) {
42 style += `color: ${this.data.plain ? color : 'white'};`;
43 if (!this.data.plain) {
44 // Use background instead of backgroundColor to make linear-gradient work
45 style += `background: ${color};`;
46 }
47 // hide border when color is linear-gradient
48 if (color.indexOf('gradient') !== -1) {
49 style += 'border: 0;';
50 }
51 else {
52 style += `border-color: ${color};`;
53 }
54 }
55 if (style !== this.data.style) {
56 this.setData({ style });
57 }
58 }
27 } 59 }
28 }, 60 },
29 methods: { 61 methods: {
......
1 { 1 {
2 "component": true, 2 "component": true,
3 "usingComponents": { 3 "usingComponents": {
4 "van-icon": "../icon/index",
4 "van-loading": "../loading/index" 5 "van-loading": "../loading/index"
5 } 6 }
6 } 7 }
......
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
3 <button 3 <button
4 id="{{ id }}" 4 id="{{ id }}"
5 class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}" 5 class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
6 open-type="{{ openType }}"
7 hover-class="van-button--active hover-class" 6 hover-class="van-button--active hover-class"
8 lang="{{ lang }}" 7 lang="{{ lang }}"
8 style="{{ style }} {{ customStyle }}"
9 open-type="{{ openType }}"
9 business-id="{{ businessId }}" 10 business-id="{{ businessId }}"
10 session-from="{{ sessionFrom }}" 11 session-from="{{ sessionFrom }}"
11 send-message-title="{{ sendMessageTitle }}" 12 send-message-title="{{ sendMessageTitle }}"
...@@ -26,7 +27,8 @@ ...@@ -26,7 +27,8 @@
26 <van-loading 27 <van-loading
27 custom-class="loading-class" 28 custom-class="loading-class"
28 size="{{ loadingSize }}" 29 size="{{ loadingSize }}"
29 color="{{ type === 'default' ? '#c9c9c9' : '' }}" 30 type="{{ loadingType }}"
31 color="{{ type === 'default' ? '#c9c9c9' : 'white' }}"
30 /> 32 />
31 <view 33 <view
32 wx:if="{{ loadingText }}" 34 wx:if="{{ loadingText }}"
...@@ -35,5 +37,16 @@ ...@@ -35,5 +37,16 @@
35 {{ loadingText }} 37 {{ loadingText }}
36 </view> 38 </view>
37 </block> 39 </block>
38 <slot wx:else /> 40 <block wx:else>
41 <van-icon
42 wx:if="{{ icon }}"
43 size="1.2em"
44 name="{{ icon }}"
45 class="van-button__icon"
46 custom-style="line-height: inherit;"
47 />
48 <view class="van-button__text">
49 <slot />
50 </view>
51 </block>
39 </button> 52 </button>
......
1 @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__loading-text{margin-left:5px;display:inline-block;vertical-align:middle}.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}
...\ No newline at end of file ...\ No newline at end of file
1 @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;line-height:20px;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);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-color:#fff;background-color:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:1px solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background-color:#07c160;background-color:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:1px solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background-color:#1989fa;background-color:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:1px solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background-color:#ee0a24;background-color:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:1px solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background-color:#ff976a;background-color:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:1px solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background-color:#fff;background-color: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
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
34 <view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">{{ currency }} {{ price }}</view> 34 <view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">{{ currency }} {{ price }}</view>
35 <view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view> 35 <view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
36 <view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view> 36 <view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
37 <slot name="bottom" />
37 </view> 38 </view>
38 </view> 39 </view>
39 </view> 40 </view>
......
1 @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}
...\ No newline at end of file ...\ No newline at end of file
1 @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:90px;width:var(--card-thumb-size,90px);height:90px;height:var(--card-thumb-size,90px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%}.van-card__content{position:relative;-webkit-flex:1;flex:1;min-width:0}.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:#7d7e80;color:var(--card-desc-color,#7d7e80)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24)}.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:#7d7e80;color:var(--card-origin-price-color,#7d7e80)}.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
......
1 @import '../common/index.wxss';.van-cell-group__title{font-size:14px;padding:15px 15px 5px;color:#999;line-height:16px}
...\ No newline at end of file ...\ No newline at end of file
1 @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
......
...@@ -22,6 +22,7 @@ VantComponent({ ...@@ -22,6 +22,7 @@ VantComponent({
22 titleWidth: String, 22 titleWidth: String,
23 customStyle: String, 23 customStyle: String,
24 arrowDirection: String, 24 arrowDirection: String,
25 useLabelSlot: Boolean,
25 border: { 26 border: {
26 type: Boolean, 27 type: Boolean,
27 value: true 28 value: true
......
...@@ -19,11 +19,13 @@ ...@@ -19,11 +19,13 @@
19 style="{{ titleWidth ? 'max-width:' + titleWidth + ';min-width:' + titleWidth : '' }}" 19 style="{{ titleWidth ? 'max-width:' + titleWidth + ';min-width:' + titleWidth : '' }}"
20 class="van-cell__title title-class" 20 class="van-cell__title title-class"
21 > 21 >
22 <block wx:if="{{ title }}"> 22 <block wx:if="{{ title }}">{{ title }}</block>
23 {{ title }}
24 <view wx:if="{{ label }}" class="van-cell__label label-class">{{ label }}</view>
25 </block>
26 <slot wx:else name="title" /> 23 <slot wx:else name="title" />
24
25 <view wx:if="{{ label || useLabelSlot }}" class="van-cell__label label-class">
26 <slot wx:if="{{ useLabelSlot }}" name="label" />
27 <block wx:elif="{{ label }}">{{ label }}</block>
28 </view>
27 </view> 29 </view>
28 30
29 <view class="van-cell__value value-class"> 31 <view class="van-cell__value value-class">
......
1 @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}
...\ No newline at end of file ...\ No newline at end of file
1 @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__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
......
...@@ -5,29 +5,34 @@ VantComponent({ ...@@ -5,29 +5,34 @@ VantComponent({
5 name: 'checkbox', 5 name: 'checkbox',
6 type: 'descendant', 6 type: 'descendant',
7 linked(target) { 7 linked(target) {
8 const { value, disabled } = this.data; 8 this.children = this.children || [];
9 target.set({ 9 this.children.push(target);
10 value: value.indexOf(target.data.name) !== -1, 10 this.updateChild(target);
11 disabled: disabled || target.data.disabled 11 },
12 }); 12 unlinked(target) {
13 this.children = this.children.filter((child) => child !== target);
13 } 14 }
14 }, 15 },
15 props: { 16 props: {
16 max: Number, 17 max: Number,
17 value: Array, 18 value: {
18 disabled: Boolean 19 type: Array,
20 observer: 'updateChildren'
19 }, 21 },
20 watch: { 22 disabled: {
21 value(value) { 23 type: Boolean,
22 const children = this.getRelationNodes('../checkbox/index'); 24 observer: 'updateChildren'
23 children.forEach(child => { 25 }
24 child.set({ value: value.indexOf(child.data.name) !== -1 }); 26 },
25 }); 27 methods: {
28 updateChildren() {
29 (this.children || []).forEach((child) => this.updateChild(child));
26 }, 30 },
27 disabled(disabled) { 31 updateChild(child) {
28 const children = this.getRelationNodes('../checkbox/index'); 32 const { value, disabled } = this.data;
29 children.forEach(child => { 33 child.setData({
30 child.set({ disabled: disabled || child.data.disabled }); 34 value: value.indexOf(child.data.name) !== -1,
35 disabled: disabled || child.data.disabled
31 }); 36 });
32 } 37 }
33 } 38 }
......
1 { 1 {
2 "component": true, 2 "component": true
3 "usingComponents": {
4 "van-icon": "../icon/index"
5 }
6 } 3 }
......
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { addUnit } from '../common/utils';
3 function emit(target, value) {
4 target.$emit('input', value);
5 target.$emit('change', value);
6 }
2 VantComponent({ 7 VantComponent({
3 field: true, 8 field: true,
4 relation: { 9 relation: {
5 name: 'checkbox-group', 10 name: 'checkbox-group',
6 type: 'ancestor' 11 type: 'ancestor',
12 linked(target) {
13 this.parent = target;
14 },
15 unlinked() {
16 this.parent = null;
17 }
7 }, 18 },
8 classes: ['icon-class', 'label-class'], 19 classes: ['icon-class', 'label-class'],
9 props: { 20 props: {
10 value: null, 21 value: Boolean,
11 disabled: Boolean, 22 disabled: Boolean,
12 useIconSlot: Boolean, 23 useIconSlot: Boolean,
13 checkedColor: String, 24 checkedColor: String,
...@@ -16,52 +27,61 @@ VantComponent({ ...@@ -16,52 +27,61 @@ VantComponent({
16 shape: { 27 shape: {
17 type: String, 28 type: String,
18 value: 'round' 29 value: 'round'
30 },
31 iconSize: {
32 type: null,
33 observer: 'setSizeWithUnit'
19 } 34 }
20 }, 35 },
36 data: {
37 sizeWithUnit: '20px'
38 },
21 methods: { 39 methods: {
22 emitChange(value) { 40 emitChange(value) {
23 const parent = this.getRelationNodes('../checkbox-group/index')[0]; 41 if (this.parent) {
24 if (parent) { 42 this.setParentValue(this.parent, value);
25 this.setParentValue(parent, value);
26 } 43 }
27 else { 44 else {
28 this.$emit('input', value); 45 emit(this, value);
29 this.$emit('change', value);
30 } 46 }
31 }, 47 },
32 toggle() { 48 toggle() {
33 if (!this.data.disabled) { 49 const { disabled, value } = this.data;
34 this.emitChange(!this.data.value); 50 if (!disabled) {
51 this.emitChange(!value);
35 } 52 }
36 }, 53 },
37 onClickLabel() { 54 onClickLabel() {
38 if (!this.data.disabled && !this.data.labelDisabled) { 55 const { labelDisabled, disabled, value } = this.data;
39 this.emitChange(!this.data.value); 56 if (!disabled && !labelDisabled) {
57 this.emitChange(!value);
40 } 58 }
41 }, 59 },
42 setParentValue(parent, value) { 60 setParentValue(parent, value) {
43 const parentValue = parent.data.value.slice(); 61 const parentValue = parent.data.value.slice();
44 const { name } = this.data; 62 const { name } = this.data;
63 const { max } = parent.data;
45 if (value) { 64 if (value) {
46 if (parent.data.max && parentValue.length >= parent.data.max) { 65 if (max && parentValue.length >= max) {
47 return; 66 return;
48 } 67 }
49 /* istanbul ignore else */
50 if (parentValue.indexOf(name) === -1) { 68 if (parentValue.indexOf(name) === -1) {
51 parentValue.push(name); 69 parentValue.push(name);
52 parent.$emit('input', parentValue); 70 emit(parent, parentValue);
53 parent.$emit('change', parentValue);
54 } 71 }
55 } 72 }
56 else { 73 else {
57 const index = parentValue.indexOf(name); 74 const index = parentValue.indexOf(name);
58 /* istanbul ignore else */
59 if (index !== -1) { 75 if (index !== -1) {
60 parentValue.splice(index, 1); 76 parentValue.splice(index, 1);
61 parent.$emit('input', parentValue); 77 emit(parent, parentValue);
62 parent.$emit('change', parentValue);
63 }
64 } 78 }
65 } 79 }
80 },
81 setSizeWithUnit(size) {
82 this.set({
83 sizeWithUnit: addUnit(size)
84 });
85 },
66 } 86 }
67 }); 87 });
......
...@@ -6,10 +6,11 @@ ...@@ -6,10 +6,11 @@
6 <van-icon 6 <van-icon
7 wx:else 7 wx:else
8 name="success" 8 name="success"
9 size="0.8em"
9 class="{{ utils.bem('checkbox__icon', [shape, { disabled, checked: value }]) }}" 10 class="{{ utils.bem('checkbox__icon', [shape, { disabled, checked: value }]) }}"
10 style="{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}" 11 style="font-size: {{ sizeWithUnit }};{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}"
11 custom-class="icon-class" 12 custom-class="icon-class"
12 custom-style="line-height: 20px;" 13 custom-style="line-height: 1.25em;"
13 /> 14 />
14 </view> 15 </view>
15 <view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled }]) }}" bindtap="onClickLabel"> 16 <view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled }]) }}" bindtap="onClickLabel">
......
1 @import '../common/index.wxss';.van-checkbox{overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{display:inline-block;line-height:20px;vertical-align:middle}.van-checkbox__icon{display:block;font-size:14px;width:20px;height:20px;color:transparent;text-align:center;box-sizing:border-box;border:1px solid #e5e5e5;transition:.2s}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;border-color:#1989fa;background-color:#1989fa}.van-checkbox__icon--disabled{border-color:#c9c9c9;background-color:#eee}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c9c9c9}.van-checkbox__label{color:#333;margin-left:10px}.van-checkbox__label--left{float:left;margin:0 10px 0 0}.van-checkbox__label--disabled{color:#c9c9c9}.van-checkbox__label:empty{margin:0}
...\ No newline at end of file ...\ No newline at end of file
1 @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;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 #e5e5e5;border:1px solid var(--checkbox-border-color,#e5e5e5);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
......
1 import { VantComponent } from '../common/component';
2 import { isObj } from '../common/utils';
3 import { BLUE, WHITE } from '../common/color';
4 function format(rate) {
5 return Math.min(Math.max(rate, 0), 100);
6 }
7 const PERIMETER = 2 * Math.PI;
8 const BEGIN_ANGLE = -Math.PI / 2;
9 const STEP = 1;
10 VantComponent({
11 props: {
12 text: String,
13 lineCap: {
14 type: String,
15 value: 'round'
16 },
17 value: {
18 type: Number,
19 value: 0,
20 observer: 'reRender'
21 },
22 speed: {
23 type: Number,
24 value: 50
25 },
26 size: {
27 type: Number,
28 value: 100,
29 observer: 'setStyle'
30 },
31 fill: String,
32 layerColor: {
33 type: String,
34 value: WHITE
35 },
36 color: {
37 type: [String, Object],
38 value: BLUE,
39 observer: 'setHoverColor'
40 },
41 strokeWidth: {
42 type: Number,
43 value: 4
44 },
45 clockwise: {
46 type: Boolean,
47 value: true
48 }
49 },
50 data: {
51 style: 'width: 100px; height: 100px;',
52 hoverColor: BLUE
53 },
54 methods: {
55 getContext() {
56 if (!this.ctx) {
57 this.ctx = wx.createCanvasContext('van-circle', this);
58 }
59 return this.ctx;
60 },
61 setHoverColor() {
62 const context = this.getContext();
63 const { color, size } = this.data;
64 let hoverColor = color;
65 if (isObj(color)) {
66 const LinearColor = context.createLinearGradient(size, 0, 0, 0);
67 Object.keys(color)
68 .sort((a, b) => parseFloat(a) - parseFloat(b))
69 .map(key => LinearColor.addColorStop(parseFloat(key) / 100, color[key]));
70 hoverColor = LinearColor;
71 }
72 this.setData({ hoverColor });
73 },
74 setStyle() {
75 const { size } = this.data;
76 const style = `width: ${size}px; height: ${size}px;`;
77 this.setData({ style });
78 },
79 presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
80 const { strokeWidth, lineCap, clockwise, size } = this.data;
81 const position = size / 2;
82 const radius = position - strokeWidth / 2;
83 context.setStrokeStyle(strokeStyle);
84 context.setLineWidth(strokeWidth);
85 context.setLineCap(lineCap);
86 context.beginPath();
87 context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
88 context.stroke();
89 if (fill) {
90 context.setFillStyle(fill);
91 context.fill();
92 }
93 },
94 renderLayerCircle(context) {
95 const { layerColor, fill } = this.data;
96 this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
97 },
98 renderHoverCircle(context, formatValue) {
99 const { clockwise, hoverColor } = this.data;
100 // 结束角度
101 const progress = PERIMETER * (formatValue / 100);
102 const endAngle = clockwise
103 ? BEGIN_ANGLE + progress
104 : 3 * Math.PI - (BEGIN_ANGLE + progress);
105 this.presetCanvas(context, hoverColor, BEGIN_ANGLE, endAngle);
106 },
107 drawCircle(currentValue) {
108 const context = this.getContext();
109 const { size } = this.data;
110 context.clearRect(0, 0, size, size);
111 this.renderLayerCircle(context);
112 const formatValue = format(currentValue);
113 if (formatValue !== 0) {
114 this.renderHoverCircle(context, formatValue);
115 }
116 context.draw();
117 },
118 reRender() {
119 // tofector 动画暂时没有想到好的解决方案
120 const { value, speed } = this.data;
121 if (speed <= 0 || speed > 1000) {
122 this.drawCircle(value);
123 return;
124 }
125 this.clearInterval();
126 this.currentValue = this.currentValue || 0;
127 this.interval = setInterval(() => {
128 if (this.currentValue !== value) {
129 if (this.currentValue < value) {
130 this.currentValue += STEP;
131 }
132 else {
133 this.currentValue -= STEP;
134 }
135 this.drawCircle(this.currentValue);
136 }
137 else {
138 this.clearInterval();
139 }
140 }, 1000 / speed);
141 },
142 clearInterval() {
143 if (this.interval) {
144 clearInterval(this.interval);
145 this.interval = null;
146 }
147 }
148 },
149 created() {
150 const { value } = this.data;
151 this.currentValue = value;
152 this.drawCircle(value);
153 },
154 destroyed() {
155 this.ctx = null;
156 this.clearInterval();
157 }
158 });
1 <view class="van-circle">
2 <canvas class="van-circle__canvas" style="{{ style }}" canvas-id="van-circle"></canvas>
3 <view wx:if="{{ !text }}" class="van-circle__text">
4 <slot></slot>
5 </view>
6 <cover-view wx:else class="van-circle__text">{{ text }}</cover-view>
7 </view>
...\ No newline at end of file ...\ No newline at end of file
1 @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 ...\ No newline at end of file
...@@ -16,7 +16,7 @@ VantComponent({ ...@@ -16,7 +16,7 @@ VantComponent({
16 const padding = `${gutter / 2}px`; 16 const padding = `${gutter / 2}px`;
17 const style = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : ''; 17 const style = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : '';
18 if (style !== this.data.style) { 18 if (style !== this.data.style) {
19 this.set({ style }); 19 this.setData({ style });
20 } 20 }
21 } 21 }
22 } 22 }
......
...@@ -16,6 +16,7 @@ VantComponent({ ...@@ -16,6 +16,7 @@ VantComponent({
16 icon: String, 16 icon: String,
17 label: String, 17 label: String,
18 disabled: Boolean, 18 disabled: Boolean,
19 clickable: Boolean,
19 border: { 20 border: {
20 type: Boolean, 21 type: Boolean,
21 value: true 22 value: true
...@@ -34,7 +35,11 @@ VantComponent({ ...@@ -34,7 +35,11 @@ VantComponent({
34 this.updateExpanded() 35 this.updateExpanded()
35 .then(nextTick) 36 .then(nextTick)
36 .then(() => { 37 .then(() => {
37 this.set({ transition: true }); 38 const data = { transition: true };
39 if (this.data.expanded) {
40 data.contentHeight = 'auto';
41 }
42 this.setData(data);
38 }); 43 });
39 }, 44 },
40 methods: { 45 methods: {
...@@ -66,11 +71,9 @@ VantComponent({ ...@@ -66,11 +71,9 @@ VantComponent({
66 contentHeight: height ? `${height}px` : 'auto' 71 contentHeight: height ? `${height}px` : 'auto'
67 }); 72 });
68 } 73 }
69 else {
70 return this.set({ contentHeight: `${height}px` }) 74 return this.set({ contentHeight: `${height}px` })
71 .then(nextTick) 75 .then(nextTick)
72 .then(() => this.set({ contentHeight: 0 })); 76 .then(() => this.set({ contentHeight: 0 }));
73 }
74 }); 77 });
75 }, 78 },
76 onClick() { 79 onClick() {
...@@ -84,7 +87,7 @@ VantComponent({ ...@@ -84,7 +87,7 @@ VantComponent({
84 }, 87 },
85 onTransitionEnd() { 88 onTransitionEnd() {
86 if (this.data.expanded) { 89 if (this.data.expanded) {
87 this.set({ 90 this.setData({
88 contentHeight: 'auto' 91 contentHeight: 'auto'
89 }); 92 });
90 } 93 }
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
5 title="{{ title }}" 5 title="{{ title }}"
6 title-class="title-class" 6 title-class="title-class"
7 icon="{{ icon }}" 7 icon="{{ icon }}"
8 is-link="{{ isLink }}"
9 value="{{ value }}" 8 value="{{ value }}"
10 label="{{ label }}" 9 label="{{ label }}"
10 is-link="{{ isLink }}"
11 clickable="{{ clickable }}"
11 border="{{ border && expanded }}" 12 border="{{ border && expanded }}"
12 class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}" 13 class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}"
13 right-icon-class="van-cell__right-icon" 14 right-icon-class="van-cell__right-icon"
......
1 @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}
...\ No newline at end of file ...\ No newline at end of file
1 @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
......
...@@ -5,6 +5,9 @@ VantComponent({ ...@@ -5,6 +5,9 @@ VantComponent({
5 type: 'descendant', 5 type: 'descendant',
6 linked(child) { 6 linked(child) {
7 this.children.push(child); 7 this.children.push(child);
8 },
9 unlinked(child) {
10 this.children = this.children.filter((item) => item !== child);
8 } 11 }
9 }, 12 },
10 props: { 13 props: {
......
1 export declare const RED = "#f44"; 1 export declare const RED = "#ee0a24";
2 export declare const BLUE = "#1989fa"; 2 export declare const BLUE = "#1989fa";
3 export declare const WHITE = "#fff";
3 export declare const GREEN = "#07c160"; 4 export declare const GREEN = "#07c160";
5 export declare const ORANGE = "#ff976a";
6 export declare const GRAY = "#323233";
7 export declare const GRAY_DARK = "#969799";
......
1 export const RED = '#f44'; 1 export const RED = '#ee0a24';
2 export const BLUE = '#1989fa'; 2 export const BLUE = '#1989fa';
3 export const WHITE = '#fff';
3 export const GREEN = '#07c160'; 4 export const GREEN = '#07c160';
5 export const ORANGE = '#ff976a';
6 export const GRAY = '#323233';
7 export const GRAY_DARK = '#969799';
......
1 declare function VantComponent<Data, Props, Watch, Methods, Computed>(vantOptions?: VantComponentOptions<Data, Props, Watch, Methods, Computed, CombinedComponentInstance<Data, Props, Watch, Methods, Computed>>): void; 1 import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
2 declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
2 export { VantComponent }; 3 export { VantComponent };
......
1 .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}
...\ No newline at end of file ...\ No newline at end of file
1 .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
......
1 .van-clearfix:after{content:"";display:table;clear:both}
...\ No newline at end of file ...\ No newline at end of file
1 .van-clearfix:after{display:table;clear:both;content:""}
...\ No newline at end of file ...\ No newline at end of file
......
1 .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}
...\ No newline at end of file ...\ No newline at end of file
1 .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
......
1 .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}
...\ No newline at end of file ...\ No newline at end of file
1 .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
......
1 declare function isDef(value: any): boolean; 1 /// <reference types="miniprogram-api-typings" />
2 declare function isObj(x: any): boolean; 2 export declare function isDef(value: any): boolean;
3 declare function isNumber(value: any): boolean; 3 export declare function isObj(x: any): boolean;
4 declare function range(num: number, min: number, max: number): number; 4 export declare function isNumber(value: any): boolean;
5 export { isObj, isDef, isNumber, range }; 5 export declare function range(num: number, min: number, max: number): number;
6 export declare function nextTick(fn: Function): void;
7 export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSuccessCallbackResult;
8 export declare function addUnit(value?: string | number): string | undefined;
......
1 function isDef(value) { 1 export function isDef(value) {
2 return value !== undefined && value !== null; 2 return value !== undefined && value !== null;
3 } 3 }
4 function isObj(x) { 4 export function isObj(x) {
5 const type = typeof x; 5 const type = typeof x;
6 return x !== null && (type === 'object' || type === 'function'); 6 return x !== null && (type === 'object' || type === 'function');
7 } 7 }
8 function isNumber(value) { 8 export function isNumber(value) {
9 return /^\d+$/.test(value); 9 return /^\d+(\.\d+)?$/.test(value);
10 } 10 }
11 function range(num, min, max) { 11 export function range(num, min, max) {
12 return Math.min(Math.max(num, min), max); 12 return Math.min(Math.max(num, min), max);
13 } 13 }
14 export { isObj, isDef, isNumber, range }; 14 export function nextTick(fn) {
15 setTimeout(() => {
16 fn();
17 }, 1000 / 30);
18 }
19 let systemInfo = null;
20 export function getSystemInfoSync() {
21 if (systemInfo == null) {
22 systemInfo = wx.getSystemInfoSync();
23 }
24 return systemInfo;
25 }
26 export function addUnit(value) {
27 if (!isDef(value)) {
28 return undefined;
29 }
30 value = String(value);
31 return isNumber(value) ? `${value}px` : value;
32 }
......
1 import { VantComponent } from '../common/component';
2 import { isSameSecond, parseFormat, parseTimeData } from './utils';
3 function simpleTick(fn) {
4 return setTimeout(fn, 30);
5 }
6 VantComponent({
7 props: {
8 useSlot: Boolean,
9 millisecond: Boolean,
10 time: {
11 type: Number,
12 observer: 'reset'
13 },
14 format: {
15 type: String,
16 value: 'HH:mm:ss'
17 },
18 autoStart: {
19 type: Boolean,
20 value: true
21 }
22 },
23 data: {
24 timeData: parseTimeData(0),
25 formattedTime: '0'
26 },
27 destroyed() {
28 clearTimeout(this.tid);
29 this.tid = null;
30 },
31 methods: {
32 // 开始
33 start() {
34 if (this.counting) {
35 return;
36 }
37 this.counting = true;
38 this.endTime = Date.now() + this.remain;
39 this.tick();
40 },
41 // 暂停
42 pause() {
43 this.counting = false;
44 clearTimeout(this.tid);
45 },
46 // 重置
47 reset() {
48 this.pause();
49 this.remain = this.data.time;
50 this.setRemain(this.remain);
51 if (this.data.autoStart) {
52 this.start();
53 }
54 },
55 tick() {
56 if (this.data.millisecond) {
57 this.microTick();
58 }
59 else {
60 this.macroTick();
61 }
62 },
63 microTick() {
64 this.tid = simpleTick(() => {
65 this.setRemain(this.getRemain());
66 if (this.remain !== 0) {
67 this.microTick();
68 }
69 });
70 },
71 macroTick() {
72 this.tid = simpleTick(() => {
73 const remain = this.getRemain();
74 if (!isSameSecond(remain, this.remain) || remain === 0) {
75 this.setRemain(remain);
76 }
77 if (this.remain !== 0) {
78 this.macroTick();
79 }
80 });
81 },
82 getRemain() {
83 return Math.max(this.endTime - Date.now(), 0);
84 },
85 setRemain(remain) {
86 this.remain = remain;
87 const timeData = parseTimeData(remain);
88 if (this.data.useSlot) {
89 this.$emit('change', timeData);
90 }
91 this.setData({
92 formattedTime: parseFormat(this.data.format, timeData)
93 });
94 if (remain === 0) {
95 this.pause();
96 this.$emit('finish');
97 }
98 }
99 }
100 });
1 <view class="van-count-down">
2 <slot wx:if="{{ useSlot }}"/>
3 <block wx:else>{{ formattedTime }}</block>
4 </view>
1 @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 ...\ No newline at end of file
1 export declare type TimeData = {
2 days: number;
3 hours: number;
4 minutes: number;
5 seconds: number;
6 milliseconds: number;
7 };
8 export declare function parseTimeData(time: number): TimeData;
9 export declare function parseFormat(format: string, timeData: TimeData): string;
10 export declare function isSameSecond(time1: number, time2: number): boolean;
1 function padZero(num, targetLength = 2) {
2 let str = num + '';
3 while (str.length < targetLength) {
4 str = '0' + str;
5 }
6 return str;
7 }
8 const SECOND = 1000;
9 const MINUTE = 60 * SECOND;
10 const HOUR = 60 * MINUTE;
11 const DAY = 24 * HOUR;
12 export function parseTimeData(time) {
13 const days = Math.floor(time / DAY);
14 const hours = Math.floor((time % DAY) / HOUR);
15 const minutes = Math.floor((time % HOUR) / MINUTE);
16 const seconds = Math.floor((time % MINUTE) / SECOND);
17 const milliseconds = Math.floor(time % SECOND);
18 return {
19 days,
20 hours,
21 minutes,
22 seconds,
23 milliseconds
24 };
25 }
26 export function parseFormat(format, timeData) {
27 const { days } = timeData;
28 let { hours, minutes, seconds, milliseconds } = timeData;
29 if (format.indexOf('DD') === -1) {
30 hours += days * 24;
31 }
32 else {
33 format = format.replace('DD', padZero(days));
34 }
35 if (format.indexOf('HH') === -1) {
36 minutes += hours * 60;
37 }
38 else {
39 format = format.replace('HH', padZero(hours));
40 }
41 if (format.indexOf('mm') === -1) {
42 seconds += minutes * 60;
43 }
44 else {
45 format = format.replace('mm', padZero(minutes));
46 }
47 if (format.indexOf('ss') === -1) {
48 milliseconds += seconds * 1000;
49 }
50 else {
51 format = format.replace('ss', padZero(seconds));
52 }
53 return format.replace('SSS', padZero(milliseconds, 3));
54 }
55 export function isSameSecond(time1, time2) {
56 return Math.floor(time1 / 1000) === Math.floor(time2 / 1000);
57 }
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { isDef } from '../common/utils'; 2 import { isDef } from '../common/utils';
3 import { pickerProps } from '../picker/shared';
3 const currentYear = new Date().getFullYear(); 4 const currentYear = new Date().getFullYear();
4 function isValidDate(date) { 5 function isValidDate(date) {
5 return isDef(date) && !isNaN(new Date(date).getTime()); 6 return isDef(date) && !isNaN(new Date(date).getTime());
...@@ -12,7 +13,7 @@ function padZero(val) { ...@@ -12,7 +13,7 @@ function padZero(val) {
12 } 13 }
13 function times(n, iteratee) { 14 function times(n, iteratee) {
14 let index = -1; 15 let index = -1;
15 const result = Array(n); 16 const result = Array(n < 0 ? 0 : n);
16 while (++index < n) { 17 while (++index < n) {
17 result[index] = iteratee(index); 18 result[index] = iteratee(index);
18 } 19 }
...@@ -29,100 +30,95 @@ function getTrueValue(formattedValue) { ...@@ -29,100 +30,95 @@ function getTrueValue(formattedValue) {
29 function getMonthEndDay(year, month) { 30 function getMonthEndDay(year, month) {
30 return 32 - new Date(year, month - 1, 32).getDate(); 31 return 32 - new Date(year, month - 1, 32).getDate();
31 } 32 }
33 const defaultFormatter = (_, value) => value;
32 VantComponent({ 34 VantComponent({
33 props: { 35 classes: ['active-class', 'toolbar-class', 'column-class'],
34 value: null, 36 props: Object.assign(Object.assign({}, pickerProps), { value: null, filter: null, type: {
35 title: String,
36 loading: Boolean,
37 itemHeight: {
38 type: Number,
39 value: 44
40 },
41 visibleItemCount: {
42 type: Number,
43 value: 5
44 },
45 confirmButtonText: {
46 type: String,
47 value: '确认'
48 },
49 cancelButtonText: {
50 type: String,
51 value: '取消'
52 },
53 type: {
54 type: String, 37 type: String,
55 value: 'datetime' 38 value: 'datetime'
56 }, 39 }, showToolbar: {
57 showToolbar: {
58 type: Boolean, 40 type: Boolean,
59 value: true 41 value: true
60 }, 42 }, formatter: {
61 minDate: { 43 type: null,
44 value: defaultFormatter
45 }, minDate: {
62 type: Number, 46 type: Number,
63 value: new Date(currentYear - 10, 0, 1).getTime() 47 value: new Date(currentYear - 10, 0, 1).getTime()
64 }, 48 }, maxDate: {
65 maxDate: {
66 type: Number, 49 type: Number,
67 value: new Date(currentYear + 10, 11, 31).getTime() 50 value: new Date(currentYear + 10, 11, 31).getTime()
68 }, 51 }, minHour: {
69 minHour: {
70 type: Number, 52 type: Number,
71 value: 0 53 value: 0
72 }, 54 }, maxHour: {
73 maxHour: {
74 type: Number, 55 type: Number,
75 value: 23 56 value: 23
76 }, 57 }, minMinute: {
77 minMinute: {
78 type: Number, 58 type: Number,
79 value: 0 59 value: 0
80 }, 60 }, maxMinute: {
81 maxMinute: {
82 type: Number, 61 type: Number,
83 value: 59 62 value: 59
84 } 63 } }),
85 },
86 data: { 64 data: {
87 innerValue: Date.now(), 65 innerValue: Date.now(),
88 columns: [] 66 columns: []
89 }, 67 },
90 watch: { 68 watch: {
91 value(val) { 69 value: 'updateValue',
70 type: 'updateValue',
71 minDate: 'updateValue',
72 maxDate: 'updateValue',
73 minHour: 'updateValue',
74 maxHour: 'updateValue',
75 minMinute: 'updateValue',
76 maxMinute: 'updateValue'
77 },
78 methods: {
79 updateValue() {
92 const { data } = this; 80 const { data } = this;
93 val = this.correctValue(val); 81 const val = this.correctValue(this.data.value);
94 const isEqual = val === data.innerValue; 82 const isEqual = val === data.innerValue;
95 if (!isEqual) { 83 if (!isEqual) {
96 this.updateColumnValue(val).then(() => { 84 this.updateColumnValue(val).then(() => {
97 this.$emit('input', val); 85 this.$emit('input', val);
98 }); 86 });
99 } 87 }
88 else {
89 this.updateColumns();
90 }
100 }, 91 },
101 type: 'updateColumns',
102 minHour: 'updateColumns',
103 maxHour: 'updateColumns',
104 minMinute: 'updateColumns',
105 maxMinute: 'updateColumns'
106 },
107 methods: {
108 getPicker() { 92 getPicker() {
109 if (this.picker == null) { 93 if (this.picker == null) {
110 const picker = this.picker = this.selectComponent('.van-datetime-picker'); 94 this.picker = this.selectComponent('.van-datetime-picker');
95 const { picker } = this;
111 const { setColumnValues } = picker; 96 const { setColumnValues } = picker;
112 picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]); 97 picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]);
113 } 98 }
114 return this.picker; 99 return this.picker;
115 }, 100 },
116 updateColumns() { 101 updateColumns() {
117 const results = this.getRanges().map(({ type, range }, index) => { 102 const { formatter = defaultFormatter } = this.data;
118 const values = times(range[1] - range[0] + 1, index => { 103 const results = this.getOriginColumns().map(column => ({
104 values: column.values.map(value => formatter(column.type, value))
105 }));
106 return this.set({ columns: results });
107 },
108 getOriginColumns() {
109 const { filter } = this.data;
110 const results = this.getRanges().map(({ type, range }) => {
111 let values = times(range[1] - range[0] + 1, index => {
119 let value = range[0] + index; 112 let value = range[0] + index;
120 value = type === 'year' ? `${value}` : padZero(value); 113 value = type === 'year' ? `${value}` : padZero(value);
121 return value; 114 return value;
122 }); 115 });
123 return { values }; 116 if (filter) {
117 values = filter(type, values);
118 }
119 return { type, values };
124 }); 120 });
125 return this.set({ columns: results }); 121 return results;
126 }, 122 },
127 getRanges() { 123 getRanges() {
128 const { data } = this; 124 const { data } = this;
...@@ -237,7 +233,7 @@ VantComponent({ ...@@ -237,7 +233,7 @@ VantComponent({
237 const picker = this.getPicker(); 233 const picker = this.getPicker();
238 if (data.type === 'time') { 234 if (data.type === 'time') {
239 const indexes = picker.getIndexes(); 235 const indexes = picker.getIndexes();
240 value = `${indexes[0] + data.minHour}:${indexes[1] + data.minMinute}`; 236 value = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1].values[indexes[1]]}`;
241 } 237 }
242 else { 238 else {
243 const values = picker.getValues(); 239 const values = picker.getValues();
...@@ -265,20 +261,26 @@ VantComponent({ ...@@ -265,20 +261,26 @@ VantComponent({
265 }, 261 },
266 updateColumnValue(value) { 262 updateColumnValue(value) {
267 let values = []; 263 let values = [];
268 const { data } = this; 264 const { type, formatter = defaultFormatter } = this.data;
269 const picker = this.getPicker(); 265 const picker = this.getPicker();
270 if (data.type === 'time') { 266 if (type === 'time') {
271 const pair = value.split(':'); 267 const pair = value.split(':');
272 values = [pair[0], pair[1]]; 268 values = [
269 formatter('hour', pair[0]),
270 formatter('minute', pair[1])
271 ];
273 } 272 }
274 else { 273 else {
275 const date = new Date(value); 274 const date = new Date(value);
276 values = [`${date.getFullYear()}`, padZero(date.getMonth() + 1)]; 275 values = [
277 if (data.type === 'date') { 276 formatter('year', `${date.getFullYear()}`),
278 values.push(padZero(date.getDate())); 277 formatter('month', padZero(date.getMonth() + 1))
278 ];
279 if (type === 'date') {
280 values.push(formatter('day', padZero(date.getDate())));
279 } 281 }
280 if (data.type === 'datetime') { 282 if (type === 'datetime') {
281 values.push(padZero(date.getDate()), padZero(date.getHours()), padZero(date.getMinutes())); 283 values.push(formatter('day', padZero(date.getDate())), formatter('hour', padZero(date.getHours())), formatter('minute', padZero(date.getMinutes())));
282 } 284 }
283 } 285 }
284 return this.set({ innerValue: value }) 286 return this.set({ innerValue: value })
......
1 <van-picker 1 <van-picker
2 class="van-datetime-picker" 2 class="van-datetime-picker"
3 active-class="active-class"
4 toolbar-class="toolbar-class"
5 column-class="column-class"
3 title="{{ title }}" 6 title="{{ title }}"
4 columns="{{ columns }}" 7 columns="{{ columns }}"
5 item-height="{{ itemHeight }}" 8 item-height="{{ itemHeight }}"
......
1 /// <reference types="miniprogram-api-typings" />
2 import { Weapp } from './weapp';
3 declare type RecordToAny<T> = {
4 [K in keyof T]: any;
5 };
6 export declare type CombinedComponentInstance<Data, Props, Methods> = Methods & WechatMiniprogram.Component.TrivialInstance & Weapp.FormField & {
7 data: Data & RecordToAny<Props>;
8 };
9 export interface VantComponentOptions<Data, Props, Methods, Instance> {
10 data?: Data;
11 field?: boolean;
12 classes?: string[];
13 mixins?: string[];
14 props?: Props & Weapp.PropertyOption;
15 watch?: Weapp.WatchOption<Instance>;
16 relation?: Weapp.RelationOption<Instance> & {
17 name: string;
18 };
19 relations?: {
20 [componentName: string]: Weapp.RelationOption<Instance>;
21 };
22 methods?: Methods & Weapp.MethodOption<Instance>;
23 beforeCreate?: (this: Instance) => void;
24 created?: (this: Instance) => void;
25 mounted?: (this: Instance) => void;
26 destroyed?: (this: Instance) => void;
27 }
28 export {};
1 /// <reference types="miniprogram-api-typings" />
2 export declare namespace Weapp {
3 export interface FormField {
4 data: {
5 name: string;
6 value: any;
7 };
8 }
9 interface Target {
10 id: string;
11 tagName: string;
12 dataset: {
13 [key: string]: any;
14 };
15 }
16 export interface Event {
17 /**
18 * 代表事件的类型。
19 */
20 type: string;
21 /**
22 * 页面打开到触发事件所经过的毫秒数。
23 */
24 timeStamp: number;
25 /**
26 * 触发事件的源组件。
27 */
28 target: Target;
29 /**
30 * 事件绑定的当前组件。
31 */
32 currentTarget: Target;
33 /**
34 * 额外的信息
35 */
36 detail: any;
37 }
38 interface Touch {
39 /**
40 * 触摸点的标识符
41 */
42 identifier: number;
43 /**
44 * 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
45 */
46 pageX: number;
47 /**
48 * 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
49 */
50 pageY: number;
51 /**
52 * 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
53 */
54 clientX: number;
55 /**
56 * 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
57 */
58 clientY: number;
59 }
60 export interface TouchEvent extends Event {
61 touches: Array<Touch>;
62 changedTouches: Array<Touch>;
63 }
64 /**
65 * relation定义,miniprogram-api-typings缺少this定义
66 */
67 export interface RelationOption<Instance> {
68 /** 目标组件的相对关系 */
69 type: 'parent' | 'child' | 'ancestor' | 'descendant';
70 /** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */
71 linked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
72 /** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */
73 linkChanged?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
74 /** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */
75 unlinked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
76 /** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */
77 target?: string;
78 }
79 /**
80 * obverser定义,miniprogram-api-typings缺少this定义
81 */
82 type Observer<Instance, T> = (this: Instance, newVal: T, oldVal: T, changedPath: Array<string | number>) => void;
83 /**
84 * watch定义
85 */
86 export interface WatchOption<Instance> {
87 [name: string]: string | Observer<Instance, any>;
88 }
89 /**
90 * methods定义,miniprogram-api-typings缺少this定义
91 */
92 export interface MethodOption<Instance> {
93 [name: string]: (this: Instance, ...args: any[]) => any;
94 }
95 export interface ComputedOption<Instance> {
96 [name: string]: (this: Instance) => any;
97 }
98 type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | null;
99 export interface PropertyOption {
100 [name: string]: PropertyType | PropertyType[] | {
101 /** 属性类型 */
102 type: PropertyType | PropertyType[];
103 /** 属性初始值 */
104 value?: any;
105 /** 属性值被更改时的响应函数 */
106 observer?: string | Observer<WechatMiniprogram.Component.TrivialInstance, any>;
107 /** 属性的类型(可以指定多个) */
108 optionalTypes?: PropertyType[];
109 };
110 }
111 export {};
112 }
1 /// <reference types="miniprogram-api-typings" />
1 declare type DialogAction = 'confirm' | 'cancel'; 2 declare type DialogAction = 'confirm' | 'cancel';
2 declare type DialogOptions = { 3 declare type DialogOptions = {
3 lang?: string; 4 lang?: string;
4 show?: boolean; 5 show?: boolean;
5 title?: string; 6 title?: string;
7 width?: string | number;
6 zIndex?: number; 8 zIndex?: number;
7 context?: any; 9 context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
8 message?: string; 10 message?: string;
9 overlay?: boolean; 11 overlay?: boolean;
10 selector?: string; 12 selector?: string;
11 ariaLabel?: string; 13 ariaLabel?: string;
14 className?: string;
15 customStyle?: string;
12 transition?: string; 16 transition?: string;
13 asyncClose?: boolean; 17 asyncClose?: boolean;
14 businessId?: number; 18 businessId?: number;
15 sessionFrom?: string; 19 sessionFrom?: string;
20 overlayStyle?: string;
16 appParameter?: string; 21 appParameter?: string;
17 messageAlign?: string; 22 messageAlign?: string;
18 sendMessageImg?: string; 23 sendMessageImg?: string;
......
...@@ -4,13 +4,14 @@ function getContext() { ...@@ -4,13 +4,14 @@ function getContext() {
4 return pages[pages.length - 1]; 4 return pages[pages.length - 1];
5 } 5 }
6 const Dialog = options => { 6 const Dialog = options => {
7 options = Object.assign({}, Dialog.currentOptions, options); 7 options = Object.assign(Object.assign({}, Dialog.currentOptions), options);
8 return new Promise((resolve, reject) => { 8 return new Promise((resolve, reject) => {
9 const context = options.context || getContext(); 9 const context = options.context || getContext();
10 const dialog = context.selectComponent(options.selector); 10 const dialog = context.selectComponent(options.selector);
11 delete options.context;
11 delete options.selector; 12 delete options.selector;
12 if (dialog) { 13 if (dialog) {
13 dialog.set(Object.assign({ onCancel: reject, onConfirm: resolve }, options)); 14 dialog.setData(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
14 queue.push(dialog); 15 queue.push(dialog);
15 } 16 }
16 else { 17 else {
...@@ -21,13 +22,17 @@ const Dialog = options => { ...@@ -21,13 +22,17 @@ const Dialog = options => {
21 Dialog.defaultOptions = { 22 Dialog.defaultOptions = {
22 show: true, 23 show: true,
23 title: '', 24 title: '',
25 width: null,
24 message: '', 26 message: '',
25 zIndex: 100, 27 zIndex: 100,
26 overlay: true, 28 overlay: true,
29 selector: '#van-dialog',
30 className: '',
27 asyncClose: false, 31 asyncClose: false,
28 messageAlign: '',
29 transition: 'scale', 32 transition: 'scale',
30 selector: '#van-dialog', 33 customStyle: '',
34 messageAlign: '',
35 overlayStyle: '',
31 confirmButtonText: '确认', 36 confirmButtonText: '确认',
32 cancelButtonText: '取消', 37 cancelButtonText: '取消',
33 showConfirmButton: true, 38 showConfirmButton: true,
......
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { button } from '../mixins/button'; 2 import { button } from '../mixins/button';
3 import { openType } from '../mixins/open-type'; 3 import { openType } from '../mixins/open-type';
4 import { addUnit } from '../common/utils';
5 import { GRAY, BLUE } from '../common/color';
4 VantComponent({ 6 VantComponent({
5 mixins: [button, openType], 7 mixins: [button, openType],
6 props: { 8 props: {
...@@ -8,11 +10,19 @@ VantComponent({ ...@@ -8,11 +10,19 @@ VantComponent({
8 title: String, 10 title: String,
9 message: String, 11 message: String,
10 useSlot: Boolean, 12 useSlot: Boolean,
13 className: String,
14 customStyle: String,
11 asyncClose: Boolean, 15 asyncClose: Boolean,
12 messageAlign: String, 16 messageAlign: String,
17 overlayStyle: String,
18 useTitleSlot: Boolean,
13 showCancelButton: Boolean, 19 showCancelButton: Boolean,
14 closeOnClickOverlay: Boolean, 20 closeOnClickOverlay: Boolean,
15 confirmButtonOpenType: String, 21 confirmButtonOpenType: String,
22 width: {
23 type: null,
24 observer: 'setWidthWithUnit'
25 },
16 zIndex: { 26 zIndex: {
17 type: Number, 27 type: Number,
18 value: 2000 28 value: 2000
...@@ -25,6 +35,14 @@ VantComponent({ ...@@ -25,6 +35,14 @@ VantComponent({
25 type: String, 35 type: String,
26 value: '取消' 36 value: '取消'
27 }, 37 },
38 confirmButtonColor: {
39 type: String,
40 value: BLUE
41 },
42 cancelButtonColor: {
43 type: String,
44 value: GRAY
45 },
28 showConfirmButton: { 46 showConfirmButton: {
29 type: Boolean, 47 type: Boolean,
30 value: true 48 value: true
...@@ -61,19 +79,19 @@ VantComponent({ ...@@ -61,19 +79,19 @@ VantComponent({
61 }, 79 },
62 handleAction(action) { 80 handleAction(action) {
63 if (this.data.asyncClose) { 81 if (this.data.asyncClose) {
64 this.set({ 82 this.setData({
65 [`loading.${action}`]: true 83 [`loading.${action}`]: true
66 }); 84 });
67 } 85 }
68 this.onClose(action); 86 this.onClose(action);
69 }, 87 },
70 close() { 88 close() {
71 this.set({ 89 this.setData({
72 show: false 90 show: false
73 }); 91 });
74 }, 92 },
75 stopLoading() { 93 stopLoading() {
76 this.set({ 94 this.setData({
77 loading: { 95 loading: {
78 confirm: false, 96 confirm: false,
79 cancel: false 97 cancel: false
...@@ -85,12 +103,17 @@ VantComponent({ ...@@ -85,12 +103,17 @@ VantComponent({
85 this.close(); 103 this.close();
86 } 104 }
87 this.$emit('close', action); 105 this.$emit('close', action);
88 //把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading 106 // 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
89 this.$emit(action, { dialog: this }); 107 this.$emit(action, { dialog: this });
90 const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel']; 108 const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel'];
91 if (callback) { 109 if (callback) {
92 callback(this); 110 callback(this);
93 } 111 }
112 },
113 setWidthWithUnit(val) {
114 this.setData({
115 widthWithUnit: addUnit(val)
116 });
94 } 117 }
95 } 118 }
96 }); 119 });
......
...@@ -2,16 +2,19 @@ ...@@ -2,16 +2,19 @@
2 show="{{ show }}" 2 show="{{ show }}"
3 z-index="{{ zIndex }}" 3 z-index="{{ zIndex }}"
4 overlay="{{ overlay }}" 4 overlay="{{ overlay }}"
5 custom-class="van-dialog"
6 transition="{{ transition }}" 5 transition="{{ transition }}"
6 custom-class="van-dialog {{ className }}"
7 custom-style="{{ widthWithUnit ? 'width: ' + widthWithUnit + ';' : '' }}{{ customStyle }}"
8 overlay-style="{{ overlayStyle }}"
7 close-on-click-overlay="{{ closeOnClickOverlay }}" 9 close-on-click-overlay="{{ closeOnClickOverlay }}"
8 bind:close="onClickOverlay" 10 bind:close="onClickOverlay"
9 > 11 >
10 <view 12 <view
11 wx:if="{{ title }}" 13 wx:if="{{ title || useTitleSlot }}"
12 class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}" 14 class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}"
13 > 15 >
14 {{ title }} 16 <slot wx:if="{{ useTitleSlot }}" name="title" />
17 <block wx:elif="{{ title }}"> {{ title }}</block>
15 </view> 18 </view>
16 19
17 <slot wx:if="{{ useSlot }}" /> 20 <slot wx:if="{{ useSlot }}" />
...@@ -19,7 +22,7 @@ ...@@ -19,7 +22,7 @@
19 wx:elif="{{ message }}" 22 wx:elif="{{ message }}"
20 class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}" 23 class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}"
21 > 24 >
22 <text>{{ message }}</text> 25 <text class="van-dialog__message-text">{{ message }}</text>
23 </view> 26 </view>
24 27
25 <view class="van-hairline--top van-dialog__footer"> 28 <view class="van-hairline--top van-dialog__footer">
...@@ -29,6 +32,7 @@ ...@@ -29,6 +32,7 @@
29 loading="{{ loading.cancel }}" 32 loading="{{ loading.cancel }}"
30 class="van-dialog__button van-hairline--right" 33 class="van-dialog__button van-hairline--right"
31 custom-class="van-dialog__cancel" 34 custom-class="van-dialog__cancel"
35 custom-style="color: {{ cancelButtonColor }}"
32 bind:click="onCancel" 36 bind:click="onCancel"
33 > 37 >
34 {{ cancelButtonText }} 38 {{ cancelButtonText }}
...@@ -39,6 +43,7 @@ ...@@ -39,6 +43,7 @@
39 class="van-dialog__button" 43 class="van-dialog__button"
40 loading="{{ loading.confirm }}" 44 loading="{{ loading.confirm }}"
41 custom-class="van-dialog__confirm" 45 custom-class="van-dialog__confirm"
46 custom-style="color: {{ confirmButtonColor }}"
42 47
43 open-type="{{ confirmButtonOpenType }}" 48 open-type="{{ confirmButtonOpenType }}"
44 lang="{{ lang }}" 49 lang="{{ lang }}"
......
1 @import '../common/index.wxss';.van-dialog{width:85%;overflow:hidden;font-size:16px;background-color:#fff;border-radius:4px}.van-dialog__header{padding-top:25px;font-weight:500;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:1.5;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)}
...\ No newline at end of file ...\ No newline at end of file
1 @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:#7d7e80;color:var(--dialog-has-title-message-text-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-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
......
1 import { VantComponent } from '../common/component';
2 VantComponent({
3 props: {
4 dashed: {
5 type: Boolean,
6 value: false
7 },
8 hairline: {
9 type: Boolean,
10 value: false
11 },
12 contentPosition: {
13 type: String,
14 value: ''
15 },
16 fontSize: {
17 type: Number,
18 value: ''
19 },
20 borderColor: {
21 type: String,
22 value: ''
23 },
24 textColor: {
25 type: String,
26 value: ''
27 },
28 customStyle: {
29 type: String,
30 value: ''
31 }
32 }
33 });
1 {
2 "component": true,
3 "usingComponents": {}
4 }
...\ No newline at end of file ...\ No newline at end of file
1 <wxs src="../wxs/utils.wxs" module="utils" />
2
3 <view
4 class="custom-class {{ utils.bem('divider', [{dashed, hairline}, contentPosition]) }}"
5 style="{{ borderColor ? 'border-color: ' + borderColor + ';' : '' }}{{ textColor ? 'color: ' + textColor + ';' : '' }} {{ fontSize ? 'font-size: ' + fontSize + 'px;' : '' }} {{ customStyle }}"
6 >
7 <slot />
8 </view>
1 @import '../common/index.wxss';.van-divider{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin:16px 0;margin:var(--divider-margin,16px 0);color:#969799;color:var(--divider-text-color,#969799);font-size:14px;font-size:var(--divider-font-size,14px);line-height:24px;line-height:var(--divider-line-height,24px);border:0 solid #ebedf0;border-color:var(--divider-border-color,#ebedf0)}.van-divider:after,.van-divider:before{display:block;-webkit-flex:1;flex:1;box-sizing:border-box;height:1px;border-color:inherit;border-style:inherit;border-width:1px 0 0}.van-divider:before{content:""}.van-divider--hairline:after,.van-divider--hairline:before{-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-divider--dashed{border-style:dashed}.van-divider--center:before,.van-divider--left:before,.van-divider--right:before{margin-right:16px;margin-right:var(--divider-content-padding,16px)}.van-divider--center:after,.van-divider--left:after,.van-divider--right:after{content:"";margin-left:16px;margin-left:var(--divider-content-padding,16px)}.van-divider--left:before{max-width:10%;max-width:var(--divider-content-left-width,10%)}.van-divider--right:after{max-width:10%;max-width:var(--divider-content-right-width,10%)}
...\ No newline at end of file ...\ No newline at end of file
1 import { VantComponent } from '../common/component';
2 VantComponent({
3 field: true,
4 relation: {
5 name: 'dropdown-menu',
6 type: 'ancestor',
7 linked(target) {
8 this.parent = target;
9 },
10 unlinked() {
11 this.parent = null;
12 }
13 },
14 props: {
15 value: null,
16 title: String,
17 disabled: Boolean,
18 titleClass: String,
19 options: {
20 type: Array,
21 value: []
22 }
23 },
24 data: {
25 transition: true,
26 showPopup: false,
27 showWrapper: false,
28 displayTitle: ''
29 },
30 created() {
31 this.setData({ displayTitle: this.computedDisplayTitle(this.data.value) });
32 },
33 methods: {
34 computedDisplayTitle(curValue) {
35 const { title, options } = this.data;
36 if (title) {
37 return title;
38 }
39 const match = options.filter(option => option.value === curValue);
40 const displayTitle = match.length ? match[0].text : '';
41 return displayTitle;
42 },
43 onClickOverlay() {
44 this.toggle();
45 this.$emit('close');
46 },
47 onOptionTap(event) {
48 let { value, displayTitle } = this.data;
49 const { option } = event.currentTarget.dataset;
50 const { value: optionValue } = option;
51 if (optionValue !== value) {
52 value = optionValue;
53 displayTitle = this.computedDisplayTitle(optionValue);
54 this.$emit('change', optionValue);
55 }
56 this.setData({ showPopup: false, value, displayTitle });
57 const time = this.data.duration || 0;
58 setTimeout(() => {
59 this.setData({ showWrapper: false });
60 }, time);
61 // parent 中的 itemListData 是 children 上的数据的集合
62 // 数据的更新由 children 各自维护,但是模板的更新需要额外触发 parent 的 setData
63 this.parent.setData({ itemListData: this.parent.data.itemListData });
64 },
65 toggle() {
66 const { childIndex } = this.data;
67 this.parent.toggleItem(childIndex);
68 }
69 }
70 });
1 { 1 {
2 "component": true, 2 "component": true,
3 "usingComponents": { 3 "usingComponents": {
4 "van-popup": "../popup/index",
4 "van-cell": "../cell/index", 5 "van-cell": "../cell/index",
5 "van-switch": "../switch/index" 6 "van-icon": "../icon/index"
6 } 7 }
7 } 8 }
......
1 <wxs src="../wxs/utils.wxs" module="utils" />
2
3 <view
4 wx:if="{{ showWrapper }}"
5 class="{{ utils.bem('dropdown-item', direction) }}"
6 style="{{ wrapperStyle }}"
7 >
8 <van-popup
9 show="{{ showPopup }}"
10 custom-style="position: absolute;"
11 overlay-style="position: absolute;"
12 overlay="{{ overlay }}"
13 position="{{ direction === 'down' ? 'top' : 'bottom' }}"
14 duration="{{ transition ? duration : 0 }}"
15 close-on-click-overlay="{{ closeOnClickOverlay }}"
16 bind:close="onClickOverlay"
17 >
18 <van-cell
19 wx:for="{{ options }}"
20 wx:key="{{ item.value }}"
21 data-option="{{ item }}"
22 class="{{ utils.bem('dropdown-item__option', { active: item.value === value } ) }}"
23 clickable
24 icon="{{ item.icon }}"
25 bind:tap="onOptionTap"
26 >
27 <view
28 slot="title"
29 class="van-dropdown-item__title"
30 style="{{ item.value === value ? 'color:' + activeColor : '' }}"
31 >
32 {{ item.text }}
33 </view>
34 <van-icon
35 wx:if="{{ item.value === value }}"
36 name="success"
37 class="van-dropdown-item__icon"
38 color="{{ activeColor }}"
39 />
40 </van-cell>
41
42 <slot />
43 </van-popup>
44 </view>
1 @import '../common/index.wxss';.van-dropdown-item{position:fixed;right:0;left:0;overflow:hidden}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:#1989fa;color:var(--dropdown-menu-option-active-color,#1989fa)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit}
...\ No newline at end of file ...\ No newline at end of file
1 import { VantComponent } from '../common/component';
2 import { addUnit } from '../common/utils';
3 let ARRAY = [];
4 VantComponent({
5 field: true,
6 relation: {
7 name: 'dropdown-item',
8 type: 'descendant',
9 linked(target) {
10 this.children = this.children || [];
11 // 透传 props 给 dropdown-item
12 const { overlay, duration, activeColor, closeOnClickOverlay, direction } = this.data;
13 this.updateChildData(target, {
14 overlay,
15 duration,
16 activeColor,
17 closeOnClickOverlay,
18 direction,
19 childIndex: this.children.length
20 });
21 this.children.push(target);
22 // 收集 dropdown-item 的 data 挂在 data 上
23 target &&
24 this.setData({
25 itemListData: this.data.itemListData.concat([target.data])
26 });
27 },
28 unlinked(target) {
29 this.children = this.children.filter((child) => child !== target);
30 }
31 },
32 props: {
33 activeColor: String,
34 overlay: {
35 type: Boolean,
36 value: true
37 },
38 zIndex: {
39 type: Number,
40 value: 10
41 },
42 duration: {
43 type: Number,
44 value: 200
45 },
46 direction: {
47 type: String,
48 value: 'down'
49 },
50 closeOnClickOverlay: {
51 type: Boolean,
52 value: true
53 },
54 closeOnClickOutside: {
55 type: Boolean,
56 value: true
57 }
58 },
59 data: {
60 itemListData: []
61 },
62 created() {
63 ARRAY.push(this);
64 },
65 destroyed() {
66 ARRAY = ARRAY.filter(item => item !== this);
67 },
68 methods: {
69 updateChildData(childItem, newData, needRefreshList = false) {
70 childItem.setData(newData);
71 if (needRefreshList) {
72 // dropdown-item data 更新,涉及到 title 的展示,触发模板更新
73 this.setData({ itemListData: this.data.itemListData });
74 }
75 },
76 toggleItem(active) {
77 this.children.forEach((item, index) => {
78 const { showPopup } = item.data;
79 if (index === active) {
80 this.toggleChildItem(item);
81 }
82 else if (showPopup) {
83 this.toggleChildItem(item, false, { immediate: true });
84 }
85 });
86 },
87 toggleChildItem(childItem, show, options = {}) {
88 const { showPopup, duration } = childItem.data;
89 if (show === undefined)
90 show = !showPopup;
91 if (show === showPopup) {
92 return;
93 }
94 const newChildData = { transition: !options.immediate, showPopup: show };
95 if (!show) {
96 const time = options.immediate ? 0 : duration;
97 this.updateChildData(childItem, Object.assign({}, newChildData), true);
98 setTimeout(() => {
99 this.updateChildData(childItem, { showWrapper: false }, true);
100 }, time);
101 return;
102 }
103 this.getChildWrapperStyle().then((wrapperStyle = '') => {
104 this.updateChildData(childItem, Object.assign(Object.assign({}, newChildData), { wrapperStyle, showWrapper: true }), true);
105 });
106 },
107 close() {
108 this.children.forEach((item) => {
109 this.toggleChildItem(item, false, { immediate: true });
110 });
111 },
112 getChildWrapperStyle() {
113 const { windowHeight } = wx.getSystemInfoSync();
114 const { zIndex, direction } = this.data;
115 let offset = 0;
116 return this.getRect('.van-dropdown-menu').then(rect => {
117 const { top = 0, bottom = 0 } = rect;
118 if (direction === 'down') {
119 offset = bottom;
120 }
121 else {
122 offset = windowHeight - top;
123 }
124 let wrapperStyle = `z-index: ${zIndex};`;
125 if (direction === 'down') {
126 wrapperStyle += `top: ${addUnit(offset)};`;
127 }
128 else {
129 wrapperStyle += `bottom: ${addUnit(offset)};`;
130 }
131 return Promise.resolve(wrapperStyle);
132 });
133 },
134 onTitleTap(event) {
135 // item ---> dropdown-item
136 const { item, index } = event.currentTarget.dataset;
137 if (!item.disabled) {
138 // menuItem ---> dropdown-menu
139 ARRAY.forEach(menuItem => {
140 if (menuItem && menuItem.data.closeOnClickOutside && menuItem !== this) {
141 menuItem.close();
142 }
143 });
144 this.toggleItem(index);
145 }
146 }
147 }
148 });
1 {
2 "component": true
3 }
...\ No newline at end of file ...\ No newline at end of file
1 <wxs src="../wxs/utils.wxs" module="utils" />
2
3 <view class="van-dropdown-menu van-dropdown-menu--top-bottom">
4 <view
5 wx:for="{{ itemListData }}"
6 wx:key="index"
7 data-item="{{ item }}"
8 data-index="{{ index }}"
9 class="{{ utils.bem('dropdown-menu__item', { disabled: item.disabled }) }}"
10 bind:tap="onTitleTap"
11 >
12 <view
13 class="{{ item.titleClass }} {{ utils.bem('dropdown-menu__title', { active: item.showPopup, down: item.showPopup === (direction === 'down') }) }}"
14 style="{{ item.showPopup ? 'color:' + activeColor : '' }}"
15 >
16 <view class="van-ellipsis">
17 {{item.displayTitle}}
18 </view>
19 </view>
20 </view>
21
22 <slot />
23 </view>
1 @import '../common/index.wxss';.van-dropdown-menu{display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;height:50px;height:var(--dropdown-menu-height,50px);background-color:#fff;background-color:var(--dropdown-menu-background-color,#fff)}.van-dropdown-menu__item{display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:#969799;color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{position:relative;box-sizing:border-box;max-width:100%;padding:0 8px;padding:var(--dropdown-menu-title-padding,0 8px);color:#323233;color:var(--dropdown-menu-title-text-color,#323233);font-size:15px;font-size:var(--dropdown-menu-title-font-size,15px);line-height:18px;line-height:var(--dropdown-menu-title-line-height,18px)}.van-dropdown-menu__title:after{position:absolute;top:50%;right:-4px;margin-top:-5px;border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:.8;content:""}.van-dropdown-menu__title--active{color:#1989fa;color:var(--dropdown-menu-title-active-text-color,#1989fa)}.van-dropdown-menu__title--down:after{margin-top:-1px;-webkit-transform:rotate(135deg);transform:rotate(135deg)}
...\ No newline at end of file ...\ No newline at end of file
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { getSystemInfoSync } from '../common/utils';
2 VantComponent({ 3 VantComponent({
3 field: true, 4 field: true,
4 classes: ['input-class'], 5 classes: ['input-class', 'right-icon-class'],
5 props: { 6 props: {
6 size: String, 7 size: String,
7 icon: String, 8 icon: String,
...@@ -12,27 +13,37 @@ VantComponent({ ...@@ -12,27 +13,37 @@ VantComponent({
12 center: Boolean, 13 center: Boolean,
13 isLink: Boolean, 14 isLink: Boolean,
14 leftIcon: String, 15 leftIcon: String,
16 rightIcon: String,
15 disabled: Boolean, 17 disabled: Boolean,
16 autosize: Boolean, 18 autosize: Boolean,
17 readonly: Boolean, 19 readonly: Boolean,
18 required: Boolean, 20 required: Boolean,
21 password: Boolean,
19 iconClass: String, 22 iconClass: String,
20 clearable: Boolean, 23 clearable: Boolean,
24 clickable: Boolean,
21 inputAlign: String, 25 inputAlign: String,
22 errorMessageAlign: String, 26 placeholder: String,
23 customClass: String, 27 customStyle: String,
24 confirmType: String, 28 confirmType: String,
25 confirmHold: Boolean, 29 confirmHold: Boolean,
30 holdKeyboard: Boolean,
26 errorMessage: String, 31 errorMessage: String,
27 placeholder: String, 32 arrowDirection: String,
28 customStyle: String, 33 placeholderStyle: String,
29 useIconSlot: Boolean, 34 errorMessageAlign: String,
30 useButtonSlot: Boolean, 35 selectionEnd: {
36 type: Number,
37 value: -1
38 },
39 selectionStart: {
40 type: Number,
41 value: -1
42 },
31 showConfirmBar: { 43 showConfirmBar: {
32 type: Boolean, 44 type: Boolean,
33 value: true 45 value: true
34 }, 46 },
35 placeholderStyle: String,
36 adjustPosition: { 47 adjustPosition: {
37 type: Boolean, 48 type: Boolean,
38 value: true 49 value: true
...@@ -59,63 +70,29 @@ VantComponent({ ...@@ -59,63 +70,29 @@ VantComponent({
59 } 70 }
60 }, 71 },
61 data: { 72 data: {
62 showClear: false 73 focused: false,
63 }, 74 system: getSystemInfoSync().system.split(' ').shift().toLowerCase()
64 beforeCreate() {
65 this.focused = false;
66 }, 75 },
67 methods: { 76 methods: {
68 onInput(event) { 77 onInput(event) {
69 const { value = '' } = event.detail || {}; 78 const { value = '' } = event.detail || {};
70 this.set({ 79 this.setData({ value }, () => {
71 value,
72 showClear: this.getShowClear(value)
73 }, () => {
74 this.emitChange(value); 80 this.emitChange(value);
75 }); 81 });
76 }, 82 },
77 onFocus(event) { 83 onFocus(event) {
78 const { value = '', height = 0 } = event.detail || {}; 84 this.setData({ focused: true });
79 this.$emit('focus', { value, height }); 85 this.$emit('focus', event.detail);
80 this.focused = true;
81 this.blurFromClear = false;
82 this.set({
83 showClear: this.getShowClear()
84 });
85 }, 86 },
86 onBlur(event) { 87 onBlur(event) {
87 const { value = '', cursor = 0 } = event.detail || {}; 88 this.setData({ focused: false });
88 this.$emit('blur', { value, cursor }); 89 this.$emit('blur', event.detail);
89 this.focused = false;
90 const showClear = this.getShowClear();
91 if (this.data.value === value) {
92 this.set({
93 showClear
94 });
95 }
96 else if (!this.blurFromClear) {
97 // fix: the handwritten keyboard does not trigger input change
98 this.set({
99 value,
100 showClear
101 }, () => {
102 this.emitChange(value);
103 });
104 }
105 }, 90 },
106 onClickIcon() { 91 onClickIcon() {
107 this.$emit('click-icon'); 92 this.$emit('click-icon');
108 }, 93 },
109 getShowClear(value) {
110 value = value === undefined ? this.data.value : value;
111 return (this.data.clearable && this.focused && value && !this.data.readonly);
112 },
113 onClear() { 94 onClear() {
114 this.blurFromClear = true; 95 this.setData({ value: '' }, () => {
115 this.set({
116 value: '',
117 showClear: this.getShowClear('')
118 }, () => {
119 this.emitChange(''); 96 this.emitChange('');
120 this.$emit('clear', ''); 97 this.$emit('clear', '');
121 }); 98 });
......
1 <wxs src="../wxs/utils.wxs" module="utils" /> 1 <wxs src="../wxs/utils.wxs" module="utils" />
2 2
3 <van-cell 3 <van-cell
4 size="{{ size }}"
4 icon="{{ leftIcon }}" 5 icon="{{ leftIcon }}"
5 title="{{ label }}" 6 title="{{ label }}"
6 center="{{ center }}" 7 center="{{ center }}"
7 border="{{ border }}" 8 border="{{ border }}"
8 is-link="{{ isLink }}" 9 is-link="{{ isLink }}"
9 required="{{ required }}" 10 required="{{ required }}"
10 custom-style="{{ customStyle }}" 11 clickable="{{ clickable }}"
11 title-width="{{ titleWidth }}" 12 title-width="{{ titleWidth }}"
13 custom-style="{{ customStyle }}"
14 arrow-direction="{{ arrowDirection }}"
12 custom-class="van-field" 15 custom-class="van-field"
13 size="{{ size }}"
14 > 16 >
15 <slot name="left-icon" slot="icon" /> 17 <slot name="left-icon" slot="icon" />
16 <slot name="label" slot="title" /> 18 <slot name="label" slot="title" />
17 <view class="van-field__body {{ type === 'textarea' ? 'van-field__body--textarea' : '' }}"> 19 <view class="{{ utils.bem('field__body', [type, system]) }}">
18 <textarea 20 <textarea
19 wx:if="{{ type === 'textarea' }}" 21 wx:if="{{ type === 'textarea' }}"
20 class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}" 22 class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}"
21 fixed="{{ fixed }}" 23 fixed="{{ fixed }}"
22 focus="{{ focus }}" 24 focus="{{ focus }}"
23 value="{{ value }}" 25 value="{{ value }}"
24 disabled="{{ disabled || readonly }}" 26 disabled="{{ disabled || readonly }}"
25 maxlength="{{ maxlength }}" 27 maxlength="{{ maxlength }}"
26 auto-height="{{ autosize }}"
27 placeholder="{{ placeholder }}" 28 placeholder="{{ placeholder }}"
28 placeholder-style="{{ placeholderStyle }}" 29 placeholder-style="{{ placeholderStyle }}"
29 placeholder-class="{{ error ? 'van-field__input--error' : 'van-field__placeholder' }}" 30 placeholder-class="{{ utils.bem('field__placeholder', { error }) }}"
31 auto-height="{{ autosize }}"
30 cursor-spacing="{{ cursorSpacing }}" 32 cursor-spacing="{{ cursorSpacing }}"
31 adjust-position="{{ adjustPosition }}" 33 adjust-position="{{ adjustPosition }}"
32 show-confirm-bar="{{ showConfirmBar }}" 34 show-confirm-bar="{{ showConfirmBar }}"
35 hold-keyboard="{{ holdKeyboard }}"
36 selection-end="{{ selectionEnd }}"
37 selection-start="{{ selectionStart }}"
33 bindinput="onInput" 38 bindinput="onInput"
34 bind:blur="onBlur" 39 bind:blur="onBlur"
35 bind:focus="onFocus" 40 bind:focus="onFocus"
36 bind:confirm="onConfirm" 41 bind:confirm="onConfirm"
37 /> 42 >
43 </textarea>
38 <input 44 <input
39 wx:else 45 wx:else
40 class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}" 46 class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}"
...@@ -45,34 +51,39 @@ ...@@ -45,34 +51,39 @@
45 maxlength="{{ maxlength }}" 51 maxlength="{{ maxlength }}"
46 placeholder="{{ placeholder }}" 52 placeholder="{{ placeholder }}"
47 placeholder-style="{{ placeholderStyle }}" 53 placeholder-style="{{ placeholderStyle }}"
48 placeholder-class="{{ error ? 'van-field__input--error' : 'van-field__placeholder' }}" 54 placeholder-class="{{ utils.bem('field__placeholder', { error }) }}"
49 confirm-type="{{ confirmType }}" 55 confirm-type="{{ confirmType }}"
50 confirm-hold="{{ confirmHold }}" 56 confirm-hold="{{ confirmHold }}"
57 hold-keyboard="{{ holdKeyboard }}"
51 cursor-spacing="{{ cursorSpacing }}" 58 cursor-spacing="{{ cursorSpacing }}"
52 adjust-position="{{ adjustPosition }}" 59 adjust-position="{{ adjustPosition }}"
60 selection-end="{{ selectionEnd }}"
61 selection-start="{{ selectionStart }}"
62 password="{{ password || type === 'password' }}"
53 bindinput="onInput" 63 bindinput="onInput"
54 bind:blur="onBlur" 64 bind:blur="onBlur"
55 bind:focus="onFocus" 65 bind:focus="onFocus"
56 bind:confirm="onConfirm" 66 bind:confirm="onConfirm"
57 /> 67 />
58 <van-icon 68 <van-icon
59 wx:if="{{ showClear }}" 69 wx:if="{{ clearable && focused && value && !readonly }}"
60 size="16px" 70 size="16px"
61 name="clear" 71 name="clear"
62 class="van-field__clear-root" 72 class="van-field__clear-root van-field__icon-root"
63 custom-class="van-field__clear" 73 bindtouchstart="onClear"
64 bind:touchstart="onClear"
65 /> 74 />
66 <view class="van-field__icon-container" wx:if="{{ icon || useIconSlot }}" bind:tap="onClickIcon"> 75 <view class="van-field__icon-container" bind:tap="onClickIcon">
67 <van-icon 76 <van-icon
68 wx:if="{{ icon }}" 77 wx:if="{{ rightIcon || icon }}"
69 size="16px" 78 size="16px"
70 name="{{ icon }}" 79 name="{{ rightIcon || icon }}"
71 custom-class="van-field__icon {{ iconClass }}" 80 class="van-field__icon-root {{ iconClass }}"
81 custom-class="right-icon-class"
72 /> 82 />
73 <slot wx:else name="icon" /> 83 <slot name="right-icon" />
84 <slot name="icon" />
74 </view> 85 </view>
75 <view wx:if="{{ useButtonSlot }}" class="van-field__button"> 86 <view class="van-field__button">
76 <slot name="button" /> 87 <slot name="button" />
77 </view> 88 </view>
78 </view> 89 </view>
......
1 @import '../common/index.wxss';.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{min-height:24px}.van-field__input{display:block;width:100%;height:24px;min-height:24px;padding:0;margin:0;line-height:inherit;color:#333;text-align:left;background-color:initial;border:0;box-sizing:border-box;resize:none}.van-field__input--disabled{color:#999;background-color:initial;opacity:1}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__input--error{color:#f44}.van-field__placeholder{color:#999}.van-field__clear-root{display:-webkit-flex;display:flex;height:24px;-webkit-align-items:center;align-items:center}.van-field__button,.van-field__clear,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear,.van-field__icon-container{padding:0 10px;margin-right:-10px;line-height:inherit;vertical-align:middle}.van-field__clear{color:#c9c9c9}.van-field__icon-container{color:#999}.van-field__icon{display:block!important}.van-field__button{padding-left:10px}.van-field__error-message{font-size:12px;color:#f44;text-align:left}.van-field__error--center{text-align:center}.van-field__error--right{text-align:right}
...\ No newline at end of file ...\ No newline at end of file
1 @import '../common/index.wxss';.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{line-height:1.2em;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__body--textarea.van-field__body--ios{margin-top:-4.5px}.van-field__input{position:relative;display:block;box-sizing:border-box;width:100%;margin:0;padding:0;line-height:inherit;text-align:left;background-color:initial;border:0;resize:none;color:#323233;color:var(--field-input-text-color,#323233);height:24px;height:var(--cell-line-height,24px);min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__input--textarea{height:18px;height:var(--field-text-area-min-height,18px);min-height:18px;min-height:var(--field-text-area-min-height,18px)}.van-field__input--error{color:#ee0a24;color:var(--field-input-error-text-color,#ee0a24)}.van-field__input--disabled{background-color:initial;opacity:1;color:#969799;color:var(--field-input-disabled-text-color,#969799)}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__placeholder{position:absolute;top:0;right:0;left:0;pointer-events:none;color:#969799;color:var(--field-placeholder-text-color,#969799)}.van-field__placeholder--error{color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;vertical-align:middle;padding:0 8px;padding:0 var(--padding-xs,8px);margin-right:-8px;margin-right:-var(--padding-xs,8px)}.van-field__button,.van-field__clear-root,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear-root{color:#c8c9cc;color:var(--field-clear-icon-color,#c8c9cc)}.van-field__icon-container{color:#969799;color:var(--field-icon-container-color,#969799)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:8px;padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{text-align:left;font-size:12px;font-size:var(--field-error-message-text-font-size,12px);color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -4,8 +4,16 @@ import { button } from '../mixins/button'; ...@@ -4,8 +4,16 @@ import { button } from '../mixins/button';
4 import { openType } from '../mixins/open-type'; 4 import { openType } from '../mixins/open-type';
5 VantComponent({ 5 VantComponent({
6 mixins: [link, button, openType], 6 mixins: [link, button, openType],
7 relation: {
8 type: 'ancestor',
9 name: 'goods-action',
10 linked(parent) {
11 this.parent = parent;
12 }
13 },
7 props: { 14 props: {
8 text: String, 15 text: String,
16 color: String,
9 loading: Boolean, 17 loading: Boolean,
10 disabled: Boolean, 18 disabled: Boolean,
11 type: { 19 type: {
...@@ -13,10 +21,21 @@ VantComponent({ ...@@ -13,10 +21,21 @@ VantComponent({
13 value: 'danger' 21 value: 'danger'
14 } 22 }
15 }, 23 },
24 mounted() {
25 this.updateStyle();
26 },
16 methods: { 27 methods: {
17 onClick(event) { 28 onClick(event) {
18 this.$emit('click', event.detail); 29 this.$emit('click', event.detail);
19 this.jumpLink(); 30 this.jumpLink();
31 },
32 updateStyle() {
33 const { children = [] } = this.parent;
34 const index = children.indexOf(this);
35 this.setData({
36 isFirst: index === 0,
37 isLast: index === children.length - 1
38 });
20 } 39 }
21 } 40 }
22 }); 41 });
......
1 <wxs src="../wxs/utils.wxs" module="utils" />
1 <van-button 2 <van-button
2 square 3 square
3 id="{{ id }}" 4 id="{{ id }}"
4 size="large"
5 lang="{{ lang }}" 5 lang="{{ lang }}"
6 type="{{ type }}" 6 type="{{ type }}"
7 color="{{ color }}"
7 loading="{{ loading }}" 8 loading="{{ loading }}"
8 disabled="{{ disabled }}" 9 disabled="{{ disabled }}"
9 open-type="{{ openType }}" 10 open-type="{{ openType }}"
10 custom-class="custom-class" 11 custom-class="{{ utils.bem('goods-action-button', [type, { first: isFirst, last: isLast }]) }}"
11 business-id="{{ businessId }}" 12 business-id="{{ businessId }}"
12 session-from="{{ sessionFrom }}" 13 session-from="{{ sessionFrom }}"
13 app-parameter="{{ appParameter }}" 14 app-parameter="{{ appParameter }}"
......
1 @import '../common/index.wxss';:host{-webkit-flex:1;flex:1}
...\ No newline at end of file ...\ No newline at end of file
1 @import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{border:none!important;height:40px!important;height:var(--goods-action-button-height,40px)!important;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important;line-height:40px!important;line-height:var(--goods-action-button-height,40px)!important}.van-goods-action-button--first{display:block!important;margin-left:5px;border-top-left-radius:40px/2!important;border-top-left-radius:var(--goods-action-button-height,40px)/2!important;border-bottom-left-radius:40px/2!important;border-bottom-left-radius:var(--goods-action-button-height,40px)/2!important}.van-goods-action-button--last{display:block!important;margin-right:5px;border-top-right-radius:40px/2!important;border-top-right-radius:var(--goods-action-button-height,40px)/2!important;border-bottom-right-radius:40px/2!important;border-bottom-right-radius:var(--goods-action-button-height,40px)/2!important}.van-goods-action-button--warning{background:linear-gradient(90deg,#ffd01e,#ff8917);background:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917))}.van-goods-action-button--danger{background:linear-gradient(90deg,#ff6034,#ee0a24);background:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24))}@media (max-width:321px){.van-goods-action-button{font-size:13px}}
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,6 +7,7 @@ VantComponent({ ...@@ -7,6 +7,7 @@ VantComponent({
7 mixins: [link, button, openType], 7 mixins: [link, button, openType],
8 props: { 8 props: {
9 text: String, 9 text: String,
10 dot: Boolean,
10 info: String, 11 info: String,
11 icon: String, 12 icon: String,
12 disabled: Boolean, 13 disabled: Boolean,
......
...@@ -22,14 +22,17 @@ ...@@ -22,14 +22,17 @@
22 bindgetphonenumber="bindGetPhoneNumber" 22 bindgetphonenumber="bindGetPhoneNumber"
23 bindlaunchapp="bindLaunchApp" 23 bindlaunchapp="bindLaunchApp"
24 > 24 >
25 <view class="van-goods-action-icon__content van-hairline--right"> 25 <view class="van-goods-action-icon__content">
26 <van-icon 26 <van-icon
27 wx:if="{{ icon }}"
27 size="20px" 28 size="20px"
28 name="{{ icon }}" 29 name="{{ icon }}"
30 dot="{{ dot }}"
29 info="{{ info }}" 31 info="{{ info }}"
30 class="van-goods-action-icon__icon" 32 class="van-goods-action-icon__icon"
31 custom-class="icon-class" 33 custom-class="icon-class"
32 /> 34 />
35 <slot name="icon" />
33 <text class="text-class">{{ text }}</text> 36 <text class="text-class">{{ text }}</text>
34 </view> 37 </view>
35 </van-button> 38 </van-button>
......
1 @import '../common/index.wxss';.van-goods-action-icon{width:50px!important;border:none!important}.van-goods-action-icon__content{display:-webkit-flex;display:flex;height:100%;font-size:10px;line-height:1;color:#7d7e80;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center}.van-goods-action-icon__icon{margin-bottom:4px}
...\ No newline at end of file ...\ No newline at end of file
1 @import '../common/index.wxss';.van-goods-action-icon{border:none!important;width:50px!important;width:var(--goods-action-icon-height,50px)!important}.van-goods-action-icon__content{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center;height:100%;line-height:1;font-size:10px;font-size:var(--goods-action-icon-font-size,10px);color:#7d7e80;color:var(--goods-action-icon-text-color,#7d7e80)}.van-goods-action-icon__icon{margin-bottom:4px}
...\ No newline at end of file ...\ No newline at end of file
......
1 import { VantComponent } from '../common/component'; 1 import { VantComponent } from '../common/component';
2 import { safeArea } from '../mixins/safe-area';
3 VantComponent({ 2 VantComponent({
4 mixins: [safeArea()] 3 relation: {
4 type: 'descendant',
5 name: 'goods-action-button',
6 linked(child) {
7 this.children.push(child);
8 },
9 unlinked(child) {
10 this.children = this.children.filter((item) => item !== child);
11 }
12 },
13 beforeCreate() {
14 this.children = [];
15 },
16 props: {
17 safeAreaInsetBottom: {
18 type: Boolean,
19 value: true
20 }
21 }
5 }); 22 });
......
1 <wxs src="../wxs/utils.wxs" module="utils" /> 1 <wxs src="../wxs/utils.wxs" module="utils" />
2 2
3 <view class="custom-class {{ utils.bem('goods-action', { safe: isIPhoneX && safeAreaInsetBottom }) }}"> 3 <view class="custom-class {{ utils.bem('goods-action', { safe: safeAreaInsetBottom }) }}">
4 <slot /> 4 <slot />
5 </view> 5 </view>
......