Commit e0e3e31d938af30f2d8c84c06b4f715773fb507b

Authored by 吉鹏
Exists in master

fix confix

Showing 202 changed files   Show diff stats

Too many changes.

To preserve performance only 100 of 202 files displayed.

1 <script> File was deleted
2 export default {
3 onLaunch: function() {
4 console.log('App Launch')
5 },
6 onShow: function() {
7 console.log('App Show')
8 },
9 onHide: function() {
10 console.log('App Hide')
11 }
12 }
13 </script>
14
15 <style>
16 /*每个页面公共css */
17 </style>
18 1 <script>
common/data.js
1 // 数据格式,数据中只需要包含以下字段和数据格式,可以添加字段,比如id等等,不影响组件显示, File was deleted
2 // 组件的返回结果是有菜单数组下标形式返回,
3 // 如果传入数据中有value,也会返回value,开发者可根据返回的下标获取所选中的菜单
4 /*
5 [
6 {
7 "name":"", //字符串类型 选填项 菜单名称,如不填,则取第一个子菜单的name值,filter和radio类型则将设置为"筛选"
8 "type":"" //字符串类型 必填项 可取值 hierarchy/filter/radio hierarchy单/多层级菜单(最多三级); filter筛选多选菜单; radio筛选单选菜单
9 "submenu":[ //对象数组类型 必填项 子菜单数据
10 {
11 "name":"", //字符串类型 必填项 菜单名称
12 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null,filter类型此字段无效果
13 "submenu":[ //对象数组类型 必填项 子菜单数据
14 {
15 "name":"", //字符串类型 必填项 菜单名称
16 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null
17 "submenu":[ //对象数组类型 必填项 子菜单数据 filter类型无效
18 {
19 "name":"", //字符串类型 必填项 菜单名称 hierarchy类型层级最多到此
20 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null
21 }
22 ]
23 }
24 ]
25 }
26 ]
27 }
28 ]
29 */
30
31 //0.0.4版本起 返回结果将有两部分组成:
32 /*
33 {
34 index:[], //旧版本的下标数组形式
35 value:[] //菜单中的valve,结构和下标结果数组一样,只是把下标替换成了value而已
36 }
37 */
38 // 以下演示数据中,我故意把value设置成跟name一样,只是为了方便演示,使示例更加易懂,实际使用时候value应该是一个标识,给后台识别所用的.
39 // 数据较长,请仔细查看。
40 export default [
41 {
42 "name":'综合',
43 "type": 'filter',
44 "submenu": [{
45 "submenu": [
46
47 ]
48 },
49 ],
50 },
51 {
52 name:'品牌',
53 "type": 'filter',
54 "submenu": [{
55 "name": '品牌',
56 "value": "品牌",
57 "submenu": [{
58 "name": "帕森",
59 "value": "帕森",
60 },
61 {
62 "name": "海伦凯勒",
63 "value": "海伦凯勒",
64 },
65 ]
66 },
67 ]
68 },
69 {
70 "name":'功能',
71 "type": 'filter',
72 "submenu": [{
73 "name": "智能排序",
74 "value": "智能排序"
75 },
76 {
77 "name": "离我最近",
78 "value": "离我最近"
79 },
80 {
81 "name": "人均从高到低",
82 "value": "人均从高到低"
83 },
84 {
85 "name": "人均从低到高",
86 "value": "人均从低到高"
87 }
88 ]
89 },
90 {
91 "name":'材质',
92 "type": 'filter',
93 "submenu": [{
94 "submenu": [{
95 "name": "满减活动",
96 "value": "满减活动"
97 },
98 {
99 "name": "打折优惠",
100 "value": "打折优惠"
101 },
102 {
103 "name": "会员专享",
104 "value": "会员专享"
105 }
106 ]
107 }
108 ]
109 },
110 {
111 "name":'折扣',
112 "type": 'filter',
113 "submenu": [{
114 "name": "折扣(多选)",
115 "submenu": [{
116 "name": "满减活动",
117 "value": "满减活动"
118 },
119 {
120 "name": "打折优惠",
121 "value": "打折优惠"
122 },
123 {
124 "name": "会员专享",
125 "value": "会员专享"
126 }
127 ]
128 }
129 ]
130 }
131 ]
132
133 1 // 数据格式,数据中只需要包含以下字段和数据格式,可以添加字段,比如id等等,不影响组件显示,
components/HM-filterDropdown/HM-filterDropdown.vue
1 <template> File was deleted
2 <view class="HMfilterDropdown" @touchmove.stop.prevent="discard" @tap.stop="discard">
3 <view class="nav">
4 <block v-for="(item,index) in menu" :key="index">
5 <view class="first-menu" :class="{'on':showPage==index}" @tap="togglePage(index)">
6 <text class="name">{{item.name}}</text>
7 <text class="iconfont triangle" :style="'transform:rotate('+triangleDeg[index]+'deg);'"></text>
8 </view>
9 </block>
10 </view>
11 <view class="mask" :class="{'show':isShowMask,'hide':maskVisibility!=true}" @tap="togglePage(showPage)"></view>
12 <block v-for="(page,page_index) in subData" :key="page_index">
13 <view class="sub-menu-class" :class="{'show':showPage==page_index,'hide':pageState[page_index]!=true}">
14 <block v-if="page.type=='hierarchy'&& page.submenu.length>0">
15 <scroll-view class="sub-menu-list" :class="[activeMenuArr[page_index].length>1?'first':'alone']"
16 :scroll-y="true" :scroll-into-view="'first_id'+firstScrollInto">
17 <block v-for="(sub,index) in page.submenu" :key="index">
18 <view class="sub-menu" :id="'first_id'+index" :class="{'on':activeMenuArr[page_index][0]==index}" @tap="selectHierarchyMenu(page_index,index,null,null)">
19 <view class="menu-name">
20 <text>{{sub.name}}</text>
21 <text class="iconfont selected"></text>
22 </view>
23 </view>
24 </block>
25 </scroll-view>
26 <block v-for="(sub,index) in page.submenu" :key="index">
27 <scroll-view class="sub-menu-list not-first" :scroll-y="true" v-if="activeMenuArr[page_index][0]==index&&sub.submenu.length>0"
28 :scroll-into-view="'second_id'+secondScrollInto">
29 <block v-for="(sub_second,second_index) in sub.submenu" :key="second_index">
30 <view class="sub-menu" :id="'second_id'+second_index" :class="{'on':activeMenuArr[page_index][1]==second_index}">
31 <view class="menu-name" @tap="selectHierarchyMenu(page_index,activeMenuArr[page_index][0],second_index,null)">
32 <text>{{sub_second.name}}</text>
33 <text class="iconfont selected"></text>
34 </view>
35 <view class="more-sub-menu" v-if="sub_second.submenu&&sub.submenu.length>0&&sub_second.submenu.length>0">
36 <block v-for="(sub2,sub2_index) in sub_second.submenu" :key="sub2_index">
37 <text v-if="sub_second.showAllSub || (sub2_index<8)" :class="{'on':activeMenuArr[page_index][1]==second_index&&activeMenuArr[page_index][2]==sub2_index}"
38 @tap="selectHierarchyMenu(page_index,activeMenuArr[page_index][0],second_index,sub2_index)">{{sub2.name}}</text>
39 <text v-if="sub_second.showAllSub!=true && sub2_index==8 && sub_second.submenu.length>9" @tap="showMoreSub(second_index)">更多<text
40 class="iconfont triangle"></text></text>
41 </block>
42 </view>
43 </view>
44 </block>
45 </scroll-view>
46 </block>
47 </block>
48 <block v-if="page.type=='filter'">
49 <view class="filter">
50 <scroll-view class="menu-box" :scroll-y="true">
51 <view class="box" v-for="(box,box_index) in page.submenu" :key="box_index">
52 <view class="title">{{box.name}}</view>
53 <view class="labels">
54 <view v-for="(label,label_index) in box.submenu" :key="label_index" @tap="selectFilterLabel(page_index,box_index,label_index)"
55 :class="{'on':label.selected}">{{label.name}}</view>
56 </view>
57 </view>
58 </scroll-view>
59 <view class="btn-box">
60 <view class="reset" @tap="resetFilterData(page_index)">重置</view>
61 <view class="submit" @tap="setFilterData(page_index)">确定</view>
62 </view>
63 </view>
64 </block>
65 <block v-if="page.type=='radio'">
66 <view class="filter">
67 <scroll-view class="menu-box" :scroll-y="true">
68 <view class="box" v-for="(box,box_index) in page.submenu" :key="box_index">
69 <view class="title">{{box.name}}</view>
70 <view class="labels">
71 <view v-for="(label,label_index) in box.submenu" :key="label_index" @tap="selectRadioLabel(page_index,box_index,label_index)"
72 :class="{'on':label.selected}">{{label.name}}</view>
73 </view>
74 </view>
75 </scroll-view>
76 <view class="btn-box">
77 <view class="reset" @tap="resetFilterData(page_index)">重置</view>
78 <view class="submit" @tap="setFilterData(page_index)">确定</view>
79 </view>
80 </view>
81 </block>
82 </view>
83 </block>
84 </view>
85 </template>
86 <script>
87 export default {
88 data() {
89 return {
90 subData: [], //菜单数据
91 menu: [], //顶部横条数据
92 showPage: -1, //菜单页面显示/隐藏动画控制
93 pageState: [], //页面的状态
94 activeMenuArr: [], //UI状态
95 shadowActiveMenuArr: [], //记录选中
96 defaultActive:[],
97 triangleDeg: [], //小三角形的翻转动画控制
98 isShowMask: false, //遮罩层显示/隐藏动画控制
99 maskVisibility: false, //遮罩层显示/隐藏状态
100 //滚动区域定位
101 firstScrollInto: 0,
102 secondScrollInto: 0,
103 componentTop:0 ,//组件top
104 isReadNewSelect:false
105 }
106 },
107 props: {
108 filterData: {
109 value: Array,
110 default: []
111 },
112 defaultSelected:{
113 value: Array,
114 default: []
115 },
116 updateMenuName:{
117 value: Boolean,
118 default: true
119 },
120 dataFormat:{
121 value: String,
122 default: 'Array'
123 }
124 },
125 watch: {
126 filterData: {
127 handler() {
128 this.initMenu(); //filterData重新赋值初始化菜单
129 },
130 immediate: true
131 },
132 defaultSelected(newVal) {
133 if(newVal.length==0){
134 return;
135 }
136 this.defaultActive = JSON.parse(JSON.stringify(newVal));
137 this.activeMenuArr = JSON.parse(JSON.stringify(newVal));
138 this.shadowActiveMenuArr = JSON.parse(JSON.stringify(newVal));
139 if(this.updateMenuName){
140 this.setMenuName();
141 }
142 }
143 },
144 methods: {
145 initMenu() {
146 let tmpMenuActiveArr=[];
147 let tmpMenu=[];
148 for (let i = 0; i < this.filterData.length; i++) {
149 let tmpitem = this.filterData[i];
150 tmpMenu.push({
151 //如果没有设置name,则取第一个菜单作为menu.name,filter类型则将"筛选"作为menu.name
152 name: tmpitem.name || (tmpitem.type == "filter" ? "筛选" : tmpitem.submenu[0].name),
153 type: tmpitem.type
154 });
155 //初始化选中项数组-ui状态
156 tmpMenuActiveArr.push(this.processActive(tmpitem));
157 //初始化角度数组
158 this.triangleDeg.push(0);
159 //初始化控制显示状态数组
160 this.pageState.push(false);
161 //递归处理子菜单数据
162 tmpitem = this.processSubMenu(tmpitem);
163 this.filterData[i] = tmpitem;
164 }
165 this.menu = tmpMenu;
166 //初始化选中项数组
167 tmpMenuActiveArr = this.defaultActive.length>0?this.defaultActive:this.activeMenuArr.length>0?this.activeMenuArr:tmpMenuActiveArr;
168 this.defaultActive = [];
169 this.activeMenuArr = JSON.parse(JSON.stringify(tmpMenuActiveArr));
170 this.shadowActiveMenuArr = JSON.parse(JSON.stringify(tmpMenuActiveArr));
171 //加载菜单数据
172 this.subData = this.filterData;
173 //设定顶部菜单名字
174 if(this.updateMenuName){
175 this.setMenuName();
176 }
177 },
178 setMenuName(){
179 for(var i=0;i<this.activeMenuArr.length;i++){
180 let row = this.activeMenuArr[i];
181 if (typeof(row[0]) != 'object'){
182 var tmpsub = false;
183 if(row.length>0 && row[0]!=null){
184 tmpsub = this.subData[i].submenu[row[0]];
185 if(row.length>1 && row[1]!=null){
186 tmpsub = tmpsub.submenu[row[1]];
187 if(row.length>2 && row[2]!=null){
188 tmpsub = tmpsub.submenu[row[2]];
189 }
190 }
191 }else{
192 tmpsub = false;
193 }
194 if(tmpsub){
195 this.menu[i].name = tmpsub.name;
196 }
197 }
198 }
199 },
200 //展开更多
201 showMoreSub(index) {
202 this.subData[this.showPage].submenu[this.activeMenuArr[this.showPage][0]].submenu[index].showAllSub = true;
203 this.$forceUpdate();
204 },
205 //选中
206 selectHierarchyMenu(page_index, level1_index, level2_index, level3_index) {
207 //读取记录
208 if (level1_index != null && level2_index == null && level3_index == null && this.shadowActiveMenuArr[page_index][0] ==
209 level1_index) {
210 this.activeMenuArr.splice(page_index, 1, JSON.parse(JSON.stringify(this.shadowActiveMenuArr[page_index])));
211 } else {
212 this.activeMenuArr[page_index].splice(0, 1, level1_index);
213 (level2_index!=null||this.activeMenuArr[page_index].length>=2)&&this.activeMenuArr[page_index].splice(1, 1, level2_index) || this.activeMenuArr[page_index].splice(1, 1);
214 (level3_index!=null||this.activeMenuArr[page_index].length>=3)&&this.activeMenuArr[page_index].splice(2, 1, level3_index) || this.activeMenuArr[page_index].splice(2, 1);
215 }
216 //写入结果
217 if (level3_index != null || level2_index != null || (level1_index != null && this.subData[page_index].submenu[level1_index].submenu.length == 0)
218 ) {
219 let sub = this.subData[page_index].submenu[level1_index].submenu[level2_index];
220 if(this.updateMenuName){
221 this.menu[page_index].name = (level3_index != null && sub.submenu[level3_index].name) || (level2_index != null && sub.name) || this.subData[page_index].submenu[level1_index].name;
222 }
223 this.shadowActiveMenuArr[page_index] = JSON.parse(JSON.stringify(this.activeMenuArr[page_index]));
224 this.togglePage(this.showPage);
225 }
226 },
227 //写入结果,筛选
228 setFilterData(page_index) {
229 this.shadowActiveMenuArr[page_index] = JSON.parse(JSON.stringify(this.activeMenuArr[page_index]));
230 this.togglePage(this.showPage);
231 },
232 //重置结果和ui,筛选
233 resetFilterData(page_index) {
234 let tmpArr = [];
235 let level = this.shadowActiveMenuArr[page_index].length;
236 while (level > 0) {
237 tmpArr.push([]);
238 let box = this.subData[page_index].submenu[level - 1].submenu;
239 for (let i = 0; i < box.length; i++) {
240 this.subData[page_index].submenu[level - 1].submenu[i].selected = false;
241 }
242 level--;
243 }
244 this.activeMenuArr[page_index] = JSON.parse(JSON.stringify(tmpArr));
245 this.$forceUpdate();
246 },
247 //选中筛选类label-UI状态
248 selectFilterLabel(page_index, box_index, label_index) {
249 let find_index = this.activeMenuArr[page_index][box_index].indexOf(label_index);
250 if (find_index > -1) {
251 this.activeMenuArr[page_index][box_index].splice(find_index, 1);
252 this.subData[page_index].submenu[box_index].submenu[label_index].selected = false;
253 } else {
254 this.activeMenuArr[page_index][box_index].push(label_index);
255 this.subData[page_index].submenu[box_index].submenu[label_index].selected = true;
256 }
257 this.$forceUpdate();
258 },
259 //选中单选类label-UI状态
260 selectRadioLabel(page_index, box_index, label_index) {
261
262 let activeIndex = this.activeMenuArr[page_index][box_index][0];
263 if(activeIndex == label_index){
264 this.subData[page_index].submenu[box_index].submenu[activeIndex].selected = false;
265 this.activeMenuArr[page_index][box_index][0] = null;
266 }else{
267 if(activeIndex!=null && activeIndex<this.subData[page_index].submenu[box_index].submenu.length){
268 this.subData[page_index].submenu[box_index].submenu[activeIndex].selected = false;
269 }
270
271 this.subData[page_index].submenu[box_index].submenu[label_index].selected = true;
272 this.activeMenuArr[page_index][box_index][0] = label_index;
273 }
274 this.$forceUpdate();
275 },
276 //菜单开关
277 togglePage(index) {
278 if (index == this.showPage) {
279 this.hidePageLayer(true);
280 this.hideMask();
281 this.showPage = -1;
282 } else {
283 if (this.showPage > -1) {
284 this.hidePageLayer(false);
285 }
286 this.showPageLayer(index);
287 this.showMask();
288 }
289 },
290 //hide遮罩层
291 hideMask() {
292 this.isShowMask = false;
293 setTimeout(() => {
294 this.maskVisibility = false;
295 }, 200);
296 },
297 //show遮罩层
298 showMask() {
299 this.maskVisibility = true;
300 this.$nextTick(() => {
301 setTimeout(() => {
302 this.isShowMask = true;
303 }, 0);
304 })
305 },
306 //hide菜单页
307 hidePageLayer(isAnimation) {
308 this.triangleDeg[this.showPage] = 0;
309 let tmpIndex = this.showPage;
310 if (isAnimation) {
311 setTimeout(() => {
312 this.pageState.splice(tmpIndex, 1, false);
313 }, 200);
314 this.confirm();
315 } else {
316 this.pageState.splice(tmpIndex, 1, false)
317 }
318 this.firstScrollInto = null;
319 this.secondScrollInto = null;
320 },
321 confirm() {
322 let index = JSON.parse(JSON.stringify(this.shadowActiveMenuArr));
323 let value = JSON.parse(JSON.stringify(this.shadowActiveMenuArr));
324
325 //对结果做一下处理
326 index.forEach((item, i) => {
327 if (typeof(item[0]) == 'object') {
328 //针对筛选结果过一个排序
329 item.forEach((s, j) => {
330 if(s!=null){
331 s.sort((val1, val2) => {
332 return val1 - val2;
333 });
334 item[j] = s;
335 s.forEach((v, k) => {
336 value[i][j][k] = (v==null||v>=this.subData[i].submenu[j].submenu.length)?null:this.subData[i].submenu[j].submenu[v].value;
337 if(this.subData[i].type == 'radio' && value[i][j][k] == null){
338 value[i][j] = [];
339 index[i][j] = [];
340 }
341 });
342 }
343 });
344 }else{
345 let submenu = this.subData[i].submenu[item[0]];
346 value[i][0] = submenu.value;
347 if(value[i].length>=2 && item[1]!=null){
348 if(submenu.submenu.length>0){
349 submenu = submenu.submenu[item[1]];
350 value[i][1] = submenu.hasOwnProperty('value')?submenu.value:null;
351 }else{
352 value[i][1] = null
353 }
354 if(value[i].length>=3 && item[2]!=null){
355 if(submenu.submenu.length>0){
356 submenu = submenu.submenu[item[2]];
357 value[i][2] = submenu.hasOwnProperty('value')?submenu.value:null;
358 }else{
359 value[i][2] = null;
360 }
361 }
362 }
363 }
364 index[i] = item;
365
366 });
367 // 输出
368 this.$emit('confirm', {
369 index: index,
370 value: value
371 });
372 },
373 //show菜单页
374 showPageLayer(index) {
375 this.processPage(index);
376 this.pageState.splice(index, 1, true);
377 this.$nextTick(() => {
378 setTimeout(() => {
379 this.showPage = index;
380 }, 0);
381 })
382 this.triangleDeg[index] = 180;
383 },
384 reloadActiveMenuArr(){
385 for (let i = 0; i < this.filterData.length; i++) {
386 let tmpitem = this.filterData[i];
387 let tmpArr = this.processActive(tmpitem);
388 tmpitem = this.processSubMenu(tmpitem);
389 if(this.activeMenuArr[i].length!=tmpArr.length){
390 this.filterData[i] = tmpitem;
391 this.activeMenuArr.splice(i, 1, JSON.parse(JSON.stringify(tmpArr)));
392 this.shadowActiveMenuArr.splice(i, 1, JSON.parse(JSON.stringify(tmpArr)));
393 }
394 }
395 this.subData = this.filterData;
396 this.$forceUpdate();
397 },
398 processPage(index) {
399 //check UI控制数组,结果数组,防止传入数据层级和UI控制数组不同步
400 this.reloadActiveMenuArr();
401 //重置UI控制数组
402 this.activeMenuArr.splice(index, 1, JSON.parse(JSON.stringify(this.shadowActiveMenuArr[index])));
403 if (this.menu[index].type == 'filter') {
404 //重载筛选页选中状态
405 let level = this.shadowActiveMenuArr[index].length;
406 for (let i = 0; i < level; i++) {
407 let box = this.subData[index].submenu[i].submenu;
408 for (let j = 0; j < box.length; j++) {
409 if (this.shadowActiveMenuArr[index][i].indexOf(j) > -1) {
410 this.subData[index].submenu[i].submenu[j].selected = true;
411 } else {
412 this.subData[index].submenu[i].submenu[j].selected = false;
413 }
414 }
415 }
416 } else if (this.menu[index].type == 'hierarchy') {
417 this.$nextTick(() => {
418 setTimeout(() => {
419 //滚动到选中项
420 this.firstScrollInto = parseInt(this.activeMenuArr[index][0]);
421 this.secondScrollInto = parseInt(this.activeMenuArr[index][1]);
422 }, 0);
423 })
424 } else if (this.menu[index].type == 'radio') {
425 //重载筛选页选中状态
426 let level = this.shadowActiveMenuArr[index].length;
427 for (let i = 0; i < level; i++) {
428 let box = this.subData[index].submenu[i].submenu;
429 for (let j = 0; j < box.length; j++) {
430 if (this.shadowActiveMenuArr[index][i].indexOf(j) > -1) {
431 this.subData[index].submenu[i].submenu[j].selected = true;
432 } else {
433 this.subData[index].submenu[i].submenu[j].selected = false;
434 }
435 }
436 }
437 }
438 },
439 processActive(tmpitem) {
440 let tmpArr = []
441 if (tmpitem.type == 'hierarchy'&&tmpitem.hasOwnProperty('submenu')&&tmpitem.submenu.length>0) {
442 let level = this.getMaxFloor(tmpitem.submenu);
443 while (level > 0) {
444 tmpArr.push(0);
445 level--;
446 }
447 } else if (tmpitem.type == 'filter') {
448 let level = tmpitem.submenu.length;
449 while (level > 0) {
450 tmpArr.push([]);
451 level--;
452 }
453 } else if (tmpitem.type == 'radio') {
454 let level = tmpitem.submenu.length;
455 while (level > 0) {
456 tmpArr.push([]);
457 level--;
458 }
459 }
460 return tmpArr;
461 },
462 processSubMenu(menu) {
463 if (menu.hasOwnProperty('submenu') && menu.submenu.length > 0) {
464 for (let i = 0; i < menu.submenu.length; i++) {
465 menu.submenu[i] = this.processSubMenu(menu.submenu[i]);
466 }
467 } else {
468 menu.submenu = [];
469 }
470 return menu;
471 },
472 //计算菜单层级
473 getMaxFloor(treeData) {
474 let floor = 0
475 let max = 0
476 function each(data, floor) {
477 data.forEach(e => {
478 max = floor > max ? floor : max;
479 if (e.hasOwnProperty('submenu') && e.submenu.length > 0) {
480 each(e.submenu, floor + 1)
481 }
482 })
483 }
484 each(treeData, 1)
485 return max;
486 },
487 discard() {
488
489 }
490 }
491 }
492 </script>
493 <style lang="scss">
494 .HMfilterDropdown {
495 flex-shrink: 0;
496 width: 100%;
497 height: 44px;
498 position: fixed;
499 z-index: 997;
500 flex-wrap: nowrap;
501 display: flex;
502 flex-direction: row;
503 top: var(--window-top);
504 left:0;
505 view {
506 display: flex;
507 flex-wrap: nowrap;
508 }
509 }
510 .region {
511 flex: 1;
512 height: 44px;
513 }
514 .nav {
515 width: 100%;
516 height: 44px;
517 border-bottom: solid 1rpx #eee;
518 z-index: 12;
519 background-color: #ffffff;
520 flex-direction: row;
521 .first-menu {
522 width: 100%;
523 font-size: 13px;
524 color: #757575;
525 flex-direction: row;
526 align-items: center;
527 justify-content: center;
528 transition: color .2s linear;
529
530 &.on {
531 color: #ec652b;
532
533 .iconfont {
534 color: #ec652b;
535 }
536 }
537 .name {
538 height: 20px;
539 text-align: center;
540 text-overflow: clip;
541 overflow: hidden;
542 }
543 .iconfont {
544 width: 13px;
545 height: 13px;
546 align-items: center;
547 justify-content: center;
548 transition: transform .2s linear, color .2s linear;
549 }
550 }
551 }
552 .sub-menu-class {
553 width: 100%;
554 position: absolute;
555 left: 0;
556 transform: translate3d(0, - 100%, 0);
557 max-height: 345px;
558 background-color: #ffffff;
559 z-index: 11;
560 box-shadow: 0 5px 5px rgba(0, 0, 0, .1);
561 overflow: hidden;
562 flex-direction: row;
563 transition: transform .15s linear;
564 &.hide {
565 display: none;
566 }
567
568 &.show {
569 transform: translate3d(0, calc(44px + 1rpx), 0);
570 }
571 }
572 .sub-menu-list {
573 width: 100%;
574 height: 345px;
575 flex-direction: column;
576 .sub-menu {
577 min-height: 44px;
578 font-size: 13px;
579 flex-direction: column;
580 padding-right: 15px;
581 >.menu-name {
582 height: 44px;
583 flex-direction: row;
584 align-items: center;
585 justify-content: space-between;
586 >.iconfont {
587 display: none;
588 font-size: 18px;
589 color: #ec652b;
590 }
591 }
592 }
593 &.first {
594 flex-shrink: 0;
595 width: 236rpx;
596 background-color: #f0f0f0;
597 .sub-menu {
598 padding-left: 15px;
599
600 &.on {
601 background-color: #fff;
602 }
603 }
604 }
605 &.alone {
606 max-height: 345px;
607 min-height: 170px;
608 height: auto;
609 .sub-menu {
610 min-height: calc(44px - 1rpx);
611 margin-left: 15px;
612 border-bottom: solid 1rpx #e5e5e5;
613
614 &.on {
615 color: #ec652b;
616
617 >.menu-name {
618 >.iconfont {
619 display: block;
620 }
621 }
622 }
623 }
624 }
625 &.not-first {
626 .sub-menu {
627 min-height: calc(44px - 1rpx);
628 margin-left: 15px;
629 border-bottom: solid 1rpx #e5e5e5;
630 >.menu-name {
631 height: calc(44px - 1rpx);
632 >.iconfont {
633 display: none;
634 font-size: 18px;
635 color: #ec652b;
636 }
637 }
638 &.on {
639 color: #ec652b;
640 >.menu-name {
641 >.iconfont {
642 display: block;
643 }
644 }
645 }
646 .more-sub-menu {
647 flex-direction: row;
648 flex-wrap: wrap;
649 padding-bottom: 9px;
650 >text {
651 height: 30px;
652 border-radius: 3px;
653 background-color: #f5f5f5;
654 color: #9b9b9b;
655 margin-bottom: 6px;
656 margin-right: 6px;
657 text-align: center;
658 line-height: 30px;
659 border: solid #f5f5f5 1rpx;
660 flex: 0 0 calc(33.33% - 6px);
661 overflow: hidden;
662 font-size: 12px;
663 &:nth-child(3n) {
664 margin-right: 0;
665 }
666 &.on {
667 border-color: #f6c8ac;
668 color: #ec652b;
669 }
670 .iconfont {
671 color: #9b9b9b;
672 }
673 }
674 }
675 }
676 }
677 }
678 .filter {
679 width: 100%;
680 height: 345px;
681 display: flex;
682 flex-direction: column;
683 justify-content: space-between;
684 align-items: center;
685 .menu-box {
686 width: 698rpx;
687 height: calc(345px - 75px);
688 flex-shrink: 1;
689 .box {
690 width: 100%;
691 margin-top: 16px;
692 flex-direction: column;
693 .title {
694 width: 100%;
695 font-size: 13px;
696 color: #888;
697 }
698 .labels {
699 flex-direction: row;
700 flex-wrap: wrap;
701 .on {
702 border-color: #ec652b;
703 background-color: #ec652b;
704 color: #fff;
705 }
706 >view {
707 width: 148rpx;
708 height: 30px;
709 border: solid 1rpx #adadad;
710 border-radius: 2px;
711 margin-right: 15px;
712 margin-top: 8px;
713 font-size: 12px;
714 flex-direction: row;
715 justify-content: center;
716 align-items: center;
717 &:nth-child(4n) {
718 margin-right: 0;
719 }
720 }
721 }
722 }
723 }
724 .btn-box {
725 flex-shrink: 0;
726 width: 698rpx;
727 height: 75px;
728 flex-direction: row !important;
729 align-items: center;
730 justify-content: space-between;
731 >view {
732 width: 320rpx;
733 height: 40px;
734 border-radius: 40px;
735 border: solid 1rpx #ec652b;
736 align-items: center;
737 justify-content: center;
738 }
739 .reset {
740 color: #ec652b;
741 }
742 .submit {
743 color: #fff;
744 background-color: #ec652b;
745 }
746 }
747 }
748 .mask {
749 z-index: 10;
750 position: fixed;
751 top: 0;
752 left: 0;
753 right: 0;
754 bottom: 0;
755 background-color: rgba(0, 0, 0, 0);
756 transition: background-color .15s linear;
757 &.show {
758 background-color: rgba(0, 0, 0, 0.5);
759 }
760 &.hide {
761 display: none;
762 }
763 }
764 /* 字体图标 */
765 @font-face {
766 font-family: "HM-FD-font";
767 src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALAAAsAAAAABpQAAAJzAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgp4gQIBNgIkAwwLCAAEIAWEbQc5G8sFERWMIbIfCbbzqA4hp7InSBibVsYGb4J42o82b3e/nJlHMw/NHbGOlwKJRCRpwzPtpAECCOZubdqxjYpQLMlVg+70/08edrgQOtx2ukpVyApZn+dyehPoQObHo3O85rYx9vOjXoBxQIHugW2yIkqIW2QXcScu4jwE8CSWbKSmrqUHFwOaJoCsLM5P4haSGIxRcRHshrUGucLCVcfqI3AZfV/+USguKCwNmtsxVztDxU/n55C+3W0Z4QQpEOTNFqCBbMCAjDUWB9CIwWk87aa70cYgqLkyd3dEmm+18R8eKATEBrV7A5CulBT8dKiWOYZk412XNcDdKSEKSGODnyKIDl+dmVt9/Dx4pu/xyeutkMlHISGPTsPCnoTNP9nOT6wTtDdlO6dPr47efvj942lkYuQzrhMKEjq9N6y98P3340gmlJ/RStUD6F31CAEEPtUW94/7rf+7XgaAz57X0ZHXAGsFFwVgw38yALuMb0IBbVyNamFYEw4oKMDTj3AHRQP5Pt4dci9VwSVkRNQh5r7CLskZadhsWHhRDBsXczk8ZYk3ewnCxmQeQKa3BOHvA8XXO2j+vqRhf7CE+sPmn4anvoL29JLa4qqaUQkmoK+QG2osCckq7txi2leK86aIPyJ3eQZ8xytXYmyQ51jQndJAxIJlqiGSLsOqImiZCjTiZCJt6Lq26U2OoXqwUo0hRaAE0K5AziANy/uLVeXzWyjVqyjcoeupjxDr5MMDn8MDkLG9Aenu5ZrOSSoghAUsRmogkkahSoWAtnlUARnCkY3It0Iu7mWhdmd9Z/19BwBP6GidEi0G56opckXTGZVSPxgAAAA=');
768 }
769 .iconfont {
770 font-family: "HM-FD-font" !important;
771 font-size: 13px;
772 font-style: normal;
773 color: #757575;
774 &.triangle {
775 &:before {
776 content: "\e65a";
777 }
778 }
779 &.selected {
780 &:before {
781 content: "\e607";
782 }
783 }
784 }
785 </style>
786 1 <template>
components/card.vue
1 <template> File was deleted
2 <view>
3
4 </view>
5 </template>
6
7 <script>
8 export default {
9 data() {
10 return {
11
12 };
13 }
14 }
15 </script>
16
17 <style lang="scss">
18
19 </style>
20 1 <template>
components/uni-drawer/uni-drawer.vue
1 <template> File was deleted
2 <view v-if="visibleSync" :class="{ 'uni-drawer--visible': showDrawer }" class="uni-drawer" @touchmove.stop.prevent="clear">
3 <view class="uni-drawer__mask" :class="{ 'uni-drawer__mask--visible': showDrawer && mask }" @tap="close('mask')" />
4 <view class="uni-drawer__content" :class="{'uni-drawer--right': rightMode,'uni-drawer--left': !rightMode, 'uni-drawer__content--visible': showDrawer}" :style="{width:drawerWidth+'px'}">
5 <slot />
6 </view>
7 </view>
8 </template>
9
10 <script>
11 /**
12 * Drawer 抽屉
13 * @description 抽屉侧滑菜单
14 * @tutorial https://ext.dcloud.net.cn/plugin?id=26
15 * @property {Boolean} mask = [true | false] 是否显示遮罩
16 * @property {Boolean} maskClick = [true | false] 点击遮罩是否关闭
17 * @property {Boolean} mode = [left | right] Drawer 滑出位置
18 * @value left 从左侧滑出
19 * @value right 从右侧侧滑出
20 * @property {Number} width 抽屉的宽度 ,仅 vue 页面生效
21 * @event {Function} close 组件关闭时触发事件
22 */
23 export default {
24 name: 'UniDrawer',
25 props: {
26 /**
27 * 显示模式(左、右),只在初始化生效
28 */
29 mode: {
30 type: String,
31 default: ''
32 },
33 /**
34 * 蒙层显示状态
35 */
36 mask: {
37 type: Boolean,
38 default: true
39 },
40 /**
41 * 遮罩是否可点击关闭
42 */
43 maskClick:{
44 type: Boolean,
45 default: true
46 },
47 /**
48 * 抽屉宽度
49 */
50 width: {
51 type: Number,
52 default: 220
53 }
54 },
55 data() {
56 return {
57 visibleSync: false,
58 showDrawer: false,
59 rightMode: false,
60 watchTimer: null,
61 drawerWidth: 220
62 }
63 },
64 created() {
65 // #ifndef APP-NVUE
66 this.drawerWidth = this.width
67 // #endif
68 this.rightMode = this.mode === 'right'
69 },
70 methods: {
71 clear(){},
72 close(type) {
73 // fixed by mehaotian 抽屉尚未完全关闭或遮罩禁止点击时不触发以下逻辑
74 if((type === 'mask' && !this.maskClick) || !this.visibleSync) return
75 this._change('showDrawer', 'visibleSync', false)
76 },
77 open() {
78 // fixed by mehaotian 处理重复点击打开的事件
79 if(this.visibleSync) return
80 this._change('visibleSync', 'showDrawer', true)
81 },
82 _change(param1, param2, status) {
83 this[param1] = status
84 if (this.watchTimer) {
85 clearTimeout(this.watchTimer)
86 }
87 this.watchTimer = setTimeout(() => {
88 this[param2] = status
89 this.$emit('change',status)
90 }, status ? 50 : 300)
91 }
92 }
93 }
94 </script>
95
96 <style lang="scss" scoped>
97 // 抽屉宽度
98 $drawer-width: 220px;
99
100 .uni-drawer {
101 /* #ifndef APP-NVUE */
102 display: block;
103 /* #endif */
104 position: fixed;
105 top: 0;
106 left: 0;
107 right: 0;
108 bottom: 0;
109 overflow: hidden;
110 z-index: 999;
111 }
112
113 .uni-drawer__content {
114 /* #ifndef APP-NVUE */
115 display: block;
116 /* #endif */
117 position: absolute;
118 top: 0;
119 width: $drawer-width;
120 bottom: 0;
121 background-color: $uni-bg-color;
122 transition: transform 0.3s ease;
123 }
124
125 .uni-drawer--left {
126 left: 0;
127 /* #ifdef APP-NVUE */
128 transform: translateX(-$drawer-width);
129 /* #endif */
130 /* #ifndef APP-NVUE */
131 transform: translateX(-100%);
132 /* #endif */
133 }
134
135 .uni-drawer--right {
136 right: 0;
137 /* #ifdef APP-NVUE */
138 transform: translateX($drawer-width);
139 /* #endif */
140 /* #ifndef APP-NVUE */
141 transform: translateX(100%);
142 /* #endif */
143 }
144
145 .uni-drawer__content--visible {
146 transform: translateX(0px);
147 }
148
149
150 .uni-drawer__mask {
151 /* #ifndef APP-NVUE */
152 display: block;
153 /* #endif */
154 opacity: 0;
155 position: absolute;
156 top: 0;
157 left: 0;
158 bottom: 0;
159 right: 0;
160 background-color: $uni-bg-color-mask;
161 transition: opacity 0.3s;
162 }
163
164 .uni-drawer__mask--visible {
165 /* #ifndef APP-NVUE */
166 display: block;
167 /* #endif */
168 opacity: 1;
169 }
170 </style>
171 1 <template>
1 import Vue from 'vue' File was deleted
2 import App from './App'
3
4 Vue.config.productionTip = false
5
6 App.mpType = 'app'
7
8 const app = new Vue({
9 ...App
10 })
11 app.$mount()
12 1 import Vue from 'vue'
manifest.json
1 { File was deleted
2 "name" : "gulu-vue",
3 "appid" : "",
4 "description" : "",
5 "versionName" : "1.0.0",
6 "versionCode" : "100",
7 "transformPx" : false,
8 /* 5+App特有相关 */
9 "app-plus" : {
10 "usingComponents" : true,
11 "nvueCompiler" : "uni-app",
12 "compilerVersion" : 3,
13 "splashscreen" : {
14 "alwaysShowBeforeRender" : true,
15 "waiting" : true,
16 "autoclose" : true,
17 "delay" : 0
18 },
19 /* 模块配置 */
20 "modules" : {},
21 /* 应用发布信息 */
22 "distribute" : {
23 /* android打包配置 */
24 "android" : {
25 "permissions" : [
26 "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
27 "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
28 "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
29 "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
30 "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
31 "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
32 "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
33 "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
34 "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
35 "<uses-permission android:name=\"android.permission.CAMERA\"/>",
36 "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
37 "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
38 "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
39 "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
40 "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
41 "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
42 "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
43 "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
44 "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
45 "<uses-feature android:name=\"android.hardware.camera\"/>",
46 "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
47 "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
48 ]
49 },
50 /* ios打包配置 */
51 "ios" : {},
52 /* SDK配置 */
53 "sdkConfigs" : {}
54 }
55 },
56 /* 快应用特有相关 */
57 "quickapp" : {},
58 /* 小程序特有相关 */
59 "mp-weixin" : {
60 "appid" : "",
61 "setting" : {
62 "urlCheck" : false
63 },
64 "usingComponents" : true
65 },
66 "mp-alipay" : {
67 "usingComponents" : true
68 },
69 "mp-baidu" : {
70 "usingComponents" : true
71 },
72 "mp-toutiao" : {
73 "usingComponents" : true
74 }
75 }
76 1 {
File was created 1 {
2 "name": "gulu-vue",
3 "version": "0.1.0",
4 "private": true,
5 "scripts": {
6 "serve": "npm run dev:h5",
7 "build": "npm run build:h5",
8 "build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
9 "build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
10 "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
11 "build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
12 "build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
13 "build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
14 "build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
15 "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
16 "build:quickapp-light": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-light vue-cli-service uni-build",
17 "build:quickapp-vue": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-vue vue-cli-service uni-build",
18 "dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
19 "dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
20 "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
21 "dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
22 "dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
23 "dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
24 "dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
25 "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
26 "dev:quickapp-light": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-light vue-cli-service uni-build --watch",
27 "dev:quickapp-vue": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-vue vue-cli-service uni-build --watch",
28 "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
29 "serve:quickapp-vue": "node node_modules/@dcloudio/uni-quickapp-vue/bin/serve.js"
30 },
31 "dependencies": {
32 "@dcloudio/uni-app-plus": "^2.0.0-26920200424005",
33 "@dcloudio/uni-h5": "^2.0.0-26920200424005",
34 "@dcloudio/uni-helper-json": "^1.0.5",
35 "@dcloudio/uni-mp-alipay": "^2.0.0-26920200424005",
36 "@dcloudio/uni-mp-baidu": "^2.0.0-26920200424005",
37 "@dcloudio/uni-mp-qq": "^2.0.0-26920200424005",
38 "@dcloudio/uni-mp-toutiao": "^2.0.0-26920200424005",
39 "@dcloudio/uni-mp-weixin": "^2.0.0-26920200424005",
40 "@dcloudio/uni-quickapp-light": "^2.0.0-26920200424005",
41 "@dcloudio/uni-quickapp-vue": "^2.0.0-26920200424005",
42 "@dcloudio/uni-stat": "^2.0.0-26920200424005",
43 "core-js": "^3.6.5",
44 "flyio": "^0.6.2",
45 "node-sass": "^4.14.0",
46 "regenerator-runtime": "^0.12.1",
47 "sass-loader": "^8.0.2",
48 "vue": "^2.6.11",
49 "vuex": "^3.0.1"
50 },
51 "devDependencies": {
52 "@dcloudio/uni-cli-shared": "^2.0.0-26920200424005",
53 "@dcloudio/uni-migration": "^2.0.0-26920200424005",
54 "@dcloudio/uni-template-compiler": "^2.0.0-26920200424005",
55 "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-26920200424005",
56 "@dcloudio/vue-cli-plugin-uni": "^2.0.0-26920200424005",
57 "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-26920200424005",
58 "@dcloudio/webpack-uni-mp-loader": "^2.0.0-26920200424005",
59 "@dcloudio/webpack-uni-pages-loader": "^2.0.0-26920200424005",
60 "@types/html5plus": "*",
61 "@types/uni-app": "*",
62 "@vue/cli-plugin-babel": "~4.3.0",
63 "@vue/cli-service": "~4.3.0",
64 "babel-plugin-import": "^1.11.0",
65 "cross-env": "^7.0.2",
66 "mini-types": "*",
67 "miniprogram-api-typings": "^2.8.0-2",
68 "postcss-comment": "^2.0.0",
69 "vue-template-compiler": "^2.6.11"
70 },
71 "browserslist": [
72 "Android >= 4",
73 "ios >= 8"
74 ],
75 "uni-app": {
76 "scripts": {}
77 }
78 }
1 { 79
pages.json
1 { File was deleted
2 "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
3 {
4 "path": "pages/index/index",
5 "style": {
6 "navigationBarTitleText": "商城一览"
7 }
8 },
9 {
10 "path": "pages/cart/cart",
11 "style": {
12 "navigationBarTitleText": "购物车"
13 }
14 },
15 {
16 "path": "pages/user/user",
17 "style": {
18 "navigationBarTitleText": "我的"
19 }
20 }
21 ],
22 "globalStyle": {
23 "navigationBarTextStyle": "black",
24 "navigationBarTitleText": "uni-app",
25 "navigationBarBackgroundColor": "#F8F8F8",
26 "backgroundColor": "#F8F8F8"
27 },
28 "tabBar": {
29 "color": "#C0C4CC",
30 "selectedColor": "#fa436a",
31 "borderStyle": "black",
32 "backgroundColor": "#ffffff",
33 "list": [{
34 "pagePath": "pages/index/index",
35 "iconPath": "static/tab-home.png",
36 "selectedIconPath": "static/tab-home-current.png",
37 "text": "首页"
38 },
39 {
40 "pagePath": "pages/cart/cart",
41 "iconPath": "static/tab-cart.png",
42 "selectedIconPath": "static/tab-cart-current.png",
43 "text": "购物车"
44 },
45 {
46 "pagePath": "pages/user/user",
47 "iconPath": "static/tab-my.png",
48 "selectedIconPath": "static/tab-my-current.png",
49 "text": "我的"
50 }
51 ]
52 }
53 }
54 1 {
pages/cart/cart.vue
1 <template> File was deleted
2 <view class="content">
3 <image class="logo" src="/static/logo.png"></image>
4 <view class="text-area">
5 <text class="title">{{title}}</text>
6 </view>
7 </view>
8 </template>
9
10 <script>
11 export default {
12 data() {
13 return {
14 title: 'Hello'
15 }
16 },
17 onLoad() {
18
19 },
20 methods: {
21
22 }
23 }
24 </script>
25
26 <style>
27 .content {
28 display: flex;
29 flex-direction: column;
30 align-items: center;
31 justify-content: center;
32 }
33
34 .logo {
35 height: 200rpx;
36 width: 200rpx;
37 margin-top: 200rpx;
38 margin-left: auto;
39 margin-right: auto;
40 margin-bottom: 50rpx;
41 }
42
43 .text-area {
44 display: flex;
45 justify-content: center;
46 }
47
48 .title {
49 font-size: 36rpx;
50 color: #8f8f94;
51 }
52 </style>
53 1 <template>
pages/index/index.vue
1 <template> File was deleted
2 <view class="content">
3 <view class="header">
4 <!-- 搜索-->
5 <view class="searchBar">
6 <icon class="searchIcon" type="search" size="14"></icon>
7 <input class="searchIpt" placeholder="老花镜" confirm-type="search"/>
8 </view>
9
10 <!-- 筛选栏-->
11 <view class="screenBar">
12 <view v-for="item in screenItems" :key="item.current" @click="onClickItem(item.current)" >
13 <view class="screenItem" v-bind:class="{ active: current === item.current }" v-if="item.current === 2" @click="dropDown">
14 {{ item.text }}<icon type="info" size="14"></icon>
15 </view>
16 <view class="screenItem" v-bind:class="{ active: current === item.current }" v-if="item.current === 4" @click="showDrawer('showRight')">
17 {{ item.text }}<icon type="info" size="14"></icon>
18 </view>
19 <view v-if="item.current !== 2&&item.current!==4">
20 <view class="screenItem" v-bind:class="{ active: current === item.current }">{{ item.text }}</view>
21 </view>
22 </view>
23 </view>
24 </view>
25 <uni-drawer ref="showRight" mask="true" maskClick=true mode="right" :width="320" @change="change($event,'showRight')">
26 <view class="close">
27 <view @click="closeDrawer('showRight')"><text class="word-btn-white">关闭</text></view>
28 </view>
29 </uni-drawer>
30
31
32
33 <!-- 筛选菜单-->
34 <view class="content-wrap">
35 <view>
36 <HMfilterDropdown :filterData="filterData" :defaultSelected ="filterDropdownValue" :updateMenuName="true" @confirm="confirm" dataFormat="Object"></HMfilterDropdown>
37 <!-- 占位 -->
38 <view class="place"></view>
39 <!-- 商品列表 -->
40 <view class="goods-list">
41 <view class="product-list">
42 <view class="product" v-for="(goods) in goodsList" :key="goods.goods_id" @tap="toGoods(goods)">
43 <image mode="widthFix" :src="goods.img"></image>
44 <view class="name">{{goods.name}}</view>
45 <view class="info">
46 <view class="price">{{goods.price}}</view>
47 <view class="slogan">{{goods.slogan}}</view>
48 </view>
49 </view>
50 </view>
51 <view class="loading-text">{{loadingText}}</view>
52 </view>
53
54 </view>
55 </view>
56 </view>
57 </template>
58
59 <script>
60 import uniDrawer from "@/components/uni-drawer/uni-drawer.vue";
61 import HMfilterDropdown from "../../components/HM-filterDropdown/HM-filterDropdown.vue";
62 import data from '@/common/data.js';//筛选菜单数据
63 export default {
64 components: {
65 uniDrawer,
66 'HMfilterDropdown':HMfilterDropdown
67 },
68 data() {
69 return {
70 screenItems: [
71 {current:0,text:'全部',hasIcon:false},
72 {current:1,text:'销量',hasIcon:false},
73 {current:2,text:'价格',hasIcon:true},
74 {current:3,text:'折扣',hasIcon:false},
75 {current:4,text:'筛选',hasIcon:true},
76 ],
77 current: 0,
78 showRight: false,
79 indexArr:'',
80 valueArr:'',
81 //商品数据
82 goodsList:[
83 { goods_id: 0, img: '/static/img/goods/p1.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
84 { goods_id: 1, img: '/static/img/goods/p2.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
85 { goods_id: 2, img: '/static/img/goods/p3.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
86 { goods_id: 3, img: '/static/img/goods/p4.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
87 { goods_id: 4, img: '/static/img/goods/p5.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
88 { goods_id: 5, img: '/static/img/goods/p6.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
89 { goods_id: 6, img: '/static/img/goods/p7.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
90 { goods_id: 7, img: '/static/img/goods/p8.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
91 { goods_id: 8, img: '/static/img/goods/p9.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
92 { goods_id: 9, img: '/static/img/goods/p10.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' }
93 ],
94 loadingText:"正在加载...",
95 filterDropdownValue:[],
96 filterData:[]
97 }
98 },
99 filters: {
100   outData(value) {
101     return JSON.stringify(value);
102   }
103 },
104 onLoad: function () {
105 //定时器模拟ajax异步请求数据
106 setTimeout(()=>{
107 //传入defaultSelected的结构不能错,错了就报错运行异常。 不选中的项目传入null
108 this.filterDropdownValue = [
109 [1,1,0], //第0个菜单选中 一级菜单的第1项,二级菜单的第1项,三级菜单的第3项
110 [null,null], //第1个菜单选中 都不选中
111 [1], //第2个菜单选中 一级菜单的第1项
112 [[0],[1,2,7],[1,0]], //筛选菜单选中 第一个筛选的第0项,第二个筛选的第1,2,7项,第三个筛选的第1,0项
113 [[0],[1],[1]], //单选菜单选中 第一个筛选的第0项,第二个筛选的第1项,第三个筛选的第1项
114 ];
115 this.filterData = data;
116 },100);
117 //模拟ajax请求子菜单数据。
118 // setTimeout(()=>{
119 //this.filterData[1].submenu[0].submenu = [{"name": "附近","value": "附近"},{"name": "1km","value": "1km"},{"name": "2km","value": "2km"},{"name": "3km","value": "3km"},{"name": "4km","value": "4km"},{"name": "5km","value": "5km"}];
120 // },5000)
121 },
122 methods: {
123 showDrawer(e) {
124 this.$refs[e].open()
125 },
126 closeDrawer(e) {
127 this.$refs[e].close()
128 },
129 change(e, type) {
130 this[type] = e
131 },
132 onClickItem(e) {
133 if (this.current !== e) {
134 this.current = e;
135 }
136 },
137 dropDown(){
138 console.log('下拉')
139 },
140 //接收菜单结果
141 confirm(e){
142 this.indexArr = e.index;
143 this.valueArr = e.value;
144 return;
145 console.log('修改菜单');
146 this.filterData[4].submenu[1] = {
147 "name": "项目2",
148 "submenu": [
149
150 ]
151 }
152 }
153 },
154 onNavigationBarButtonTap(e) {
155 this.showRight = !this.showRight
156 },
157 //上拉加载,
158 onReachBottom(){
159 console.log('到底加载')
160 let len = this.goodsList.length;
161 if(len>=30){
162 this.loadingText="~~到底了~~";
163 return false;
164 }else{
165 this.loadingText="正在加载...";
166 }
167 let end_goods_id = this.goodsList[len-1].goods_id;
168 for(let i=1;i<=10;i++){
169 let goods_id = end_goods_id+i;
170 let p = { goods_id: goods_id, img: '/static/img/goods/p'+(goods_id%10==0?10:goods_id%10)+'.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' };
171 this.goodsList.push(p);
172 }
173 },
174 }
175 </script>
176
177 <style lang="scss">
178 .content {
179 display: flex;
180 flex-direction: column;
181 align-items: center;
182 justify-content: center;
183 background-color: #F7F6F6;
184 }
185 .header{
186 display: flex;
187 flex-direction: column;
188 align-items: center;
189 justify-content: center;
190 background-color: #F7F6F6;
191 height:178rpx ;
192 width: 100%;
193 z-index: 999;
194 position: fixed;
195 top: 0;
196 }
197 .searchBar {
198 width: 670rpx;
199 display: flex;
200 position: fixed;
201 top: 0;
202 justify-content: center;
203 align-items: center;
204 box-sizing: border-box;
205 padding: 0rpx 16rpx;
206 border: 1px solid #FF6B4A;
207 border-radius: 8rpx;
208 background-color: #ffffff;
209 }
210
211 .searchIpt {
212 height: 68rpx;
213 width: 670rpx;
214 padding: 16rpx;
215 font-size: 28rpx;
216 box-sizing: border-box;
217 }
218 .screenBar{
219 position: fixed;
220 top: 68rpx;
221 width: 670rpx;
222 height: 110rpx;
223 display: flex;
224 flex-direction: row;
225 justify-content: space-between;
226 align-items: center;
227 color: #333333;
228 font-size: 32rpx;
229 }
230 .active{
231 color: #FF6B4A;
232 }
233 .screenItem{
234 display: flex;
235 justify-content: center;
236 align-items: center;
237 }
238 .content-wrap{
239 width: 100%;
240 background-color: #FFFFFF;
241 }
242
243 .HMfilterDropdown{
244 position: fixed;
245 top: 178rpx !important;
246 }
247 .place{
248 background-color: #ffffff;
249 height: 266rpx;
250 }
251 .goods-list{
252 padding-top: 10px;
253 .loading-text{
254 width: 100%;
255 display: flex;
256 justify-content: center;
257 align-items: center;
258 height: 30px;
259 color: #979797;
260 font-size: 12px;
261 }
262 .product-list{
263 width: 92%;
264 padding: 0 4% 3vw 4%;
265 display: flex;
266 justify-content: space-between;
267 flex-wrap: wrap;
268 .product{
269 width: 48%;
270 border-radius: 10px;
271 background-color: #fff;
272 margin: 0 0 7px 0;
273 box-shadow: 0 3px 12px rgba(0,0,0,0.1);
274 image{
275 width: 100%;
276 border-radius: 10px 10px 0 0;
277 }
278 .name{
279 width: 92%;
280 padding: 5px 4%;
281 display: -webkit-box;
282 -webkit-box-orient: vertical;
283 -webkit-line-clamp: 2;
284 text-align: justify;
285 overflow: hidden;
286 font-size: 15px;
287 }
288 .info{
289 display: flex;
290 justify-content: space-between;
291 align-items: flex-end;
292 width: 92%;
293 padding: 5px 4% 5px 4%;
294 .price{
295 color: #e65339;
296 font-size: 15px;
297 font-weight: 600;
298 }
299 .slogan{
300 color: #807c87;
301 font-size: 12px;
302 }
303 }
304 }
305 }
306 }
307
308 </style>
309 1 <template>
pages/user/user.vue
1 <template> File was deleted
2 <view class="content">
3 <image class="logo" src="/static/logo.png"></image>
4 <view class="text-area">
5 <text class="title">{{title}}</text>
6 </view>
7 </view>
8 </template>
9
10 <script>
11 export default {
12 data() {
13 return {
14 title: 'Hello'
15 }
16 },
17 onLoad() {
18
19 },
20 methods: {
21
22 }
23 }
24 </script>
25
26 <style>
27 .content {
28 display: flex;
29 flex-direction: column;
30 align-items: center;
31 justify-content: center;
32 }
33
34 .logo {
35 height: 200rpx;
36 width: 200rpx;
37 margin-top: 200rpx;
38 margin-left: auto;
39 margin-right: auto;
40 margin-bottom: 50rpx;
41 }
42
43 .text-area {
44 display: flex;
45 justify-content: center;
46 }
47
48 .title {
49 font-size: 36rpx;
50 color: #8f8f94;
51 }
52 </style>
53 1 <template>
File was created 1 <script>
2 export default {
3 onLaunch: function() {
4 console.log('App Launch')
5 },
6 onShow: function() {
7 console.log('App Show')
8 },
9 onHide: function() {
10 console.log('App Hide')
11 }
12 }
13 </script>
14
15 <style>
16 /*每个页面公共css */
17 </style>
18
File was created 1 MIT License
2
3 Copyright (c) 2018 DCloud
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE.
22
File was created 1 thie is a new gulu project base on vue
2
File was created 1 # hello-uniapp
2
3 `uni-app`框架示例,一套代码,同时发行到iOS、Android、H5、小程序等多个平台,请使用手机扫码快速体验`uni-app`的强大功能。
4
5 <p align="center">
6 <a href="https://m3w.cn/uniapp" target="blank">
7 <img src="https://img-cdn-qiniu.dcloud.net.cn/uni-app-qr-all.jpg"/>
8 </a>
9 </p>
10
11 `uni-app`官网文档详见[https://uniapp.dcloud.io](https://uniapp.dcloud.io)
12
13 更多uni-app的模板、示例详见[插件市场](https://ext.dcloud.net.cn/)
14
15
src/common/data.js
File was created 1 // 数据格式,数据中只需要包含以下字段和数据格式,可以添加字段,比如id等等,不影响组件显示,
2 // 组件的返回结果是有菜单数组下标形式返回,
3 // 如果传入数据中有value,也会返回value,开发者可根据返回的下标获取所选中的菜单
4 /*
5 [
6 {
7 "name":"", //字符串类型 选填项 菜单名称,如不填,则取第一个子菜单的name值,filter和radio类型则将设置为"筛选"
8 "type":"" //字符串类型 必填项 可取值 hierarchy/filter/radio hierarchy单/多层级菜单(最多三级); filter筛选多选菜单; radio筛选单选菜单
9 "submenu":[ //对象数组类型 必填项 子菜单数据
10 {
11 "name":"", //字符串类型 必填项 菜单名称
12 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null,filter类型此字段无效果
13 "submenu":[ //对象数组类型 必填项 子菜单数据
14 {
15 "name":"", //字符串类型 必填项 菜单名称
16 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null
17 "submenu":[ //对象数组类型 必填项 子菜单数据 filter类型无效
18 {
19 "name":"", //字符串类型 必填项 菜单名称 hierarchy类型层级最多到此
20 "value":"", //字符串类型 选填项 自定义内容,比如id等等,如果填写了,confirm返回的结果中将返回对应选中的value,若菜单无value字段则返回null
21 }
22 ]
23 }
24 ]
25 }
26 ]
27 }
28 ]
29 */
30
31 //0.0.4版本起 返回结果将有两部分组成:
32 /*
33 {
34 index:[], //旧版本的下标数组形式
35 value:[] //菜单中的valve,结构和下标结果数组一样,只是把下标替换成了value而已
36 }
37 */
38 // 以下演示数据中,我故意把value设置成跟name一样,只是为了方便演示,使示例更加易懂,实际使用时候value应该是一个标识,给后台识别所用的.
39 // 数据较长,请仔细查看。
40 export default [
41 {
42 "name":'综合',
43 "type": 'filter',
44 "submenu": [{
45 "submenu": [
46
47 ]
48 },
49 ],
50 },
51 {
52 name:'品牌',
53 "type": 'filter',
54 "submenu": [{
55 "name": '品牌',
56 "value": "品牌",
57 "submenu": [{
58 "name": "帕森",
59 "value": "帕森",
60 },
61 {
62 "name": "海伦凯勒",
63 "value": "海伦凯勒",
64 },
65 ]
66 },
67 ]
68 },
69 {
70 "name":'功能',
71 "type": 'filter',
72 "submenu": [{
73 "name": "智能排序",
74 "value": "智能排序"
75 },
76 {
77 "name": "离我最近",
78 "value": "离我最近"
79 },
80 {
81 "name": "人均从高到低",
82 "value": "人均从高到低"
83 },
84 {
85 "name": "人均从低到高",
86 "value": "人均从低到高"
87 }
88 ]
89 },
90 {
91 "name":'材质',
92 "type": 'filter',
93 "submenu": [{
94 "submenu": [{
95 "name": "满减活动",
96 "value": "满减活动"
97 },
98 {
99 "name": "打折优惠",
100 "value": "打折优惠"
101 },
102 {
103 "name": "会员专享",
104 "value": "会员专享"
105 }
106 ]
107 }
108 ]
109 },
110 {
111 "name":'折扣',
112 "type": 'filter',
113 "submenu": [{
114 "name": "折扣(多选)",
115 "submenu": [{
116 "name": "满减活动",
117 "value": "满减活动"
118 },
119 {
120 "name": "打折优惠",
121 "value": "打折优惠"
122 },
123 {
124 "name": "会员专享",
125 "value": "会员专享"
126 }
127 ]
128 }
129 ]
130 }
131 ]
132
133
src/components/HM-filterDropdown/HM-filterDropdown.vue
File was created 1 <template>
2 <view class="HMfilterDropdown" @touchmove.stop.prevent="discard" @tap.stop="discard">
3 <view class="nav">
4 <block v-for="(item,index) in menu" :key="index">
5 <view class="first-menu" :class="{'on':showPage==index}" @tap="togglePage(index)">
6 <text class="name">{{item.name}}</text>
7 <text class="iconfont triangle" :style="'transform:rotate('+triangleDeg[index]+'deg);'"></text>
8 </view>
9 </block>
10 </view>
11 <view class="mask" :class="{'show':isShowMask,'hide':maskVisibility!=true}" @tap="togglePage(showPage)"></view>
12 <block v-for="(page,page_index) in subData" :key="page_index">
13 <view class="sub-menu-class" :class="{'show':showPage==page_index,'hide':pageState[page_index]!=true}">
14 <block v-if="page.type=='hierarchy'&& page.submenu.length>0">
15 <scroll-view class="sub-menu-list" :class="[activeMenuArr[page_index].length>1?'first':'alone']"
16 :scroll-y="true" :scroll-into-view="'first_id'+firstScrollInto">
17 <block v-for="(sub,index) in page.submenu" :key="index">
18 <view class="sub-menu" :id="'first_id'+index" :class="{'on':activeMenuArr[page_index][0]==index}" @tap="selectHierarchyMenu(page_index,index,null,null)">
19 <view class="menu-name">
20 <text>{{sub.name}}</text>
21 <text class="iconfont selected"></text>
22 </view>
23 </view>
24 </block>
25 </scroll-view>
26 <block v-for="(sub,index) in page.submenu" :key="index">
27 <scroll-view class="sub-menu-list not-first" :scroll-y="true" v-if="activeMenuArr[page_index][0]==index&&sub.submenu.length>0"
28 :scroll-into-view="'second_id'+secondScrollInto">
29 <block v-for="(sub_second,second_index) in sub.submenu" :key="second_index">
30 <view class="sub-menu" :id="'second_id'+second_index" :class="{'on':activeMenuArr[page_index][1]==second_index}">
31 <view class="menu-name" @tap="selectHierarchyMenu(page_index,activeMenuArr[page_index][0],second_index,null)">
32 <text>{{sub_second.name}}</text>
33 <text class="iconfont selected"></text>
34 </view>
35 <view class="more-sub-menu" v-if="sub_second.submenu&&sub.submenu.length>0&&sub_second.submenu.length>0">
36 <block v-for="(sub2,sub2_index) in sub_second.submenu" :key="sub2_index">
37 <text v-if="sub_second.showAllSub || (sub2_index<8)" :class="{'on':activeMenuArr[page_index][1]==second_index&&activeMenuArr[page_index][2]==sub2_index}"
38 @tap="selectHierarchyMenu(page_index,activeMenuArr[page_index][0],second_index,sub2_index)">{{sub2.name}}</text>
39 <text v-if="sub_second.showAllSub!=true && sub2_index==8 && sub_second.submenu.length>9" @tap="showMoreSub(second_index)">更多<text
40 class="iconfont triangle"></text></text>
41 </block>
42 </view>
43 </view>
44 </block>
45 </scroll-view>
46 </block>
47 </block>
48 <block v-if="page.type=='filter'">
49 <view class="filter">
50 <scroll-view class="menu-box" :scroll-y="true">
51 <view class="box" v-for="(box,box_index) in page.submenu" :key="box_index">
52 <view class="title">{{box.name}}</view>
53 <view class="labels">
54 <view v-for="(label,label_index) in box.submenu" :key="label_index" @tap="selectFilterLabel(page_index,box_index,label_index)"
55 :class="{'on':label.selected}">{{label.name}}</view>
56 </view>
57 </view>
58 </scroll-view>
59 <view class="btn-box">
60 <view class="reset" @tap="resetFilterData(page_index)">重置</view>
61 <view class="submit" @tap="setFilterData(page_index)">确定</view>
62 </view>
63 </view>
64 </block>
65 <block v-if="page.type=='radio'">
66 <view class="filter">
67 <scroll-view class="menu-box" :scroll-y="true">
68 <view class="box" v-for="(box,box_index) in page.submenu" :key="box_index">
69 <view class="title">{{box.name}}</view>
70 <view class="labels">
71 <view v-for="(label,label_index) in box.submenu" :key="label_index" @tap="selectRadioLabel(page_index,box_index,label_index)"
72 :class="{'on':label.selected}">{{label.name}}</view>
73 </view>
74 </view>
75 </scroll-view>
76 <view class="btn-box">
77 <view class="reset" @tap="resetFilterData(page_index)">重置</view>
78 <view class="submit" @tap="setFilterData(page_index)">确定</view>
79 </view>
80 </view>
81 </block>
82 </view>
83 </block>
84 </view>
85 </template>
86 <script>
87 export default {
88 data() {
89 return {
90 subData: [], //菜单数据
91 menu: [], //顶部横条数据
92 showPage: -1, //菜单页面显示/隐藏动画控制
93 pageState: [], //页面的状态
94 activeMenuArr: [], //UI状态
95 shadowActiveMenuArr: [], //记录选中
96 defaultActive:[],
97 triangleDeg: [], //小三角形的翻转动画控制
98 isShowMask: false, //遮罩层显示/隐藏动画控制
99 maskVisibility: false, //遮罩层显示/隐藏状态
100 //滚动区域定位
101 firstScrollInto: 0,
102 secondScrollInto: 0,
103 componentTop:0 ,//组件top
104 isReadNewSelect:false
105 }
106 },
107 props: {
108 filterData: {
109 value: Array,
110 default: []
111 },
112 defaultSelected:{
113 value: Array,
114 default: []
115 },
116 updateMenuName:{
117 value: Boolean,
118 default: true
119 },
120 dataFormat:{
121 value: String,
122 default: 'Array'
123 }
124 },
125 watch: {
126 filterData: {
127 handler() {
128 this.initMenu(); //filterData重新赋值初始化菜单
129 },
130 immediate: true
131 },
132 defaultSelected(newVal) {
133 if(newVal.length==0){
134 return;
135 }
136 this.defaultActive = JSON.parse(JSON.stringify(newVal));
137 this.activeMenuArr = JSON.parse(JSON.stringify(newVal));
138 this.shadowActiveMenuArr = JSON.parse(JSON.stringify(newVal));
139 if(this.updateMenuName){
140 this.setMenuName();
141 }
142 }
143 },
144 methods: {
145 initMenu() {
146 let tmpMenuActiveArr=[];
147 let tmpMenu=[];
148 for (let i = 0; i < this.filterData.length; i++) {
149 let tmpitem = this.filterData[i];
150 tmpMenu.push({
151 //如果没有设置name,则取第一个菜单作为menu.name,filter类型则将"筛选"作为menu.name
152 name: tmpitem.name || (tmpitem.type == "filter" ? "筛选" : tmpitem.submenu[0].name),
153 type: tmpitem.type
154 });
155 //初始化选中项数组-ui状态
156 tmpMenuActiveArr.push(this.processActive(tmpitem));
157 //初始化角度数组
158 this.triangleDeg.push(0);
159 //初始化控制显示状态数组
160 this.pageState.push(false);
161 //递归处理子菜单数据
162 tmpitem = this.processSubMenu(tmpitem);
163 this.filterData[i] = tmpitem;
164 }
165 this.menu = tmpMenu;
166 //初始化选中项数组
167 tmpMenuActiveArr = this.defaultActive.length>0?this.defaultActive:this.activeMenuArr.length>0?this.activeMenuArr:tmpMenuActiveArr;
168 this.defaultActive = [];
169 this.activeMenuArr = JSON.parse(JSON.stringify(tmpMenuActiveArr));
170 this.shadowActiveMenuArr = JSON.parse(JSON.stringify(tmpMenuActiveArr));
171 //加载菜单数据
172 this.subData = this.filterData;
173 //设定顶部菜单名字
174 if(this.updateMenuName){
175 this.setMenuName();
176 }
177 },
178 setMenuName(){
179 for(var i=0;i<this.activeMenuArr.length;i++){
180 let row = this.activeMenuArr[i];
181 if (typeof(row[0]) != 'object'){
182 var tmpsub = false;
183 if(row.length>0 && row[0]!=null){
184 tmpsub = this.subData[i].submenu[row[0]];
185 if(row.length>1 && row[1]!=null){
186 tmpsub = tmpsub.submenu[row[1]];
187 if(row.length>2 && row[2]!=null){
188 tmpsub = tmpsub.submenu[row[2]];
189 }
190 }
191 }else{
192 tmpsub = false;
193 }
194 if(tmpsub){
195 this.menu[i].name = tmpsub.name;
196 }
197 }
198 }
199 },
200 //展开更多
201 showMoreSub(index) {
202 this.subData[this.showPage].submenu[this.activeMenuArr[this.showPage][0]].submenu[index].showAllSub = true;
203 this.$forceUpdate();
204 },
205 //选中
206 selectHierarchyMenu(page_index, level1_index, level2_index, level3_index) {
207 //读取记录
208 if (level1_index != null && level2_index == null && level3_index == null && this.shadowActiveMenuArr[page_index][0] ==
209 level1_index) {
210 this.activeMenuArr.splice(page_index, 1, JSON.parse(JSON.stringify(this.shadowActiveMenuArr[page_index])));
211 } else {
212 this.activeMenuArr[page_index].splice(0, 1, level1_index);
213 (level2_index!=null||this.activeMenuArr[page_index].length>=2)&&this.activeMenuArr[page_index].splice(1, 1, level2_index) || this.activeMenuArr[page_index].splice(1, 1);
214 (level3_index!=null||this.activeMenuArr[page_index].length>=3)&&this.activeMenuArr[page_index].splice(2, 1, level3_index) || this.activeMenuArr[page_index].splice(2, 1);
215 }
216 //写入结果
217 if (level3_index != null || level2_index != null || (level1_index != null && this.subData[page_index].submenu[level1_index].submenu.length == 0)
218 ) {
219 let sub = this.subData[page_index].submenu[level1_index].submenu[level2_index];
220 if(this.updateMenuName){
221 this.menu[page_index].name = (level3_index != null && sub.submenu[level3_index].name) || (level2_index != null && sub.name) || this.subData[page_index].submenu[level1_index].name;
222 }
223 this.shadowActiveMenuArr[page_index] = JSON.parse(JSON.stringify(this.activeMenuArr[page_index]));
224 this.togglePage(this.showPage);
225 }
226 },
227 //写入结果,筛选
228 setFilterData(page_index) {
229 this.shadowActiveMenuArr[page_index] = JSON.parse(JSON.stringify(this.activeMenuArr[page_index]));
230 this.togglePage(this.showPage);
231 },
232 //重置结果和ui,筛选
233 resetFilterData(page_index) {
234 let tmpArr = [];
235 let level = this.shadowActiveMenuArr[page_index].length;
236 while (level > 0) {
237 tmpArr.push([]);
238 let box = this.subData[page_index].submenu[level - 1].submenu;
239 for (let i = 0; i < box.length; i++) {
240 this.subData[page_index].submenu[level - 1].submenu[i].selected = false;
241 }
242 level--;
243 }
244 this.activeMenuArr[page_index] = JSON.parse(JSON.stringify(tmpArr));
245 this.$forceUpdate();
246 },
247 //选中筛选类label-UI状态
248 selectFilterLabel(page_index, box_index, label_index) {
249 let find_index = this.activeMenuArr[page_index][box_index].indexOf(label_index);
250 if (find_index > -1) {
251 this.activeMenuArr[page_index][box_index].splice(find_index, 1);
252 this.subData[page_index].submenu[box_index].submenu[label_index].selected = false;
253 } else {
254 this.activeMenuArr[page_index][box_index].push(label_index);
255 this.subData[page_index].submenu[box_index].submenu[label_index].selected = true;
256 }
257 this.$forceUpdate();
258 },
259 //选中单选类label-UI状态
260 selectRadioLabel(page_index, box_index, label_index) {
261
262 let activeIndex = this.activeMenuArr[page_index][box_index][0];
263 if(activeIndex == label_index){
264 this.subData[page_index].submenu[box_index].submenu[activeIndex].selected = false;
265 this.activeMenuArr[page_index][box_index][0] = null;
266 }else{
267 if(activeIndex!=null && activeIndex<this.subData[page_index].submenu[box_index].submenu.length){
268 this.subData[page_index].submenu[box_index].submenu[activeIndex].selected = false;
269 }
270
271 this.subData[page_index].submenu[box_index].submenu[label_index].selected = true;
272 this.activeMenuArr[page_index][box_index][0] = label_index;
273 }
274 this.$forceUpdate();
275 },
276 //菜单开关
277 togglePage(index) {
278 if (index == this.showPage) {
279 this.hidePageLayer(true);
280 this.hideMask();
281 this.showPage = -1;
282 } else {
283 if (this.showPage > -1) {
284 this.hidePageLayer(false);
285 }
286 this.showPageLayer(index);
287 this.showMask();
288 }
289 },
290 //hide遮罩层
291 hideMask() {
292 this.isShowMask = false;
293 setTimeout(() => {
294 this.maskVisibility = false;
295 }, 200);
296 },
297 //show遮罩层
298 showMask() {
299 this.maskVisibility = true;
300 this.$nextTick(() => {
301 setTimeout(() => {
302 this.isShowMask = true;
303 }, 0);
304 })
305 },
306 //hide菜单页
307 hidePageLayer(isAnimation) {
308 this.triangleDeg[this.showPage] = 0;
309 let tmpIndex = this.showPage;
310 if (isAnimation) {
311 setTimeout(() => {
312 this.pageState.splice(tmpIndex, 1, false);
313 }, 200);
314 this.confirm();
315 } else {
316 this.pageState.splice(tmpIndex, 1, false)
317 }
318 this.firstScrollInto = null;
319 this.secondScrollInto = null;
320 },
321 confirm() {
322 let index = JSON.parse(JSON.stringify(this.shadowActiveMenuArr));
323 let value = JSON.parse(JSON.stringify(this.shadowActiveMenuArr));
324
325 //对结果做一下处理
326 index.forEach((item, i) => {
327 if (typeof(item[0]) == 'object') {
328 //针对筛选结果过一个排序
329 item.forEach((s, j) => {
330 if(s!=null){
331 s.sort((val1, val2) => {
332 return val1 - val2;
333 });
334 item[j] = s;
335 s.forEach((v, k) => {
336 value[i][j][k] = (v==null||v>=this.subData[i].submenu[j].submenu.length)?null:this.subData[i].submenu[j].submenu[v].value;
337 if(this.subData[i].type == 'radio' && value[i][j][k] == null){
338 value[i][j] = [];
339 index[i][j] = [];
340 }
341 });
342 }
343 });
344 }else{
345 let submenu = this.subData[i].submenu[item[0]];
346 value[i][0] = submenu.value;
347 if(value[i].length>=2 && item[1]!=null){
348 if(submenu.submenu.length>0){
349 submenu = submenu.submenu[item[1]];
350 value[i][1] = submenu.hasOwnProperty('value')?submenu.value:null;
351 }else{
352 value[i][1] = null
353 }
354 if(value[i].length>=3 && item[2]!=null){
355 if(submenu.submenu.length>0){
356 submenu = submenu.submenu[item[2]];
357 value[i][2] = submenu.hasOwnProperty('value')?submenu.value:null;
358 }else{
359 value[i][2] = null;
360 }
361 }
362 }
363 }
364 index[i] = item;
365
366 });
367 // 输出
368 this.$emit('confirm', {
369 index: index,
370 value: value
371 });
372 },
373 //show菜单页
374 showPageLayer(index) {
375 this.processPage(index);
376 this.pageState.splice(index, 1, true);
377 this.$nextTick(() => {
378 setTimeout(() => {
379 this.showPage = index;
380 }, 0);
381 })
382 this.triangleDeg[index] = 180;
383 },
384 reloadActiveMenuArr(){
385 for (let i = 0; i < this.filterData.length; i++) {
386 let tmpitem = this.filterData[i];
387 let tmpArr = this.processActive(tmpitem);
388 tmpitem = this.processSubMenu(tmpitem);
389 if(this.activeMenuArr[i].length!=tmpArr.length){
390 this.filterData[i] = tmpitem;
391 this.activeMenuArr.splice(i, 1, JSON.parse(JSON.stringify(tmpArr)));
392 this.shadowActiveMenuArr.splice(i, 1, JSON.parse(JSON.stringify(tmpArr)));
393 }
394 }
395 this.subData = this.filterData;
396 this.$forceUpdate();
397 },
398 processPage(index) {
399 //check UI控制数组,结果数组,防止传入数据层级和UI控制数组不同步
400 this.reloadActiveMenuArr();
401 //重置UI控制数组
402 this.activeMenuArr.splice(index, 1, JSON.parse(JSON.stringify(this.shadowActiveMenuArr[index])));
403 if (this.menu[index].type == 'filter') {
404 //重载筛选页选中状态
405 let level = this.shadowActiveMenuArr[index].length;
406 for (let i = 0; i < level; i++) {
407 let box = this.subData[index].submenu[i].submenu;
408 for (let j = 0; j < box.length; j++) {
409 if (this.shadowActiveMenuArr[index][i].indexOf(j) > -1) {
410 this.subData[index].submenu[i].submenu[j].selected = true;
411 } else {
412 this.subData[index].submenu[i].submenu[j].selected = false;
413 }
414 }
415 }
416 } else if (this.menu[index].type == 'hierarchy') {
417 this.$nextTick(() => {
418 setTimeout(() => {
419 //滚动到选中项
420 this.firstScrollInto = parseInt(this.activeMenuArr[index][0]);
421 this.secondScrollInto = parseInt(this.activeMenuArr[index][1]);
422 }, 0);
423 })
424 } else if (this.menu[index].type == 'radio') {
425 //重载筛选页选中状态
426 let level = this.shadowActiveMenuArr[index].length;
427 for (let i = 0; i < level; i++) {
428 let box = this.subData[index].submenu[i].submenu;
429 for (let j = 0; j < box.length; j++) {
430 if (this.shadowActiveMenuArr[index][i].indexOf(j) > -1) {
431 this.subData[index].submenu[i].submenu[j].selected = true;
432 } else {
433 this.subData[index].submenu[i].submenu[j].selected = false;
434 }
435 }
436 }
437 }
438 },
439 processActive(tmpitem) {
440 let tmpArr = []
441 if (tmpitem.type == 'hierarchy'&&tmpitem.hasOwnProperty('submenu')&&tmpitem.submenu.length>0) {
442 let level = this.getMaxFloor(tmpitem.submenu);
443 while (level > 0) {
444 tmpArr.push(0);
445 level--;
446 }
447 } else if (tmpitem.type == 'filter') {
448 let level = tmpitem.submenu.length;
449 while (level > 0) {
450 tmpArr.push([]);
451 level--;
452 }
453 } else if (tmpitem.type == 'radio') {
454 let level = tmpitem.submenu.length;
455 while (level > 0) {
456 tmpArr.push([]);
457 level--;
458 }
459 }
460 return tmpArr;
461 },
462 processSubMenu(menu) {
463 if (menu.hasOwnProperty('submenu') && menu.submenu.length > 0) {
464 for (let i = 0; i < menu.submenu.length; i++) {
465 menu.submenu[i] = this.processSubMenu(menu.submenu[i]);
466 }
467 } else {
468 menu.submenu = [];
469 }
470 return menu;
471 },
472 //计算菜单层级
473 getMaxFloor(treeData) {
474 let floor = 0
475 let max = 0
476 function each(data, floor) {
477 data.forEach(e => {
478 max = floor > max ? floor : max;
479 if (e.hasOwnProperty('submenu') && e.submenu.length > 0) {
480 each(e.submenu, floor + 1)
481 }
482 })
483 }
484 each(treeData, 1)
485 return max;
486 },
487 discard() {
488
489 }
490 }
491 }
492 </script>
493 <style lang="scss">
494 .HMfilterDropdown {
495 flex-shrink: 0;
496 width: 100%;
497 height: 44px;
498 position: fixed;
499 z-index: 997;
500 flex-wrap: nowrap;
501 display: flex;
502 flex-direction: row;
503 top: var(--window-top);
504 left:0;
505 view {
506 display: flex;
507 flex-wrap: nowrap;
508 }
509 }
510 .region {
511 flex: 1;
512 height: 44px;
513 }
514 .nav {
515 width: 100%;
516 height: 44px;
517 border-bottom: solid 1rpx #eee;
518 z-index: 12;
519 background-color: #ffffff;
520 flex-direction: row;
521 .first-menu {
522 width: 100%;
523 font-size: 13px;
524 color: #757575;
525 flex-direction: row;
526 align-items: center;
527 justify-content: center;
528 transition: color .2s linear;
529
530 &.on {
531 color: #ec652b;
532
533 .iconfont {
534 color: #ec652b;
535 }
536 }
537 .name {
538 height: 20px;
539 text-align: center;
540 text-overflow: clip;
541 overflow: hidden;
542 }
543 .iconfont {
544 width: 13px;
545 height: 13px;
546 align-items: center;
547 justify-content: center;
548 transition: transform .2s linear, color .2s linear;
549 }
550 }
551 }
552 .sub-menu-class {
553 width: 100%;
554 position: absolute;
555 left: 0;
556 transform: translate3d(0, - 100%, 0);
557 max-height: 345px;
558 background-color: #ffffff;
559 z-index: 11;
560 box-shadow: 0 5px 5px rgba(0, 0, 0, .1);
561 overflow: hidden;
562 flex-direction: row;
563 transition: transform .15s linear;
564 &.hide {
565 display: none;
566 }
567
568 &.show {
569 transform: translate3d(0, calc(44px + 1rpx), 0);
570 }
571 }
572 .sub-menu-list {
573 width: 100%;
574 height: 345px;
575 flex-direction: column;
576 .sub-menu {
577 min-height: 44px;
578 font-size: 13px;
579 flex-direction: column;
580 padding-right: 15px;
581 >.menu-name {
582 height: 44px;
583 flex-direction: row;
584 align-items: center;
585 justify-content: space-between;
586 >.iconfont {
587 display: none;
588 font-size: 18px;
589 color: #ec652b;
590 }
591 }
592 }
593 &.first {
594 flex-shrink: 0;
595 width: 236rpx;
596 background-color: #f0f0f0;
597 .sub-menu {
598 padding-left: 15px;
599
600 &.on {
601 background-color: #fff;
602 }
603 }
604 }
605 &.alone {
606 max-height: 345px;
607 min-height: 170px;
608 height: auto;
609 .sub-menu {
610 min-height: calc(44px - 1rpx);
611 margin-left: 15px;
612 border-bottom: solid 1rpx #e5e5e5;
613
614 &.on {
615 color: #ec652b;
616
617 >.menu-name {
618 >.iconfont {
619 display: block;
620 }
621 }
622 }
623 }
624 }
625 &.not-first {
626 .sub-menu {
627 min-height: calc(44px - 1rpx);
628 margin-left: 15px;
629 border-bottom: solid 1rpx #e5e5e5;
630 >.menu-name {
631 height: calc(44px - 1rpx);
632 >.iconfont {
633 display: none;
634 font-size: 18px;
635 color: #ec652b;
636 }
637 }
638 &.on {
639 color: #ec652b;
640 >.menu-name {
641 >.iconfont {
642 display: block;
643 }
644 }
645 }
646 .more-sub-menu {
647 flex-direction: row;
648 flex-wrap: wrap;
649 padding-bottom: 9px;
650 >text {
651 height: 30px;
652 border-radius: 3px;
653 background-color: #f5f5f5;
654 color: #9b9b9b;
655 margin-bottom: 6px;
656 margin-right: 6px;
657 text-align: center;
658 line-height: 30px;
659 border: solid #f5f5f5 1rpx;
660 flex: 0 0 calc(33.33% - 6px);
661 overflow: hidden;
662 font-size: 12px;
663 &:nth-child(3n) {
664 margin-right: 0;
665 }
666 &.on {
667 border-color: #f6c8ac;
668 color: #ec652b;
669 }
670 .iconfont {
671 color: #9b9b9b;
672 }
673 }
674 }
675 }
676 }
677 }
678 .filter {
679 width: 100%;
680 height: 345px;
681 display: flex;
682 flex-direction: column;
683 justify-content: space-between;
684 align-items: center;
685 .menu-box {
686 width: 698rpx;
687 height: calc(345px - 75px);
688 flex-shrink: 1;
689 .box {
690 width: 100%;
691 margin-top: 16px;
692 flex-direction: column;
693 .title {
694 width: 100%;
695 font-size: 13px;
696 color: #888;
697 }
698 .labels {
699 flex-direction: row;
700 flex-wrap: wrap;
701 .on {
702 border-color: #ec652b;
703 background-color: #ec652b;
704 color: #fff;
705 }
706 >view {
707 width: 148rpx;
708 height: 30px;
709 border: solid 1rpx #adadad;
710 border-radius: 2px;
711 margin-right: 15px;
712 margin-top: 8px;
713 font-size: 12px;
714 flex-direction: row;
715 justify-content: center;
716 align-items: center;
717 &:nth-child(4n) {
718 margin-right: 0;
719 }
720 }
721 }
722 }
723 }
724 .btn-box {
725 flex-shrink: 0;
726 width: 698rpx;
727 height: 75px;
728 flex-direction: row !important;
729 align-items: center;
730 justify-content: space-between;
731 >view {
732 width: 320rpx;
733 height: 40px;
734 border-radius: 40px;
735 border: solid 1rpx #ec652b;
736 align-items: center;
737 justify-content: center;
738 }
739 .reset {
740 color: #ec652b;
741 }
742 .submit {
743 color: #fff;
744 background-color: #ec652b;
745 }
746 }
747 }
748 .mask {
749 z-index: 10;
750 position: fixed;
751 top: 0;
752 left: 0;
753 right: 0;
754 bottom: 0;
755 background-color: rgba(0, 0, 0, 0);
756 transition: background-color .15s linear;
757 &.show {
758 background-color: rgba(0, 0, 0, 0.5);
759 }
760 &.hide {
761 display: none;
762 }
763 }
764 /* 字体图标 */
765 @font-face {
766 font-family: "HM-FD-font";
767 src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALAAAsAAAAABpQAAAJzAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgp4gQIBNgIkAwwLCAAEIAWEbQc5G8sFERWMIbIfCbbzqA4hp7InSBibVsYGb4J42o82b3e/nJlHMw/NHbGOlwKJRCRpwzPtpAECCOZubdqxjYpQLMlVg+70/08edrgQOtx2ukpVyApZn+dyehPoQObHo3O85rYx9vOjXoBxQIHugW2yIkqIW2QXcScu4jwE8CSWbKSmrqUHFwOaJoCsLM5P4haSGIxRcRHshrUGucLCVcfqI3AZfV/+USguKCwNmtsxVztDxU/n55C+3W0Z4QQpEOTNFqCBbMCAjDUWB9CIwWk87aa70cYgqLkyd3dEmm+18R8eKATEBrV7A5CulBT8dKiWOYZk412XNcDdKSEKSGODnyKIDl+dmVt9/Dx4pu/xyeutkMlHISGPTsPCnoTNP9nOT6wTtDdlO6dPr47efvj942lkYuQzrhMKEjq9N6y98P3340gmlJ/RStUD6F31CAEEPtUW94/7rf+7XgaAz57X0ZHXAGsFFwVgw38yALuMb0IBbVyNamFYEw4oKMDTj3AHRQP5Pt4dci9VwSVkRNQh5r7CLskZadhsWHhRDBsXczk8ZYk3ewnCxmQeQKa3BOHvA8XXO2j+vqRhf7CE+sPmn4anvoL29JLa4qqaUQkmoK+QG2osCckq7txi2leK86aIPyJ3eQZ8xytXYmyQ51jQndJAxIJlqiGSLsOqImiZCjTiZCJt6Lq26U2OoXqwUo0hRaAE0K5AziANy/uLVeXzWyjVqyjcoeupjxDr5MMDn8MDkLG9Aenu5ZrOSSoghAUsRmogkkahSoWAtnlUARnCkY3It0Iu7mWhdmd9Z/19BwBP6GidEi0G56opckXTGZVSPxgAAAA=');
768 }
769 .iconfont {
770 font-family: "HM-FD-font" !important;
771 font-size: 13px;
772 font-style: normal;
773 color: #757575;
774 &.triangle {
775 &:before {
776 content: "\e65a";
777 }
778 }
779 &.selected {
780 &:before {
781 content: "\e607";
782 }
783 }
784 }
785 </style>
786
src/components/card.vue
File was created 1 <template>
2 <view>
3
4 </view>
5 </template>
6
7 <script>
8 export default {
9 data() {
10 return {
11
12 };
13 }
14 }
15 </script>
16
17 <style lang="scss">
18
19 </style>
20
src/components/uni-drawer/uni-drawer.vue
File was created 1 <template>
2 <view v-if="visibleSync" :class="{ 'uni-drawer--visible': showDrawer }" class="uni-drawer" @touchmove.stop.prevent="clear">
3 <view class="uni-drawer__mask" :class="{ 'uni-drawer__mask--visible': showDrawer && mask }" @tap="close('mask')" />
4 <view class="uni-drawer__content" :class="{'uni-drawer--right': rightMode,'uni-drawer--left': !rightMode, 'uni-drawer__content--visible': showDrawer}" :style="{width:drawerWidth+'px'}">
5 <slot />
6 </view>
7 </view>
8 </template>
9
10 <script>
11 /**
12 * Drawer 抽屉
13 * @description 抽屉侧滑菜单
14 * @tutorial https://ext.dcloud.net.cn/plugin?id=26
15 * @property {Boolean} mask = [true | false] 是否显示遮罩
16 * @property {Boolean} maskClick = [true | false] 点击遮罩是否关闭
17 * @property {Boolean} mode = [left | right] Drawer 滑出位置
18 * @value left 从左侧滑出
19 * @value right 从右侧侧滑出
20 * @property {Number} width 抽屉的宽度 ,仅 vue 页面生效
21 * @event {Function} close 组件关闭时触发事件
22 */
23 export default {
24 name: 'UniDrawer',
25 props: {
26 /**
27 * 显示模式(左、右),只在初始化生效
28 */
29 mode: {
30 type: String,
31 default: ''
32 },
33 /**
34 * 蒙层显示状态
35 */
36 mask: {
37 type: Boolean,
38 default: true
39 },
40 /**
41 * 遮罩是否可点击关闭
42 */
43 maskClick:{
44 type: Boolean,
45 default: true
46 },
47 /**
48 * 抽屉宽度
49 */
50 width: {
51 type: Number,
52 default: 220
53 }
54 },
55 data() {
56 return {
57 visibleSync: false,
58 showDrawer: false,
59 rightMode: false,
60 watchTimer: null,
61 drawerWidth: 220
62 }
63 },
64 created() {
65 // #ifndef APP-NVUE
66 this.drawerWidth = this.width
67 // #endif
68 this.rightMode = this.mode === 'right'
69 },
70 methods: {
71 clear(){},
72 close(type) {
73 // fixed by mehaotian 抽屉尚未完全关闭或遮罩禁止点击时不触发以下逻辑
74 if((type === 'mask' && !this.maskClick) || !this.visibleSync) return
75 this._change('showDrawer', 'visibleSync', false)
76 },
77 open() {
78 // fixed by mehaotian 处理重复点击打开的事件
79 if(this.visibleSync) return
80 this._change('visibleSync', 'showDrawer', true)
81 },
82 _change(param1, param2, status) {
83 this[param1] = status
84 if (this.watchTimer) {
85 clearTimeout(this.watchTimer)
86 }
87 this.watchTimer = setTimeout(() => {
88 this[param2] = status
89 this.$emit('change',status)
90 }, status ? 50 : 300)
91 }
92 }
93 }
94 </script>
95
96 <style lang="scss" scoped>
97 // 抽屉宽度
98 $drawer-width: 220px;
99
100 .uni-drawer {
101 /* #ifndef APP-NVUE */
102 display: block;
103 /* #endif */
104 position: fixed;
105 top: 0;
106 left: 0;
107 right: 0;
108 bottom: 0;
109 overflow: hidden;
110 z-index: 999;
111 }
112
113 .uni-drawer__content {
114 /* #ifndef APP-NVUE */
115 display: block;
116 /* #endif */
117 position: absolute;
118 top: 0;
119 width: $drawer-width;
120 bottom: 0;
121 background-color: $uni-bg-color;
122 transition: transform 0.3s ease;
123 }
124
125 .uni-drawer--left {
126 left: 0;
127 /* #ifdef APP-NVUE */
128 transform: translateX(-$drawer-width);
129 /* #endif */
130 /* #ifndef APP-NVUE */
131 transform: translateX(-100%);
132 /* #endif */
133 }
134
135 .uni-drawer--right {
136 right: 0;
137 /* #ifdef APP-NVUE */
138 transform: translateX($drawer-width);
139 /* #endif */
140 /* #ifndef APP-NVUE */
141 transform: translateX(100%);
142 /* #endif */
143 }
144
145 .uni-drawer__content--visible {
146 transform: translateX(0px);
147 }
148
149
150 .uni-drawer__mask {
151 /* #ifndef APP-NVUE */
152 display: block;
153 /* #endif */
154 opacity: 0;
155 position: absolute;
156 top: 0;
157 left: 0;
158 bottom: 0;
159 right: 0;
160 background-color: $uni-bg-color-mask;
161 transition: opacity 0.3s;
162 }
163
164 .uni-drawer__mask--visible {
165 /* #ifndef APP-NVUE */
166 display: block;
167 /* #endif */
168 opacity: 1;
169 }
170 </style>
171
src/hybrid/html/local.html
File was created 1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <title>本地网页</title>
7 <style type="text/css">
8 .btn {
9 display: block;
10 margin: 20px auto;
11 padding: 5px;
12 background-color: #007aff;
13 border: 0;
14 color: #ffffff;
15 height: 40px;
16 width: 200px;
17 }
18
19 .btn-red {
20 background-color: #dd524d;
21 }
22
23 .btn-yellow {
24 background-color: #f0ad4e;
25 }
26
27 .desc {
28 padding: 10px;
29 color: #999999;
30 }
31 </style>
32 </head>
33 <body>
34 <p class="desc">web-view 组件加载本地 html 示例,仅在 App 环境下生效。点击下列按钮,跳转至其它页面。</p>
35 <div class="btn-list">
36 <button class="btn" type="button" data-action="navigateTo">navigateTo</button>
37 <button class="btn" type="button" data-action="redirectTo">redirectTo</button>
38 <button class="btn" type="button" data-action="navigateBack">navigateBack</button>
39 <button class="btn" type="button" data-action="reLaunch">reLaunch</button>
40 <button class="btn" type="button" data-action="switchTab">switchTab</button>
41 </div>
42 <p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p>
43 <div class="btn-list">
44 <button class="btn btn-red" type="button" id="postMessage">postMessage</button>
45 </div>
46 <!-- uni 的 SDK -->
47 <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
48 <script type="text/javascript">
49 document.addEventListener('UniAppJSBridgeReady', function() {
50 document.querySelector('.btn-list').addEventListener('click', function(evt) {
51 var target = evt.target;
52 if (target.tagName === 'BUTTON') {
53 var action = target.getAttribute('data-action');
54 switch (action) {
55 case 'switchTab':
56 uni.switchTab({
57 url: '/pages/tabBar/API/API'
58 });
59 break;
60 case 'reLaunch':
61 uni.reLaunch({
62 url: '/pages/tabBar/API/API'
63 });
64 break;
65 case 'navigateBack':
66 uni.navigateBack({
67 delta: 1
68 });
69 break;
70 default:
71 uni[action]({
72 url: '/pages/component/button/button'
73 });
74 break;
75 }
76 }
77 });
78 document.querySelector("#postMessage").addEventListener('click', function() {
79 uni.postMessage({
80 data: {
81 action: 'message'
82 }
83 });
84 })
85 });
86 </script>
87 </body>
88 </html>
89
File was created 1 import Vue from 'vue'
2 import App from './App'
3
4 Vue.config.productionTip = false
5
6 App.mpType = 'app'
7
8 const app = new Vue({
9 ...App
10 })
11 app.$mount()
12
src/manifest.json
File was created 1 {
2 "name" : "gulu-vue",
3 "appid" : "",
4 "description" : "",
5 "versionName" : "1.0.0",
6 "versionCode" : "100",
7 "transformPx" : false,
8 /* 5+App特有相关 */
9 "app-plus" : {
10 "usingComponents" : true,
11 "nvueCompiler" : "uni-app",
12 "compilerVersion" : 3,
13 "splashscreen" : {
14 "alwaysShowBeforeRender" : true,
15 "waiting" : true,
16 "autoclose" : true,
17 "delay" : 0
18 },
19 /* 模块配置 */
20 "modules" : {},
21 /* 应用发布信息 */
22 "distribute" : {
23 /* android打包配置 */
24 "android" : {
25 "permissions" : [
26 "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
27 "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
28 "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
29 "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
30 "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
31 "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
32 "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
33 "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
34 "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
35 "<uses-permission android:name=\"android.permission.CAMERA\"/>",
36 "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
37 "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
38 "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
39 "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
40 "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
41 "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
42 "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
43 "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
44 "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
45 "<uses-feature android:name=\"android.hardware.camera\"/>",
46 "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
47 "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
48 ]
49 },
50 /* ios打包配置 */
51 "ios" : {},
52 /* SDK配置 */
53 "sdkConfigs" : {}
54 }
55 },
56 /* 快应用特有相关 */
57 "quickapp" : {},
58 /* 小程序特有相关 */
59 "mp-weixin" : {
60 "appid" : "",
61 "setting" : {
62 "urlCheck" : false
63 },
64 "usingComponents" : true
65 },
66 "mp-alipay" : {
67 "usingComponents" : true
68 },
69 "mp-baidu" : {
70 "usingComponents" : true
71 },
72 "mp-toutiao" : {
73 "usingComponents" : true
74 }
75 }
76
File was created 1 {
2 "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
3 {
4 "path": "pages/index/index",
5 "style": {
6 "navigationBarTitleText": "商城一览"
7 }
8 },
9 {
10 "path": "pages/cart/cart",
11 "style": {
12 "navigationBarTitleText": "购物车"
13 }
14 },
15 {
16 "path": "pages/user/user",
17 "style": {
18 "navigationBarTitleText": "我的"
19 }
20 }
21 ],
22 "globalStyle": {
23 "navigationBarTextStyle": "black",
24 "navigationBarTitleText": "uni-app",
25 "navigationBarBackgroundColor": "#F8F8F8",
26 "backgroundColor": "#F8F8F8"
27 },
28 "tabBar": {
29 "color": "#C0C4CC",
30 "selectedColor": "#fa436a",
31 "borderStyle": "black",
32 "backgroundColor": "#ffffff",
33 "list": [{
34 "pagePath": "pages/index/index",
35 "iconPath": "static/tab-home.png",
36 "selectedIconPath": "static/tab-home-current.png",
37 "text": "首页"
38 },
39 {
40 "pagePath": "pages/cart/cart",
41 "iconPath": "static/tab-cart.png",
42 "selectedIconPath": "static/tab-cart-current.png",
43 "text": "购物车"
44 },
45 {
46 "pagePath": "pages/user/user",
47 "iconPath": "static/tab-my.png",
48 "selectedIconPath": "static/tab-my-current.png",
49 "text": "我的"
50 }
51 ]
52 }
53 }
54
src/pages/cart/cart.vue
File was created 1 <template>
2 <view class="content">
3 <image class="logo" src="/static/logo.png"></image>
4 <view class="text-area">
5 <text class="title">{{title}}</text>
6 </view>
7 </view>
8 </template>
9
10 <script>
11 export default {
12 data() {
13 return {
14 title: 'Hello'
15 }
16 },
17 onLoad() {
18
19 },
20 methods: {
21
22 }
23 }
24 </script>
25
26 <style>
27 .content {
28 display: flex;
29 flex-direction: column;
30 align-items: center;
31 justify-content: center;
32 }
33
34 .logo {
35 height: 200rpx;
36 width: 200rpx;
37 margin-top: 200rpx;
38 margin-left: auto;
39 margin-right: auto;
40 margin-bottom: 50rpx;
41 }
42
43 .text-area {
44 display: flex;
45 justify-content: center;
46 }
47
48 .title {
49 font-size: 36rpx;
50 color: #8f8f94;
51 }
52 </style>
53
src/pages/index/index.vue
File was created 1 <template>
2 <view class="content">
3 <view class="header">
4 <!-- 搜索-->
5 <view class="searchBar">
6 <icon class="searchIcon" type="search" size="14"></icon>
7 <input class="searchIpt" placeholder="老花镜" confirm-type="search"/>
8 </view>
9
10 <!-- 筛选栏-->
11 <view class="screenBar">
12 <view v-for="item in screenItems" :key="item.current" @click="onClickItem(item.current)" >
13 <view class="screenItem" v-bind:class="{ active: current === item.current }" v-if="item.current === 2" @click="dropDown">
14 {{ item.text }}<icon type="info" size="14"></icon>
15 </view>
16 <view class="screenItem" v-bind:class="{ active: current === item.current }" v-if="item.current === 4" @click="showDrawer('showRight')">
17 {{ item.text }}<icon type="info" size="14"></icon>
18 </view>
19 <view v-if="item.current !== 2&&item.current!==4">
20 <view class="screenItem" v-bind:class="{ active: current === item.current }">{{ item.text }}</view>
21 </view>
22 </view>
23 </view>
24 </view>
25 <uni-drawer ref="showRight" mask="true" maskClick=true mode="right" :width="320" @change="change($event,'showRight')">
26 <view class="close">
27 <view @click="closeDrawer('showRight')"><text class="word-btn-white">关闭</text></view>
28 </view>
29 </uni-drawer>
30
31
32
33 <!-- 筛选菜单-->
34 <view class="content-wrap">
35 <view>
36 <HMfilterDropdown :filterData="filterData" :defaultSelected ="filterDropdownValue" :updateMenuName="true" @confirm="confirm" dataFormat="Object"></HMfilterDropdown>
37 <!-- 占位 -->
38 <view class="place"></view>
39 <!-- 商品列表 -->
40 <view class="goods-list">
41 <view class="product-list">
42 <view class="product" v-for="(goods) in goodsList" :key="goods.goods_id" @tap="toGoods(goods)">
43 <image mode="widthFix" :src="goods.img"></image>
44 <view class="name">{{goods.name}}</view>
45 <view class="info">
46 <view class="price">{{goods.price}}</view>
47 <view class="slogan">{{goods.slogan}}</view>
48 </view>
49 </view>
50 </view>
51 <view class="loading-text">{{loadingText}}</view>
52 </view>
53
54 </view>
55 </view>
56 </view>
57 </template>
58
59 <script>
60 import uniDrawer from "@/components/uni-drawer/uni-drawer.vue";
61 import HMfilterDropdown from "../../components/HM-filterDropdown/HM-filterDropdown.vue";
62 import data from '@/common/data.js';//筛选菜单数据
63 export default {
64 components: {
65 uniDrawer,
66 'HMfilterDropdown':HMfilterDropdown
67 },
68 data() {
69 return {
70 screenItems: [
71 {current:0,text:'全部',hasIcon:false},
72 {current:1,text:'销量',hasIcon:false},
73 {current:2,text:'价格',hasIcon:true},
74 {current:3,text:'折扣',hasIcon:false},
75 {current:4,text:'筛选',hasIcon:true},
76 ],
77 current: 0,
78 showRight: false,
79 indexArr:'',
80 valueArr:'',
81 //商品数据
82 goodsList:[
83 { goods_id: 0, img: '/static/img/goods/p1.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
84 { goods_id: 1, img: '/static/img/goods/p2.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
85 { goods_id: 2, img: '/static/img/goods/p3.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
86 { goods_id: 3, img: '/static/img/goods/p4.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
87 { goods_id: 4, img: '/static/img/goods/p5.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
88 { goods_id: 5, img: '/static/img/goods/p6.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
89 { goods_id: 6, img: '/static/img/goods/p7.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
90 { goods_id: 7, img: '/static/img/goods/p8.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
91 { goods_id: 8, img: '/static/img/goods/p9.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' },
92 { goods_id: 9, img: '/static/img/goods/p10.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' }
93 ],
94 loadingText:"正在加载...",
95 filterDropdownValue:[],
96 filterData:[]
97 }
98 },
99 filters: {
100   outData(value) {
101     return JSON.stringify(value);
102   }
103 },
104 onLoad: function () {
105 //定时器模拟ajax异步请求数据
106 setTimeout(()=>{
107 //传入defaultSelected的结构不能错,错了就报错运行异常。 不选中的项目传入null
108 this.filterDropdownValue = [
109 [1,1,0], //第0个菜单选中 一级菜单的第1项,二级菜单的第1项,三级菜单的第3项
110 [null,null], //第1个菜单选中 都不选中
111 [1], //第2个菜单选中 一级菜单的第1项
112 [[0],[1,2,7],[1,0]], //筛选菜单选中 第一个筛选的第0项,第二个筛选的第1,2,7项,第三个筛选的第1,0项
113 [[0],[1],[1]], //单选菜单选中 第一个筛选的第0项,第二个筛选的第1项,第三个筛选的第1项
114 ];
115 this.filterData = data;
116 },100);
117 //模拟ajax请求子菜单数据。
118 // setTimeout(()=>{
119 //this.filterData[1].submenu[0].submenu = [{"name": "附近","value": "附近"},{"name": "1km","value": "1km"},{"name": "2km","value": "2km"},{"name": "3km","value": "3km"},{"name": "4km","value": "4km"},{"name": "5km","value": "5km"}];
120 // },5000)
121 },
122 methods: {
123 showDrawer(e) {
124 this.$refs[e].open()
125 },
126 closeDrawer(e) {
127 this.$refs[e].close()
128 },
129 change(e, type) {
130 this[type] = e
131 },
132 onClickItem(e) {
133 if (this.current !== e) {
134 this.current = e;
135 }
136 },
137 dropDown(){
138 console.log('下拉')
139 },
140 //接收菜单结果
141 confirm(e){
142 this.indexArr = e.index;
143 this.valueArr = e.value;
144 return;
145 console.log('修改菜单');
146 this.filterData[4].submenu[1] = {
147 "name": "项目2",
148 "submenu": [
149
150 ]
151 }
152 }
153 },
154 onNavigationBarButtonTap(e) {
155 this.showRight = !this.showRight
156 },
157 //上拉加载,
158 onReachBottom(){
159 console.log('到底加载')
160 let len = this.goodsList.length;
161 if(len>=30){
162 this.loadingText="~~到底了~~";
163 return false;
164 }else{
165 this.loadingText="正在加载...";
166 }
167 let end_goods_id = this.goodsList[len-1].goods_id;
168 for(let i=1;i<=10;i++){
169 let goods_id = end_goods_id+i;
170 let p = { goods_id: goods_id, img: '/static/img/goods/p'+(goods_id%10==0?10:goods_id%10)+'.jpg', name: '商品名称', price: '¥168', slogan:'1235人付款' };
171 this.goodsList.push(p);
172 }
173 },
174 }
175 </script>
176
177 <style lang="scss">
178 .content {
179 display: flex;
180 flex-direction: column;
181 align-items: center;
182 justify-content: center;
183 background-color: #F7F6F6;
184 }
185 .header{
186 display: flex;
187 flex-direction: column;
188 align-items: center;
189 justify-content: center;
190 background-color: #F7F6F6;
191 height:178rpx ;
192 width: 100%;
193 z-index: 999;
194 position: fixed;
195 top: 0;
196 }
197 .searchBar {
198 width: 670rpx;
199 display: flex;
200 position: fixed;
201 top: 0;
202 justify-content: center;
203 align-items: center;
204 box-sizing: border-box;
205 padding: 0rpx 16rpx;
206 border: 1px solid #FF6B4A;
207 border-radius: 8rpx;
208 background-color: #ffffff;
209 }
210
211 .searchIpt {
212 height: 68rpx;
213 width: 670rpx;
214 padding: 16rpx;
215 font-size: 28rpx;
216 box-sizing: border-box;
217 }
218 .screenBar{
219 position: fixed;
220 top: 68rpx;
221 width: 670rpx;
222 height: 110rpx;
223 display: flex;
224 flex-direction: row;
225 justify-content: space-between;
226 align-items: center;
227 color: #333333;
228 font-size: 32rpx;
229 }
230 .active{
231 color: #FF6B4A;
232 }
233 .screenItem{
234 display: flex;
235 justify-content: center;
236 align-items: center;
237 }
238 .content-wrap{
239 width: 100%;
240 background-color: #FFFFFF;
241 }
242
243 .HMfilterDropdown{
244 position: fixed;
245 top: 178rpx !important;
246 }
247 .place{
248 background-color: #ffffff;
249 height: 266rpx;
250 }
251 .goods-list{
252 padding-top: 10px;
253 .loading-text{
254 width: 100%;
255 display: flex;
256 justify-content: center;
257 align-items: center;
258 height: 30px;
259 color: #979797;
260 font-size: 12px;
261 }
262 .product-list{
263 width: 92%;
264 padding: 0 4% 3vw 4%;
265 display: flex;
266 justify-content: space-between;
267 flex-wrap: wrap;
268 .product{
269 width: 48%;
270 border-radius: 10px;
271 background-color: #fff;
272 margin: 0 0 7px 0;
273 box-shadow: 0 3px 12px rgba(0,0,0,0.1);
274 image{
275 width: 100%;
276 border-radius: 10px 10px 0 0;
277 }
278 .name{
279 width: 92%;
280 padding: 5px 4%;
281 display: -webkit-box;
282 -webkit-box-orient: vertical;
283 -webkit-line-clamp: 2;
284 text-align: justify;
285 overflow: hidden;
286 font-size: 15px;
287 }
288 .info{
289 display: flex;
290 justify-content: space-between;
291 align-items: flex-end;
292 width: 92%;
293 padding: 5px 4% 5px 4%;
294 .price{
295 color: #e65339;
296 font-size: 15px;
297 font-weight: 600;
298 }
299 .slogan{
300 color: #807c87;
301 font-size: 12px;
302 }
303 }
304 }
305 }
306 }
307
308 </style>
309
src/pages/user/user.vue
File was created 1 <template>
2 <view class="content">
3 <image class="logo" src="/static/logo.png"></image>
4 <view class="text-area">
5 <text class="title">{{title}}</text>
6 </view>
7 </view>
8 </template>
9
10 <script>
11 export default {
12 data() {
13 return {
14 title: 'Hello'
15 }
16 },
17 onLoad() {
18
19 },
20 methods: {
21
22 }
23 }
24 </script>
25
26 <style>
27 .content {
28 display: flex;
29 flex-direction: column;
30 align-items: center;
31 justify-content: center;
32 }
33
34 .logo {
35 height: 200rpx;
36 width: 200rpx;
37 margin-top: 200rpx;
38 margin-left: auto;
39 margin-right: auto;
40 margin-bottom: 50rpx;
41 }
42
43 .text-area {
44 display: flex;
45 justify-content: center;
46 }
47
48 .title {
49 font-size: 36rpx;
50 color: #8f8f94;
51 }
52 </style>
53
src/platforms/app-plus/feedback/feedback.vue
File was created 1 <template>
2 <view class="page">
3 <view class='feedback-title'>
4 <text>问题和意见</text>
5 <text class="feedback-quick" @tap="chooseMsg">快速键入</text>
6 </view>
7 <view class="feedback-body">
8 <textarea placeholder="请详细描述你的问题和意见..." v-model="sendDate.content" class="feedback-textare"></textarea>
9 </view>
10 <view class='feedback-title'>
11 <text>图片(选填,提供问题截图,总大小10M以下)</text>
12 </view>
13 <view class="feedback-body feedback-uploader">
14 <view class="uni-uploader">
15 <view class="uni-uploader-head">
16 <view class="uni-uploader-title">点击预览图片</view>
17 <view class="uni-uploader-info">{{imageList.length}}/8</view>
18 </view>
19 <view class="uni-uploader-body">
20 <view class="uni-uploader__files">
21 <block v-for="(image,index) in imageList" :key="index">
22 <view class="uni-uploader__file" style="position: relative;">
23 <image class="uni-uploader__img" :src="image" @tap="previewImage(index)"></image>
24 <view class="close-view" @click="close(index)">x</view>
25 </view>
26 </block>
27 <view class="uni-uploader__input-box" v-show="imageList.length < 8">
28 <view class="uni-uploader__input" @tap="chooseImg"></view>
29 </view>
30 </view>
31 </view>
32 </view>
33 </view>
34 <view class='feedback-title'>
35 <text>QQ/邮箱</text>
36 </view>
37 <view class="feedback-body">
38 <input class="feedback-input" v-model="sendDate.contact" placeholder="(选填,方便我们联系你 )" />
39 </view>
40 <view class='feedback-title feedback-star-view'>
41 <text>应用评分</text>
42 <view class="feedback-star-view">
43 <text class="feedback-star" v-for="(value,key) in stars" :key="key" :class="key < sendDate.score ? 'active' : ''"
44 @tap="chooseStar(value)"></text>
45 </view>
46 </view>
47 <button type="default" class="feedback-submit" @tap="send">提交</button>
48 <view class='feedback-title'>
49 <text>用户反馈的结果可在app打包后于DCloud开发者中心查看</text>
50 </view>
51 </view>
52 </template>
53
54 <script>
55 export default {
56 data() {
57 return {
58 msgContents: ["界面显示错乱", "启动缓慢,卡出翔了", "UI无法直视,丑哭了", "偶发性崩溃"],
59 stars: [1, 2, 3, 4, 5],
60 imageList: [],
61 sendDate: {
62 score: 0,
63 content: "",
64 contact: ""
65 }
66 }
67 },
68 onLoad() {
69 let deviceInfo = {
70 appid: plus.runtime.appid,
71 imei: plus.device.imei, //设备标识
72 p: plus.os.name === "Android" ? "a" : "i", //平台类型,i表示iOS平台,a表示Android平台。
73 md: plus.device.model, //设备型号
74 app_version: plus.runtime.version,
75 plus_version: plus.runtime.innerVersion, //基座版本号
76 os: plus.os.version,
77 net: "" + plus.networkinfo.getCurrentType()
78 }
79 this.sendDate = Object.assign(deviceInfo, this.sendDate);
80 },
81 methods: {
82 close(e) {
83 this.imageList.splice(e, 1);
84 },
85 chooseMsg() { //快速输入
86 uni.showActionSheet({
87 itemList: this.msgContents,
88 success: (res) => {
89 this.sendDate.content = this.msgContents[res.tapIndex];
90 }
91 })
92 },
93 chooseImg() { //选择图片
94 uni.chooseImage({
95 sourceType: ["camera", "album"],
96 sizeType: "compressed",
97 count: 8 - this.imageList.length,
98 success: (res) => {
99 this.imageList = this.imageList.concat(res.tempFilePaths);
100 }
101 })
102 },
103 chooseStar(e) { //点击评星
104 this.sendDate.score = e;
105 },
106 previewImage(index) { //预览图片
107 uni.previewImage({
108 urls: this.imageList,
109 current: this.imageList[index]
110 });
111 },
112 send() { //发送反馈
113 console.log(JSON.stringify(this.sendDate));
114 if (this.imageList.length === 0) {
115 uni.showModal({
116 content: '至少选择一张图片',
117 showCancel: false
118 })
119 return
120 }
121 if (this.sendDate.content.length === 0) {
122 uni.showModal({
123 content: '请输入问题和意见',
124 showCancel: false
125 })
126 return
127 }
128 uni.showLoading({
129 title: '上传中...'
130 })
131 let imgs = this.imageList.map((value, index) => {
132 return {
133 name: "image" + index,
134 uri: value
135 }
136 })
137 uni.uploadFile({
138 url: "https://service.dcloud.net.cn/feedback",
139 files: imgs,
140 formData: this.sendDate,
141 success: (res) => {
142 if (typeof res.data === 'string') {
143 res.data = JSON.parse(res.data)
144 }
145 if (res.statusCode === 200 && res.data && res.data.ret === 0) {
146 uni.showModal({
147 content: '反馈成功',
148 showCancel: false
149 })
150 this.imageList = [];
151 this.sendDate = {
152 score: 0,
153 content: "",
154 contact: ""
155 }
156 } else if (res.statusCode !== 200){
157 uni.showModal({
158 content: '反馈失败,错误码为:' + res.statusCode,
159 showCancel: false
160 })
161 } else {
162 uni.showModal({
163 content: '反馈失败',
164 showCancel: false
165 })
166 }
167 },
168 fail: (res) => {
169 console.log(JSON.stringify(res))
170 },
171 complete() {
172 uni.hideLoading()
173 }
174 });
175 }
176 }
177 }
178 </script>
179
180 <style>
181 page {
182 background-color: #EFEFF4;
183 }
184
185 .input-view {
186 font-size: 28rpx;
187 }
188
189 .close-view {
190 text-align: center;
191 line-height: 14px;
192 height: 16px;
193 width: 16px;
194 border-radius: 50%;
195 background: #FF5053;
196 color: #FFFFFF;
197 position: absolute;
198 top: -6px;
199 right: -4px;
200 font-size: 12px;
201 }
202 </style>
203
src/platforms/app-plus/orientation/orientation.vue
File was created 1 <template>
2 <view>
3 <page-head :title="title"></page-head>
4 <view class="uni-padding-wrap uni-common-mt">
5 <view class="uni-btn-v">
6 <button type="primary" @tap="getOrient">获取设备的方向信息</button>
7 <button type="primary" @tap="watchOrient">监听设备的方向变化</button>
8 <button type="primary" @tap="watchStop">停止监听</button>
9 </view>
10 <view class="uni-textarea">
11 <textarea :value="value" />
12 </view>
13 </view>
14 </view>
15 </template>
16 <script>
17 var id = null
18 export default {
19 data() {
20 return {
21 title: 'orientation',
22 value: ''
23 }
24 },
25 methods: {
26 getOrient: function () {
27 var that = this;
28 plus.orientation.getCurrentOrientation(function (o) {
29 that.value = "alpha:" + o.alpha + "\nbeta:" + o.beta + "\ngamma:" + o.gamma;
30 }, function (e) {
31 console.log("获取失败:" + e.message);
32 });
33 },
34 watchOrient: function () {
35 var that = this;
36 if (id) {
37 return;
38 }
39 id = plus.orientation.watchOrientation(function (o) {
40 that.value = "监听设备方向变化信息\n" + "alpha:" + o.alpha + "\nbeta:" + o.beta + "\ngamma:" + o.gamma;
41 }, function (e) {
42 plus.orientation.clearWatch(id);
43 id = null;
44 console.log("监听失败:" + e.message);
45 });
46 },
47 watchStop: function () {
48 if (id) {
49 plus.orientation.clearWatch(id);
50 id = null;
51 } else {
52 console.log("没有监听设备方向变化");
53 }
54 }
55 }
56 }
57 </script>
58
59 <style>
60
61 </style>
src/platforms/app-plus/proximity/proximity.vue
File was created 1 <template>
2 <view>
3 <page-head :title="title"></page-head>
4 <view class="uni-padding-wrap uni-common-mt">
5 <view class="uni-hello-text">
6 手机顶部听筒处有传感器监听距离手机屏幕的障碍物,覆盖该传感器会触发本事件变化
7 </view>
8 <view class="uni-btn-v uni-common-mt">
9 <button type="primary" @tap="getProximity">获取距离传感器信息</button>
10 <button type="primary" @tap="watchProximity">监听距离传感器变化</button>
11 <button type="primary" @tap="watchStop">停止监听</button>
12 </view>
13 <view class="uni-textarea uni-common-mt">
14 <textarea :value="value" />
15 </view>
16 </view>
17 </view>
18 </template>
19 <script>
20 var id = null
21 var bright = null
22 export default {
23 data() {
24 return {
25 title: 'proximity',
26 value: ''
27 }
28 },
29 methods: {
30 getProximity: function () {
31 var that = this;
32 plus.proximity.getCurrentProximity(function (d) {
33 that.value = "距离为:" + d;
34 }, function (e) {
35 that.value = "获取失败:" + e.message;
36 });
37 },
38 watchProximity: function () {
39 var that = this;
40 if (id) {
41 return;
42 }
43 bright = plus.screen.getBrightness();
44 id = plus.proximity.watchProximity(function (d) {
45 that.value = "距离变化:" + d;
46 plus.screen.setBrightness((d < 1) ? 0.01 : bright);
47 }, function (e) {
48 plus.proximity.clearWatch(id);
49 id = null;
50 that.value = "监听失败:" + e.message;
51 });
52 },
53 watchStop: function () {
54 var that = this;
55 if (id) {
56 that.value = "停止监听设备距离传感器信息";
57 plus.proximity.clearWatch(id);
58 id = null;
59 } else {
60 that.value = "没有监听设备距离传感器";
61 }
62 }
63 }
64 }
65 </script>
66
67 <style>
68
69 </style>
70
src/platforms/app-plus/push/push.vue
File was created 1 <template>
2 <view>
3 <page-head :title="title"></page-head>
4 <view class="uni-padding-wrap" v-if="provider[0]">
5 <view class="uni-btn-v uni-common-mt">
6 <button type="primary" @tap="openPush">开启push</button>
7 <button type="primary" @tap="closePush">关闭push</button>
8 <button type="primary" @tap="listenTranMsg">监听透传数据</button>
9 <button type="primary" @tap="removeTranMsg">移除监听透传数据</button>
10 </view>
11 <view class="uni-btn-v uni-common-mt">
12 <button type="primary" @tap="requireTranMsg">发送"透传数据"消息</button>
13 </view>
14 <view class="uni-title uni-common-mt">透传内容:</view>
15 <view class="uni-textarea">
16 <textarea v-model="tranMsg" />
17 </view>
18 </view>
19 </view>
20 </template>
21 <script>
22 export default {
23 data() {
24 return {
25 title: 'push',
26 provider: [],
27 pushServer: 'http://demo.dcloud.net.cn/push/?',
28 tranMsg:''
29 }
30 },
31 onLoad: function () {
32 uni.getProvider({
33 service: "push",
34 success: (e) => {
35 console.log("success", e);
36 this.provider = e.provider;
37 },
38 fail: (e) => {
39 console.log("获取推送通道失败", e);
40 }
41 });
42 },
43 onUnload:function(){
44 this.tranMsg = ''
45 },
46 methods: {
47 openPush() {
48 uni.subscribePush({
49 provider: this.provider[0],
50 success: (e) => {
51 uni.showToast({
52 title: "已开启push接收"
53 })
54 }
55 })
56 },
57 closePush() {
58 uni.unsubscribePush({
59 provider: this.provider[0],
60 success: (e) => {
61 uni.showToast({
62 title: "已关闭push接收"
63 })
64 }
65 })
66 },
67 listenTranMsg() {
68 uni.onPush({
69 provider: this.provider[0],
70 success: (e) => {
71 uni.showToast({
72 title: "开始监听透传数据"
73 })
74 },
75 callback: (e) => {
76 uni.showToast({
77 title: "接收到透传数据"
78 });
79
80 this.tranMsg = JSON.stringify(e.data);
81 }
82 })
83 },
84 removeTranMsg() {
85 uni.offPush({
86 provider: this.provider[0],
87 success: (e) => {
88 console.log("移除监听透传数据");
89 uni.showToast({
90 title: "移除监听透传数据"
91 })
92 }
93 })
94 },
95 requireTranMsg() { //请求‘透传数据’推送消息
96 var inf = plus.push.getClientInfo();
97 var url = this.pushServer + 'type=tran&appid=' + encodeURIComponent(plus.runtime.appid);
98 inf.id && (url += '&id=' + inf.id);
99 url += ('&cid=' + encodeURIComponent(inf.clientid));
100 if (plus.os.name == 'iOS') {
101 url += ('&token=' + encodeURIComponent(inf.token));
102 }
103 url += ('&title=' + encodeURIComponent('Hello uniapp'));
104 url += ('&content=' + encodeURIComponent('带透传数据推送通知!'));
105 if(plus.os.name === 'iOS'){
106 url += ('&payload=' + encodeURIComponent('{"title":"Hello uniapp Test","content":"test content"}'));
107 }else{
108 url += ('&payload=' + encodeURIComponent('\'{"title":"Hello uniapp Test","content":"test content"}\''));
109 }
110 url += ('&version=' + encodeURIComponent(plus.runtime.version));
111 plus.runtime.openURL(url);
112 }
113 }
114 }
115 </script>
116
117 <style>
118
119 </style>
120
121
src/platforms/app-plus/shake/shake.vue
File was created 1 <template>
2 <view class="root" :style="{backgroundImage:'url('+img+')'}">
3 <view :class="[show ? 'up' : '','shake-up']">
4 <image mode="aspectFit" src="https://img-cdn-qiniu.dcloud.net.cn/uniapp/shake/shakeup.png"></image>
5 </view>
6 <view :class="[show ? 'down' : '','shake-down']">
7 <image mode="aspectFit" src="https://img-cdn-qiniu.dcloud.net.cn/uniapp/shake/shakedown.png"></image>
8 </view>
9 </view>
10 </template>
11 <script>
12 export default {
13 data() {
14 return {
15 img: 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/shake/1.jpg',
16 show: false,
17 isOpened: false
18 }
19 },
20 onLoad: function () {
21 this.music = uni.createInnerAudioContext();
22 this.music.src = 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/shake/shake.wav';
23
24 let index = 1,
25 t = null;
26 uni.onAccelerometerChange((res) => {
27 if (Math.abs(res.x) + Math.abs(res.y) + Math.abs(res.z) > 20 && !this.show && this.isOpened) {
28 this.music.play();
29 setTimeout(() => {
30 index++;
31 if (index > 4) {
32 index = 1
33 }
34 this.img = 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/shake/' + index + '.jpg';
35 }, 2000);
36 this.show = true;
37 if (t) {
38 clearTimeout(t);
39 }
40 t = setTimeout(() => {
41 t = null;
42 this.show = false;
43 }, 600)
44 }
45 })
46 },
47 onShow() {
48 this.isOpened = true;
49 },
50 onUnload() {
51 this.show = false;
52 this.isOpened = false;
53 uni.stopAccelerometer();
54 this.music.destroy();
55 }
56 }
57 </script>
58
59 <style>
60 .root {
61 height: 100%;
62 display: flex;
63 flex-direction: column;
64 background-position: center center;
65 background-repeat: no-repeat;
66 }
67
68 .shake-up,
69 .shake-down {
70 height: 50%;
71 overflow: hidden;
72 transition: all .5s ease-in-out;
73 -webkit-transition: all .5s ease-in-out;
74 background: #333;
75 }
76
77 .up {
78 transform: translateY(-50%);
79 -webkit-transform: translateY(-50%);
80 }
81
82 .down {
83 transform: translateY(50%);
84 -webkit-transform: translateY(50%);
85 }
86
87 image {
88 height: 100%;
89 width: 100%;
90 }
91 </style>
92
src/platforms/app-plus/speech/speech.vue
File was created 1 <template>
2 <view>
3 <page-head :title="title"></page-head>
4 <view class="uni-padding-wrap uni-common-mt">
5 <view class="uni-textarea">
6 <textarea :value="value" placeholder="语音识别内容展示区域" disabled />
7 </view>
8 <view class="uni-common-mt uni-btn-v">
9 <button type="primary" @tap="startRecognize">开始语音识别</button>
10 <button type="primary" @tap="startRecognizeEnglish">开始语音识别(英语)</button>
11 </view>
12 </view>
13 </view>
14 </template>
15 <script>
16 import permision from "@/common/permission.js"
17 export default {
18 data() {
19 return {
20 title: 'speech',
21 value: ''
22 }
23 },
24 onUnload(){
25 this.value = ""
26 },
27 methods: {
28 async startRecognize () {
29 // #ifdef APP-PLUS
30 let status = await this.checkPermission();
31 if (status !== 1) {
32 return;
33 }
34 // #endif
35
36 // TODO ios 在没有请求过权限之前无法得知是否有相关权限,这种状态下需要直接调用语音,会弹出正在识别的toast
37 var options = {};
38 var that = this;
39 options.engine = 'baidu';
40 that.value = "";
41 plus.speech.startRecognize(options, function (s) {
42 console.log(s);
43 that.value += s;
44 }, function (e) {
45 console.log("语音识别失败:" + e.message);
46 });
47 },
48 async startRecognizeEnglish () {
49 // #ifdef APP-PLUS
50 let status = await this.checkPermission();
51 if (status !== 1) {
52 return;
53 }
54 // #endif
55
56 // TODO ios 在没有请求过权限之前无法得知是否有相关权限,这种状态下需要直接调用语音,会弹出正在识别的toast
57 var options = {};
58 var that = this;
59 options.engine = 'baidu';
60 options.lang = 'en-us';
61 that.value = "";
62 plus.speech.startRecognize(options, function (s) {
63 console.log(s);
64 that.value += s;
65 }, function (e) {
66 console.log("语音识别失败:" + e.message);
67 });
68 }
69 // #ifdef APP-PLUS
70 ,
71 async checkPermission() {
72 let status = permision.isIOS ? await permision.requestIOS('record') :
73 await permision.requestAndroid('android.permission.RECORD_AUDIO');
74
75 if (status === null || status === 1) {
76 status = 1;
77 } else if (status === 2) {
78 uni.showModal({
79 content: "系统麦克风已关闭",
80 confirmText: "确定",
81 showCancel: false,
82 success: function(res) {
83 }
84 })
85 } else {
86 uni.showModal({
87 content: "需要麦克风权限",
88 confirmText: "设置",
89 success: function(res) {
90 if (res.confirm) {
91 permision.gotoAppSetting();
92 }
93 }
94 })
95 }
96 return status;
97 }
98 // #endif
99 }
100 }
101 </script>
102
103 <style>
104
105 </style>
106
src/static/img/goods/p1.jpg

11.3 KB

src/static/img/goods/p10.jpg

22.6 KB

src/static/img/goods/p2.jpg

16.3 KB

src/static/img/goods/p3.jpg

15 KB

src/static/img/goods/p4.jpg

6.55 KB

src/static/img/goods/p5.jpg

29.6 KB

src/static/img/goods/p6.jpg

6.25 KB

src/static/img/goods/p7.jpg

20.1 KB

src/static/img/goods/p8.jpg

20.4 KB

src/static/img/goods/p9.jpg

24.1 KB

src/static/logo.png

3.93 KB

src/static/tab-cart-current.png

2.89 KB

src/static/tab-cart.png

2.85 KB

src/static/tab-home-current.png

3.97 KB

src/static/tab-home.png

3.87 KB

src/static/tab-my-current.png

1.31 KB

src/static/tab-my.png

2.89 KB

src/store/index.js
File was created 1 import Vue from 'vue'
2 import Vuex from 'vuex'
3
4 Vue.use(Vuex)
5
6 const store = new Vuex.Store({
7 state: {
8 hasLogin: false,
9 loginProvider: "",
10 openid: null,
11 testvuex:false,
12 colorIndex: 0,
13 colorList: ['#FF0000','#00FF00','#0000FF']
14 },
15 mutations: {
16 login(state, provider) {
17 state.hasLogin = true;
18 state.loginProvider = provider;
19 },
20 logout(state) {
21 state.hasLogin = false
22 state.openid = null
23 },
24 setOpenid(state, openid) {
25 state.openid = openid
26 },
27 setTestTrue(state){
28 state.testvuex = true
29 },
30 setTestFalse(state){
31 state.testvuex = false
32 },
33 setColorIndex(state,index){
34 state.colorIndex = index
35 }
36 },
37 getters:{
38 currentColor(state){
39 return state.colorList[state.colorIndex]
40 }
41 },
42 actions: {
43 // lazy loading openid
44 getUserOpenId: async function ({
45 commit,
46 state
47 }) {
48 return await new Promise((resolve, reject) => {
49 if (state.openid) {
50 resolve(state.openid)
51 } else {
52 uni.login({
53 success: (data) => {
54 commit('login')
55 setTimeout(function () { //模拟异步请求服务器获取 openid
56 const openid = '123456789'
57 console.log('uni.request mock openid[' + openid + ']');
58 commit('setOpenid', openid)
59 resolve(openid)
60 }, 1000)
61 },
62 fail: (err) => {
63 console.log('uni.login 接口调用失败,将无法正常使用开放接口等服务', err)
64 reject(err)
65 }
66 })
67 }
68 })
69 }
70 }
71 })
72
73 export default store
74
src/template.h5.html
File was created 1 <!DOCTYPE html>
2 <html lang="zh-CN">
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7 <title>
8 <%= htmlWebpackPlugin.options.title %>
9 </title>
10 <!-- 正式发布的时候使用,开发期间不启用。↓ -->
11 <!-- <script src="/h5/touch-emulator.js"></script>
12 <script>
13 TouchEmulator();
14 if (document.documentElement.clientWidth > 1024) {
15 window.location.href = '/h5/pcguide.html#'+location.pathname+location.search;
16 }
17 </script>
18 <style>
19 ::-webkit-scrollbar{
20 display: none;
21 }
22 </style>
23 <script>
24 var _hmt = _hmt || [];
25 (function() {
26 var hm = document.createElement("script");
27 hm.src = "https://hm.baidu.com/hm.js?";// 百度统计key
28 var s = document.getElementsByTagName("script")[0];
29 s.parentNode.insertBefore(hm, s);
30 })();
31 </script> -->
32 <!-- 正式发布的时候使用,开发期间不启用。↑ -->
33 <script>
34 document.addEventListener('DOMContentLoaded', function() {
35 document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
36 })
37 </script>
38 <link rel="stylesheet" href="<%= BASE_URL %>static/index.css" />
39 </head>
40 <body>
41 <!-- 该文件为 H5 平台的模板 HTML,并非应用入口。 -->
42 <!-- 请勿在此文件编写页面代码或直接运行此文件。 -->
43 <!-- 详见文档:https://uniapp.dcloud.io/collocation/manifest?id=h5-template -->
44 <noscript>
45 <strong>Please enable JavaScript to continue.</strong>
46 </noscript>
47 <div id="app"></div>
48 <!-- built files will be auto injected -->
49 <script>
50 /*BAIDU_STAT*/
51 </script>
52 </body>
53 </html>
54
File was created 1 /**
2 * 这里是uni-app内置的常用样式变量
3 *
4 * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
5 * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
6 *
7 */
8
9 /**
10 * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
11 *
12 * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
13 */
14
15 /* 颜色变量 */
16
17 /* 行为相关颜色 */
18 $uni-color-primary: #007aff;
19 $uni-color-success: #4cd964;
20 $uni-color-warning: #f0ad4e;
21 $uni-color-error: #dd524d;
22
23 /* 文字基本颜色 */
24 $uni-text-color:#333;//基本色
25 $uni-text-color-inverse:#fff;//反色
26 $uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
27 $uni-text-color-placeholder: #808080;
28 $uni-text-color-disable:#c0c0c0;
29
30 /* 背景颜色 */
31 $uni-bg-color:#ffffff;
32 $uni-bg-color-grey:#f8f8f8;
33 $uni-bg-color-hover:#f1f1f1;//点击状态颜色
34 $uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
35
36 /* 边框颜色 */
37 $uni-border-color:#c8c7cc;
38
39 /* 尺寸变量 */
40
41 /* 文字尺寸 */
42 $uni-font-size-sm:24rpx;
43 $uni-font-size-base:28rpx;
44 $uni-font-size-lg:32rpx;
45
46 /* 图片尺寸 */
47 $uni-img-size-sm:40rpx;
48 $uni-img-size-base:52rpx;
49 $uni-img-size-lg:80rpx;
50
51 /* Border Radius */
52 $uni-border-radius-sm: 4rpx;
53 $uni-border-radius-base: 6rpx;
54 $uni-border-radius-lg: 12rpx;
55 $uni-border-radius-circle: 50%;
56
57 /* 水平间距 */
58 $uni-spacing-row-sm: 10px;
59 $uni-spacing-row-base: 20rpx;
60 $uni-spacing-row-lg: 30rpx;
61
62 /* 垂直间距 */
63 $uni-spacing-col-sm: 8rpx;
64 $uni-spacing-col-base: 16rpx;
65 $uni-spacing-col-lg: 24rpx;
66
67 /* 透明度 */
68 $uni-opacity-disabled: 0.3; // 组件禁用态的透明度
69
70 /* 文章场景相关 */
71 $uni-color-title: #2C405A; // 文章标题颜色
72 $uni-font-size-title:40rpx;
73 $uni-color-subtitle: #555555; // 二级标题颜色
74 $uni-font-size-subtitle:36rpx;
75 $uni-color-paragraph: #3F536E; // 文章段落颜色
76 $uni-font-size-paragraph:30rpx;
src/wxcomponents/vant/button/index.d.ts
File was created 1 export {};
2
src/wxcomponents/vant/button/index.js
File was created 1 import { VantComponent } from '../common/component';
2 import { button } from '../mixins/button';
3 import { openType } from '../mixins/open-type';
4 VantComponent({
5 mixins: [button, openType],
6 classes: ['hover-class', 'loading-class'],
7 data: {
8 style: ''
9 },
10 props: {
11 icon: String,
12 plain: Boolean,
13 block: Boolean,
14 round: Boolean,
15 square: Boolean,
16 loading: Boolean,
17 hairline: Boolean,
18 disabled: Boolean,
19 loadingText: String,
20 customStyle: String,
21 loadingType: {
22 type: String,
23 value: 'circular'
24 },
25 type: {
26 type: String,
27 value: 'default'
28 },
29 size: {
30 type: String,
31 value: 'normal'
32 },
33 loadingSize: {
34 type: String,
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 }
59 }
60 },
61 methods: {
62 onClick() {
63 if (!this.data.disabled && !this.data.loading) {
64 this.$emit('click');
65 }
66 }
67 }
68 });
69
src/wxcomponents/vant/button/index.json
File was created 1 {
2 "component": true,
3 "usingComponents": {
4 "van-icon": "../icon/index",
5 "van-loading": "../loading/index"
6 }
7 }
8
src/wxcomponents/vant/button/index.vue
File was created 1 <template>
2 <uni-shadow-root class="vant-button-index"><button :id="id" :class="'custom-class '+(utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]))+' '+(hairline ? 'van-hairline--surround' : '')" hover-class="van-button--active hover-class" :lang="lang" :style="(style)+' '+(customStyle)" :open-type="openType" :business-id="businessId" :session-from="sessionFrom" :send-message-title="sendMessageTitle" :send-message-path="sendMessagePath" :send-message-img="sendMessageImg" :show-message-card="showMessageCard" :app-parameter="appParameter" :aria-label="ariaLabel" @click="onClick" @getuserinfo="bindGetUserInfo" @contact="bindContact" @getphonenumber="bindGetPhoneNumber" @error="bindError" @launchapp="bindLaunchApp" @opensetting="bindOpenSetting">
3 <block v-if="loading">
4 <van-loading custom-class="loading-class" :size="loadingSize" :type="loadingType" :color="type === 'default' ? '#c9c9c9' : 'white'"></van-loading>
5 <view v-if="loadingText" class="van-button__loading-text">
6 {{ loadingText }}
7 </view>
8 </block>
9 <block v-else>
10 <van-icon v-if="icon" size="1.2em" :name="icon" class="van-button__icon" custom-style="line-height: inherit;"></van-icon>
11 <view class="van-button__text">
12 <slot></slot>
13 </view>
14 </block>
15 </button></uni-shadow-root>
16 </template>
17 <wxs src="../wxs/utils.wxs" module="utils"></wxs>
18 <script>
19 import VanIcon from '../icon/index.vue'
20 import VanLoading from '../loading/index.vue'
21 global['__wxVueOptions'] = {components:{'van-icon': VanIcon,'van-loading': VanLoading}}
22
23 global['__wxRoute'] = 'vant/button/index'
24 import { VantComponent } from '../common/component';
25 import { button } from '../mixins/button';
26 import { openType } from '../mixins/open-type';
27 VantComponent({
28 mixins: [button, openType],
29 classes: ['hover-class', 'loading-class'],
30 data: {
31 style: ''
32 },
33 props: {
34 icon: String,
35 plain: Boolean,
36 block: Boolean,
37 round: Boolean,
38 square: Boolean,
39 loading: Boolean,
40 hairline: Boolean,
41 disabled: Boolean,
42 loadingText: String,
43 customStyle: String,
44 loadingType: {
45 type: String,
46 value: 'circular'
47 },
48 type: {
49 type: String,
50 value: 'default'
51 },
52 size: {
53 type: String,
54 value: 'normal'
55 },
56 loadingSize: {
57 type: String,
58 value: '20px'
59 },
60 color: {
61 type: String,
62 observer(color) {
63 let style = '';
64 if (color) {
65 style += `color: ${this.data.plain ? color : 'white'};`;
66 if (!this.data.plain) {
67 // Use background instead of backgroundColor to make linear-gradient work
68 style += `background: ${color};`;
69 }
70 // hide border when color is linear-gradient
71 if (color.indexOf('gradient') !== -1) {
72 style += 'border: 0;';
73 }
74 else {
75 style += `border-color: ${color};`;
76 }
77 }
78 if (style !== this.data.style) {
79 this.setData({ style });
80 }
81 }
82 }
83 },
84 methods: {
85 onClick() {
86 if (!this.data.disabled && !this.data.loading) {
87 this.$emit('click');
88 }
89 }
90 }
91 });
92 export default global['__wxComponents']['vant/button/index']
93 </script>
94 <style platform="mp-weixin">
95 @import '../common/index.css';.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}
96 </style>
src/wxcomponents/vant/button/index.wxml
File was created 1 <wxs src="../wxs/utils.wxs" module="utils" />
2
3 <button
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' : '' }}"
6 hover-class="van-button--active hover-class"
7 lang="{{ lang }}"
8 style="{{ style }} {{ customStyle }}"
9 open-type="{{ openType }}"
10 business-id="{{ businessId }}"
11 session-from="{{ sessionFrom }}"
12 send-message-title="{{ sendMessageTitle }}"
13 send-message-path="{{ sendMessagePath }}"
14 send-message-img="{{ sendMessageImg }}"
15 show-message-card="{{ showMessageCard }}"
16 app-parameter="{{ appParameter }}"
17 aria-label="{{ ariaLabel }}"
18 bindtap="onClick"
19 bindgetuserinfo="bindGetUserInfo"
20 bindcontact="bindContact"
21 bindgetphonenumber="bindGetPhoneNumber"
22 binderror="bindError"
23 bindlaunchapp="bindLaunchApp"
24 bindopensetting="bindOpenSetting"
25 >
26 <block wx:if="{{ loading }}">
27 <van-loading
28 custom-class="loading-class"
29 size="{{ loadingSize }}"
30 type="{{ loadingType }}"
31 color="{{ type === 'default' ? '#c9c9c9' : 'white' }}"
32 />
33 <view
34 wx:if="{{ loadingText }}"
35 class="van-button__loading-text"
36 >
37 {{ loadingText }}
38 </view>
39 </block>
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>
52 </button>
53
src/wxcomponents/vant/button/index.wxss
File was created 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}
src/wxcomponents/vant/common/color.d.ts
File was created 1 export declare const RED = "#ee0a24";
2 export declare const BLUE = "#1989fa";
3 export declare const WHITE = "#fff";
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";
8
src/wxcomponents/vant/common/color.js
File was created 1 export const RED = '#ee0a24';
2 export const BLUE = '#1989fa';
3 export const WHITE = '#fff';
4 export const GREEN = '#07c160';
5 export const ORANGE = '#ff976a';
6 export const GRAY = '#323233';
7 export const GRAY_DARK = '#969799';
8
src/wxcomponents/vant/common/component.d.ts
File was created 1 import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
2 declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
3 export { VantComponent };
4
src/wxcomponents/vant/common/component.js
File was created 1 import { basic } from '../mixins/basic';
2 import { observe } from '../mixins/observer/index';
3 function mapKeys(source, target, map) {
4 Object.keys(map).forEach(key => {
5 if (source[key]) {
6 target[map[key]] = source[key];
7 }
8 });
9 }
10 function VantComponent(vantOptions = {}) {
11 const options = {};
12 mapKeys(vantOptions, options, {
13 data: 'data',
14 props: 'properties',
15 mixins: 'behaviors',
16 methods: 'methods',
17 beforeCreate: 'created',
18 created: 'attached',
19 mounted: 'ready',
20 relations: 'relations',
21 destroyed: 'detached',
22 classes: 'externalClasses'
23 });
24 const { relation } = vantOptions;
25 if (relation) {
26 options.relations = Object.assign(options.relations || {}, {
27 [`../${relation.name}/index`]: relation
28 });
29 }
30 // add default externalClasses
31 options.externalClasses = options.externalClasses || [];
32 options.externalClasses.push('custom-class');
33 // add default behaviors
34 options.behaviors = options.behaviors || [];
35 options.behaviors.push(basic);
36 // map field to form-field behavior
37 if (vantOptions.field) {
38 options.behaviors.push('wx://form-field');
39 }
40 // add default options
41 options.options = {
42 multipleSlots: true,
43 addGlobalClass: true
44 };
45 observe(vantOptions, options);
46 Component(options);
47 }
48 export { VantComponent };
49
src/wxcomponents/vant/common/index.css
File was created 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}
src/wxcomponents/vant/common/index.wxss
File was created 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}
src/wxcomponents/vant/common/style/clearfix.css
File was created 1 .van-clearfix:after{display:table;clear:both;content:""}
src/wxcomponents/vant/common/style/clearfix.wxss
File was created 1 .van-clearfix:after{display:table;clear:both;content:""}
src/wxcomponents/vant/common/style/ellipsis.css
File was created 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}
src/wxcomponents/vant/common/style/ellipsis.wxss
File was created 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}
src/wxcomponents/vant/common/style/hairline.css
File was created 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}
src/wxcomponents/vant/common/style/hairline.wxss
File was created 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}
src/wxcomponents/vant/common/style/mixins/clearfix.css
src/wxcomponents/vant/common/style/mixins/clearfix.wxss
src/wxcomponents/vant/common/style/mixins/ellipsis.css
src/wxcomponents/vant/common/style/mixins/ellipsis.wxss
src/wxcomponents/vant/common/style/mixins/hairline.css
src/wxcomponents/vant/common/style/mixins/hairline.wxss
src/wxcomponents/vant/common/style/theme.css
src/wxcomponents/vant/common/style/theme.wxss
src/wxcomponents/vant/common/style/var.css
src/wxcomponents/vant/common/style/var.wxss
src/wxcomponents/vant/common/utils.d.ts
File was created 1 /// <reference types="miniprogram-api-typings" />
2 export declare function isDef(value: any): boolean;
3 export declare function isObj(x: any): boolean;
4 export declare function isNumber(value: any): boolean;
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;
9
src/wxcomponents/vant/common/utils.js
File was created 1 export function isDef(value) {
2 return value !== undefined && value !== null;
3 }
4 export function isObj(x) {
5 const type = typeof x;
6 return x !== null && (type === 'object' || type === 'function');
7 }
8 export function isNumber(value) {
9 return /^\d+(\.\d+)?$/.test(value);
10 }
11 export function range(num, min, max) {
12 return Math.min(Math.max(num, min), max);
13 }
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 }
33
src/wxcomponents/vant/icon/index.d.ts
File was created 1 export {};
2
src/wxcomponents/vant/icon/index.js
File was created 1 import { VantComponent } from '../common/component';
2 import { addUnit } from '../common/utils';
3 VantComponent({
4 props: {
5 dot: Boolean,
6 info: null,
7 size: {
8 type: null,
9 observer: 'setSizeWithUnit'
10 },
11 color: String,
12 customStyle: String,
13 classPrefix: {
14 type: String,
15 value: 'van-icon'
16 },
17 name: {
18 type: String,
19 observer(val) {
20 this.setData({
21 isImageName: val.indexOf('/') !== -1
22 });
23 }
24 }
25 },
26 data: {
27 sizeWithUnit: null,
28 },
29 methods: {
30 onClick() {
31 this.$emit('click');
32 },
33 setSizeWithUnit(size) {
34 this.setData({
35 sizeWithUnit: addUnit(size)
36 });
37 }
38 }
39 });
40
src/wxcomponents/vant/icon/index.json
File was created 1 {
2 "component": true,
3 "usingComponents": {
4 "van-info": "../info/index"
5 }
6 }
7
src/wxcomponents/vant/icon/index.vue
File was created 1 <template>
2 <uni-shadow-root class="vant-icon-index"><view :class="'custom-class '+(classPrefix)+' '+(isImageName ? 'van-icon--image' : classPrefix + '-' + name)" :style="(color ? 'color: ' + color + ';' : '')+(size ? 'font-size: ' + sizeWithUnit + ';' : '')+(customStyle)" @click="onClick">
3 <van-info v-if="info !== null || dot" :dot="dot" :info="info" custom-class="van-icon__info"></van-info>
4 <image v-if="isImageName" :src="name" mode="aspectFit" class="van-icon__image"></image>
5 </view></uni-shadow-root>
6 </template>
7
8 <script>
9 import VanInfo from '../info/index.vue'
10 global['__wxVueOptions'] = {components:{'van-info': VanInfo}}
11
12 global['__wxRoute'] = 'vant/icon/index'
13 import { VantComponent } from '../common/component';
14 import { addUnit } from '../common/utils';
15 VantComponent({
16 props: {
17 dot: Boolean,
18 info: null,
19 size: {
20 type: null,
21 observer: 'setSizeWithUnit'
22 },
23 color: String,
24 customStyle: String,
25 classPrefix: {
26 type: String,
27 value: 'van-icon'
28 },
29 name: {
30 type: String,
31 observer(val) {
32 this.setData({
33 isImageName: val.indexOf('/') !== -1
34 });
35 }
36 }
37 },
38 data: {
39 sizeWithUnit: null,
40 },
41 methods: {
42 onClick() {
43 this.$emit('click');
44 },
45 setSizeWithUnit(size) {
46 this.setData({
47 sizeWithUnit: addUnit(size)
48 });
49 }
50 }
51 });
52 export default global['__wxComponents']['vant/icon/index']
53 </script>
54 <style platform="mp-weixin">
55 @import '../common/index.css';
56
57 @font-face {
58 font-weight: 400;
59 font-family: vant-icon;
60 font-style: normal;
61 font-display: auto;
62 src: url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff2) format("woff2"), url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff) format("woff"), url(https://img.yzcdn.cn/vant/vant-icon-d3825a.ttf) format("truetype")
63 }
64
65 .van-icon {
66 position: relative;
67 font: normal normal normal 14px/1 vant-icon;
68 font-size: inherit;
69 text-rendering: auto;
70 -webkit-font-smoothing: antialiased
71 }
72
73 .van-icon,
74 .van-icon:before {
75 display: inline-block
76 }
77
78 .van-icon-add-o:before {
79 content: "\F000"
80 }
81
82 .van-icon-add-square:before {
83 content: "\F001"
84 }
85
86 .van-icon-add:before {
87 content: "\F002"
88 }
89
90 .van-icon-after-sale:before {
91 content: "\F003"
92 }
93
94 .van-icon-aim:before {
95 content: "\F004"
96 }
97
98 .van-icon-alipay:before {
99 content: "\F005"
100 }
101
102 .van-icon-apps-o:before {
103 content: "\F006"
104 }
105
106 .van-icon-arrow-down:before {
107 content: "\F007"
108 }
109
110 .van-icon-arrow-left:before {
111 content: "\F008"
112 }
113
114 .van-icon-arrow-up:before {
115 content: "\F009"
116 }
117
118 .van-icon-arrow:before {
119 content: "\F00A"
120 }
121
122 .van-icon-ascending:before {
123 content: "\F00B"
124 }
125
126 .van-icon-audio:before {
127 content: "\F00C"
128 }
129
130 .van-icon-award-o:before {
131 content: "\F00D"
132 }
133
134 .van-icon-award:before {
135 content: "\F00E"
136 }
137
138 .van-icon-bag-o:before {
139 content: "\F00F"
140 }
141
142 .van-icon-bag:before {
143 content: "\F010"
144 }
145
146 .van-icon-balance-list-o:before {
147 content: "\F011"
148 }
149
150 .van-icon-balance-list:before {
151 content: "\F012"
152 }
153
154 .van-icon-balance-o:before {
155 content: "\F013"
156 }
157
158 .van-icon-balance-pay:before {
159 content: "\F014"
160 }
161
162 .van-icon-bar-chart-o:before {
163 content: "\F015"
164 }
165
166 .van-icon-bars:before {
167 content: "\F016"
168 }
169
170 .van-icon-bell:before {
171 content: "\F017"
172 }
173
174 .van-icon-bill-o:before {
175 content: "\F018"
176 }
177
178 .van-icon-bill:before {
179 content: "\F019"
180 }
181
182 .van-icon-birthday-cake-o:before {
183 content: "\F01A"
184 }
185
186 .van-icon-bookmark-o:before {
187 content: "\F01B"
188 }
189
190 .van-icon-bookmark:before {
191 content: "\F01C"
192 }
193
194 .van-icon-browsing-history-o:before {
195 content: "\F01D"
196 }
197
198 .van-icon-browsing-history:before {
199 content: "\F01E"
200 }
201
202 .van-icon-brush-o:before {
203 content: "\F01F"
204 }
205
206 .van-icon-bulb-o:before {
207 content: "\F020"
208 }
209
210 .van-icon-bullhorn-o:before {
211 content: "\F021"
212 }
213
214 .van-icon-calender-o:before {
215 content: "\F022"
216 }
217
218 .van-icon-card:before {
219 content: "\F023"
220 }
221
222 .van-icon-cart-circle-o:before {
223 content: "\F024"
224 }
225
226 .van-icon-cart-circle:before {
227 content: "\F025"
228 }
229
230 .van-icon-cart-o:before {
231 content: "\F026"
232 }
233
234 .van-icon-cart:before {
235 content: "\F027"
236 }
237
238 .van-icon-cash-back-record:before {
239 content: "\F028"
240 }
241
242 .van-icon-cash-on-deliver:before {
243 content: "\F029"
244 }
245
246 .van-icon-cashier-o:before {
247 content: "\F02A"
248 }
249
250 .van-icon-certificate:before {
251 content: "\F02B"
252 }
253
254 .van-icon-chart-trending-o:before {
255 content: "\F02C"
256 }
257
258 .van-icon-chat-o:before {
259 content: "\F02D"
260 }
261
262 .van-icon-chat:before {
263 content: "\F02E"
264 }
265
266 .van-icon-checked:before {
267 content: "\F02F"
268 }
269
270 .van-icon-circle:before {
271 content: "\F030"
272 }
273
274 .van-icon-clear:before {
275 content: "\F031"
276 }
277
278 .van-icon-clock-o:before {
279 content: "\F032"
280 }
281
282 .van-icon-clock:before {
283 content: "\F033"
284 }
285
286 .van-icon-close:before {
287 content: "\F034"
288 }
289
290 .van-icon-closed-eye:before {
291 content: "\F035"
292 }
293
294 .van-icon-cluster-o:before {
295 content: "\F036"
296 }
297
298 .van-icon-cluster:before {
299 content: "\F037"
300 }
301
302 .van-icon-column:before {
303 content: "\F038"
304 }
305
306 .van-icon-comment-circle-o:before {
307 content: "\F039"
308 }
309
310 .van-icon-comment-circle:before {
311 content: "\F03A"
312 }
313
314 .van-icon-comment-o:before {
315 content: "\F03B"
316 }
317
318 .van-icon-comment:before {
319 content: "\F03C"
320 }
321
322 .van-icon-completed:before {
323 content: "\F03D"
324 }
325
326 .van-icon-contact:before {
327 content: "\F03E"
328 }
329
330 .van-icon-coupon-o:before {
331 content: "\F03F"
332 }
333
334 .van-icon-coupon:before {
335 content: "\F040"
336 }
337
338 .van-icon-credit-pay:before {
339 content: "\F041"
340 }
341
342 .van-icon-cross:before {
343 content: "\F042"
344 }
345
346 .van-icon-debit-pay:before {
347 content: "\F043"
348 }
349
350 .van-icon-delete:before {
351 content: "\F044"
352 }
353
354 .van-icon-descending:before {
355 content: "\F045"
356 }
357
358 .van-icon-description:before {
359 content: "\F046"
360 }
361
362 .van-icon-desktop-o:before {
363 content: "\F047"
364 }
365
366 .van-icon-diamond-o:before {
367 content: "\F048"
368 }
369
370 .van-icon-diamond:before {
371 content: "\F049"
372 }
373
374 .van-icon-discount:before {
375 content: "\F04A"
376 }
377
378 .van-icon-down:before {
379 content: "\F04B"
380 }
381
382 .van-icon-ecard-pay:before {
383 content: "\F04C"
384 }
385
386 .van-icon-edit:before {
387 content: "\F04D"
388 }
389
390 .van-icon-ellipsis:before {
391 content: "\F04E"
392 }
393
394 .van-icon-empty:before {
395 content: "\F04F"
396 }
397
398 .van-icon-envelop-o:before {
399 content: "\F050"
400 }
401
402 .van-icon-exchange:before {
403 content: "\F051"
404 }
405
406 .van-icon-expand-o:before {
407 content: "\F052"
408 }
409
410 .van-icon-expand:before {
411 content: "\F053"
412 }
413
414 .van-icon-eye-o:before {
415 content: "\F054"
416 }
417
418 .van-icon-eye:before {
419 content: "\F055"
420 }
421
422 .van-icon-fail:before {
423 content: "\F056"
424 }
425
426 .van-icon-failure:before {
427 content: "\F057"
428 }
429
430 .van-icon-filter-o:before {
431 content: "\F058"
432 }
433
434 .van-icon-fire-o:before {
435 content: "\F059"
436 }
437
438 .van-icon-fire:before {
439 content: "\F05A"
440 }
441
442 .van-icon-flag-o:before {
443 content: "\F05B"
444 }
445
446 .van-icon-flower-o:before {
447 content: "\F05C"
448 }
449
450 .van-icon-free-postage:before {
451 content: "\F05D"
452 }
453
454 .van-icon-friends-o:before {
455 content: "\F05E"
456 }
457
458 .van-icon-friends:before {
459 content: "\F05F"
460 }
461
462 .van-icon-gem-o:before {
463 content: "\F060"
464 }
465
466 .van-icon-gem:before {
467 content: "\F061"
468 }
469
470 .van-icon-gift-card-o:before {
471 content: "\F062"
472 }
473
474 .van-icon-gift-card:before {
475 content: "\F063"
476 }
477
478 .van-icon-gift-o:before {
479 content: "\F064"
480 }
481
482 .van-icon-gift:before {
483 content: "\F065"
484 }
485
486 .van-icon-gold-coin-o:before {
487 content: "\F066"
488 }
489
490 .van-icon-gold-coin:before {
491 content: "\F067"
492 }
493
494 .van-icon-good-job-o:before {
495 content: "\F068"
496 }
497
498 .van-icon-good-job:before {
499 content: "\F069"
500 }
501
502 .van-icon-goods-collect-o:before {
503 content: "\F06A"
504 }
505
506 .van-icon-goods-collect:before {
507 content: "\F06B"
508 }
509
510 .van-icon-graphic:before {
511 content: "\F06C"
512 }
513
514 .van-icon-home-o:before {
515 content: "\F06D"
516 }
517
518 .van-icon-hot-o:before {
519 content: "\F06E"
520 }
521
522 .van-icon-hot-sale-o:before {
523 content: "\F06F"
524 }
525
526 .van-icon-hot-sale:before {
527 content: "\F070"
528 }
529
530 .van-icon-hot:before {
531 content: "\F071"
532 }
533
534 .van-icon-hotel-o:before {
535 content: "\F072"
536 }
537
538 .van-icon-idcard:before {
539 content: "\F073"
540 }
541
542 .van-icon-info-o:before {
543 content: "\F074"
544 }
545
546 .van-icon-info:before {
547 content: "\F075"
548 }
549
550 .van-icon-invition:before {
551 content: "\F076"
552 }
553
554 .van-icon-label-o:before {
555 content: "\F077"
556 }
557
558 .van-icon-label:before {
559 content: "\F078"
560 }
561
562 .van-icon-like-o:before {
563 content: "\F079"
564 }
565
566 .van-icon-like:before {
567 content: "\F07A"
568 }
569
570 .van-icon-live:before {
571 content: "\F07B"
572 }
573
574 .van-icon-location-o:before {
575 content: "\F07C"
576 }
577
578 .van-icon-location:before {
579 content: "\F07D"
580 }
581
582 .van-icon-lock:before {
583 content: "\F07E"
584 }
585
586 .van-icon-logistics:before {
587 content: "\F07F"
588 }
589
590 .van-icon-manager-o:before {
591 content: "\F080"
592 }
593
594 .van-icon-manager:before {
595 content: "\F081"
596 }
597
598 .van-icon-map-marked:before {
599 content: "\F082"
600 }
601
602 .van-icon-medal-o:before {
603 content: "\F083"
604 }
605
606 .van-icon-medal:before {
607 content: "\F084"
608 }
609
610 .van-icon-more-o:before {
611 content: "\F085"
612 }
613
614 .van-icon-more:before {
615 content: "\F086"
616 }
617
618 .van-icon-music-o:before {
619 content: "\F087"
620 }
621
622 .van-icon-music:before {
623 content: "\F088"
624 }
625
626 .van-icon-new-arrival-o:before {
627 content: "\F089"
628 }
629
630 .van-icon-new-arrival:before {
631 content: "\F08A"
632 }
633
634 .van-icon-new-o:before {
635 content: "\F08B"
636 }
637
638 .van-icon-new:before {
639 content: "\F08C"
640 }
641
642 .van-icon-newspaper-o:before {
643 content: "\F08D"
644 }
645
646 .van-icon-notes-o:before {
647 content: "\F08E"
648 }
649
650 .van-icon-orders-o:before {
651 content: "\F08F"
652 }
653
654 .van-icon-other-pay:before {
655 content: "\F090"
656 }
657
658 .van-icon-paid:before {
659 content: "\F091"
660 }
661
662 .van-icon-passed:before {
663 content: "\F092"
664 }
665
666 .van-icon-pause-circle-o:before {
667 content: "\F093"
668 }
669
670 .van-icon-pause-circle:before {
671 content: "\F094"
672 }
673
674 .van-icon-pause:before {
675 content: "\F095"
676 }
677
678 .van-icon-peer-pay:before {
679 content: "\F096"
680 }
681
682 .van-icon-pending-payment:before {
683 content: "\F097"
684 }
685
686 .van-icon-phone-circle-o:before {
687 content: "\F098"
688 }
689
690 .van-icon-phone-circle:before {
691 content: "\F099"
692 }
693
694 .van-icon-phone-o:before {
695 content: "\F09A"
696 }
697
698 .van-icon-phone:before {
699 content: "\F09B"
700 }
701
702 .van-icon-photo-o:before {
703 content: "\F09C"
704 }
705
706 .van-icon-photo:before {
707 content: "\F09D"
708 }
709
710 .van-icon-photograph:before {
711 content: "\F09E"
712 }
713
714 .van-icon-play-circle-o:before {
715 content: "\F09F"
716 }
717
718 .van-icon-play-circle:before {
719 content: "\F0A0"
720 }
721
722 .van-icon-play:before {
723 content: "\F0A1"
724 }
725
726 .van-icon-plus:before {
727 content: "\F0A2"
728 }
729
730 .van-icon-point-gift-o:before {
731 content: "\F0A3"
732 }
733
734 .van-icon-point-gift:before {
735 content: "\F0A4"
736 }
737
738 .van-icon-points:before {
739 content: "\F0A5"
740 }
741
742 .van-icon-printer:before {
743 content: "\F0A6"
744 }
745
746 .van-icon-qr-invalid:before {
747 content: "\F0A7"
748 }
749
750 .van-icon-qr:before {
751 content: "\F0A8"
752 }
753
754 .van-icon-question-o:before {
755 content: "\F0A9"
756 }
757
758 .van-icon-question:before {
759 content: "\F0AA"
760 }
761
762 .van-icon-records:before {
763 content: "\F0AB"
764 }
765
766 .van-icon-refund-o:before {
767 content: "\F0AC"
768 }
769
770 .van-icon-replay:before {
771 content: "\F0AD"
772 }
773
774 .van-icon-scan:before {
775 content: "\F0AE"
776 }
777
778 .van-icon-search:before {
779 content: "\F0AF"
780 }
781
782 .van-icon-send-gift-o:before {
783 content: "\F0B0"
784 }
785
786 .van-icon-send-gift:before {
787 content: "\F0B1"
788 }
789
790 .van-icon-service-o:before {
791 content: "\F0B2"
792 }
793
794 .van-icon-service:before {
795 content: "\F0B3"
796 }
797
798 .van-icon-setting-o:before {
799 content: "\F0B4"
800 }
801
802 .van-icon-setting:before {
803 content: "\F0B5"
804 }
805
806 .van-icon-share:before {
807 content: "\F0B6"
808 }
809
810 .van-icon-shop-collect-o:before {
811 content: "\F0B7"
812 }
813
814 .van-icon-shop-collect:before {
815 content: "\F0B8"
816 }
817
818 .van-icon-shop-o:before {
819 content: "\F0B9"
820 }
821
822 .van-icon-shop:before {
823 content: "\F0BA"
824 }
825
826 .van-icon-shopping-cart-o:before {
827 content: "\F0BB"
828 }
829
830 .van-icon-shopping-cart:before {
831 content: "\F0BC"
832 }
833
834 .van-icon-shrink:before {
835 content: "\F0BD"
836 }
837
838 .van-icon-sign:before {
839 content: "\F0BE"
840 }
841
842 .van-icon-smile-comment-o:before {
843 content: "\F0BF"
844 }
845
846 .van-icon-smile-comment:before {
847 content: "\F0C0"
848 }
849
850 .van-icon-smile-o:before {
851 content: "\F0C1"
852 }
853
854 .van-icon-smile:before {
855 content: "\F0C2"
856 }
857
858 .van-icon-star-o:before {
859 content: "\F0C3"
860 }
861
862 .van-icon-star:before {
863 content: "\F0C4"
864 }
865
866 .van-icon-stop-circle-o:before {
867 content: "\F0C5"
868 }
869
870 .van-icon-stop-circle:before {
871 content: "\F0C6"
872 }
873
874 .van-icon-stop:before {
875 content: "\F0C7"
876 }
877
878 .van-icon-success:before {
879 content: "\F0C8"
880 }
881
882 .van-icon-thumb-circle-o:before {
883 content: "\F0C9"
884 }
885
886 .van-icon-thumb-circle:before {
887 content: "\F0CA"
888 }
889
890 .van-icon-todo-list-o:before {
891 content: "\F0CB"
892 }
893
894 .van-icon-todo-list:before {
895 content: "\F0CC"
896 }
897
898 .van-icon-tosend:before {
899 content: "\F0CD"
900 }
901
902 .van-icon-tv-o:before {
903 content: "\F0CE"
904 }
905
906 .van-icon-umbrella-circle:before {
907 content: "\F0CF"
908 }
909
910 .van-icon-underway-o:before {
911 content: "\F0D0"
912 }
913
914 .van-icon-underway:before {
915 content: "\F0D1"
916 }
917
918 .van-icon-upgrade:before {
919 content: "\F0D2"
920 }
921
922 .van-icon-user-circle-o:before {
923 content: "\F0D3"
924 }
925
926 .van-icon-user-o:before {
927 content: "\F0D4"
928 }
929
930 .van-icon-video-o:before {
931 content: "\F0D5"
932 }
933
934 .van-icon-video:before {
935 content: "\F0D6"
936 }
937
938 .van-icon-vip-card-o:before {
939 content: "\F0D7"
940 }
941
942 .van-icon-vip-card:before {
943 content: "\F0D8"
944 }
945
946 .van-icon-volume-o:before {
947 content: "\F0D9"
948 }
949
950 .van-icon-volume:before {
951 content: "\F0DA"
952 }
953
954 .van-icon-wap-home-o:before {
955 content: "\F0DB"
956 }
957
958 .van-icon-wap-home:before {
959 content: "\F0DC"
960 }
961
962 .van-icon-wap-nav:before {
963 content: "\F0DD"
964 }
965
966 .van-icon-warn-o:before {
967 content: "\F0DE"
968 }
969
970 .van-icon-warning-o:before {
971 content: "\F0DF"
972 }
973
974 .van-icon-warning:before {
975 content: "\F0E0"
976 }
977
978 .van-icon-weapp-nav:before {
979 content: "\F0E1"
980 }
981
982 .van-icon-wechat:before {
983 content: "\F0E2"
984 }
985
986 .van-icon-youzan-shield:before {
987 content: "\F0E3"
988 }
989
990 .vant-icon-index {
991 display: -webkit-inline-flex;
992 display: inline-flex;
993 -webkit-align-items: center;
994 align-items: center;
995 -webkit-justify-content: center;
996 justify-content: center
997 }
998
999 .van-icon--image {
1000 width: 1em;
1001 height: 1em
1002 }
1003
1004 .van-icon__image {
1005 width: 100%;
1006 height: 100%
1007 }
1008
1009 .van-icon__info {
1010 z-index: 1
1011 }
1012 </style>
src/wxcomponents/vant/icon/index.wxml
File was created 1 <view
2 class="custom-class {{ classPrefix }} {{ isImageName ? 'van-icon--image' : classPrefix + '-' + name }}"
3 style="{{ color ? 'color: ' + color + ';' : '' }}{{ size ? 'font-size: ' + sizeWithUnit + ';' : '' }}{{ customStyle }}"
4 bind:tap="onClick"
5 >
6 <van-info
7 wx:if="{{ info !== null || dot }}"
8 dot="{{ dot }}"
9 info="{{ info }}"
10 custom-class="van-icon__info"
11 />
12 <image
13 wx:if="{{ isImageName }}"
14 src="{{ name }}"
15 mode="aspectFit"
16 class="van-icon__image"
17 />
18 </view>
19
src/wxcomponents/vant/icon/index.wxss
File was created 1 @import '../common/index.wxss';
2
3 @font-face {
4 font-weight: 400;
5 font-family: vant-icon;
6 font-style: normal;
7 font-display: auto;
8 src: url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff2) format("woff2"), url(https://img.yzcdn.cn/vant/vant-icon-d3825a.woff) format("woff"), url(https://img.yzcdn.cn/vant/vant-icon-d3825a.ttf) format("truetype")
9 }
10
11 .van-icon {
12 position: relative;
13 font: normal normal normal 14px/1 vant-icon;
14 font-size: inherit;
15 text-rendering: auto;
16 -webkit-font-smoothing: antialiased
17 }
18
19 .van-icon,
20 .van-icon:before {
21 display: inline-block
22 }
23
24 .van-icon-add-o:before {
25 content: "\F000"
26 }
27
28 .van-icon-add-square:before {
29 content: "\F001"
30 }
31
32 .van-icon-add:before {
33 content: "\F002"
34 }
35
36 .van-icon-after-sale:before {
37 content: "\F003"
38 }
39
40 .van-icon-aim:before {
41 content: "\F004"
42 }
43
44 .van-icon-alipay:before {
45 content: "\F005"
46 }
47
48 .van-icon-apps-o:before {
49 content: "\F006"
50 }
51
52 .van-icon-arrow-down:before {
53 content: "\F007"
54 }
55
56 .van-icon-arrow-left:before {
57 content: "\F008"
58 }
59
60 .van-icon-arrow-up:before {
61 content: "\F009"
62 }
63
64 .van-icon-arrow:before {
65 content: "\F00A"
66 }
67
68 .van-icon-ascending:before {
69 content: "\F00B"
70 }
71
72 .van-icon-audio:before {
73 content: "\F00C"
74 }
75
76 .van-icon-award-o:before {
77 content: "\F00D"
78 }
79
80 .van-icon-award:before {
81 content: "\F00E"
82 }
83
84 .van-icon-bag-o:before {
85 content: "\F00F"
86 }
87
88 .van-icon-bag:before {
89 content: "\F010"
90 }
91
92 .van-icon-balance-list-o:before {
93 content: "\F011"
94 }
95
96 .van-icon-balance-list:before {
97 content: "\F012"
98 }
99
100 .van-icon-balance-o:before {
101 content: "\F013"
102 }
103
104 .van-icon-balance-pay:before {
105 content: "\F014"
106 }
107
108 .van-icon-bar-chart-o:before {
109 content: "\F015"
110 }
111
112 .van-icon-bars:before {
113 content: "\F016"
114 }
115
116 .van-icon-bell:before {
117 content: "\F017"
118 }
119
120 .van-icon-bill-o:before {
121 content: "\F018"
122 }
123
124 .van-icon-bill:before {
125 content: "\F019"
126 }
127
128 .van-icon-birthday-cake-o:before {
129 content: "\F01A"
130 }
131
132 .van-icon-bookmark-o:before {
133 content: "\F01B"
134 }
135
136 .van-icon-bookmark:before {
137 content: "\F01C"
138 }
139
140 .van-icon-browsing-history-o:before {
141 content: "\F01D"
142 }
143
144 .van-icon-browsing-history:before {
145 content: "\F01E"
146 }
147
148 .van-icon-brush-o:before {
149 content: "\F01F"
150 }
151
152 .van-icon-bulb-o:before {
153 content: "\F020"
154 }
155
156 .van-icon-bullhorn-o:before {
157 content: "\F021"
158 }
159
160 .van-icon-calender-o:before {
161 content: "\F022"
162 }
163
164 .van-icon-card:before {
165 content: "\F023"
166 }
167
168 .van-icon-cart-circle-o:before {
169 content: "\F024"
170 }
171
172 .van-icon-cart-circle:before {
173 content: "\F025"
174 }
175
176 .van-icon-cart-o:before {
177 content: "\F026"
178 }
179
180 .van-icon-cart:before {
181 content: "\F027"
182 }
183
184 .van-icon-cash-back-record:before {
185 content: "\F028"
186 }
187
188 .van-icon-cash-on-deliver:before {
189 content: "\F029"
190 }
191
192 .van-icon-cashier-o:before {
193 content: "\F02A"
194 }
195
196 .van-icon-certificate:before {
197 content: "\F02B"
198 }
199
200 .van-icon-chart-trending-o:before {
201 content: "\F02C"
202 }
203
204 .van-icon-chat-o:before {
205 content: "\F02D"
206 }
207
208 .van-icon-chat:before {
209 content: "\F02E"
210 }
211
212 .van-icon-checked:before {
213 content: "\F02F"
214 }
215
216 .van-icon-circle:before {
217 content: "\F030"
218 }
219
220 .van-icon-clear:before {
221 content: "\F031"
222 }
223
224 .van-icon-clock-o:before {
225 content: "\F032"
226 }
227
228 .van-icon-clock:before {
229 content: "\F033"
230 }
231
232 .van-icon-close:before {
233 content: "\F034"
234 }
235
236 .van-icon-closed-eye:before {
237 content: "\F035"
238 }
239
240 .van-icon-cluster-o:before {
241 content: "\F036"
242 }
243
244 .van-icon-cluster:before {
245 content: "\F037"
246 }
247
248 .van-icon-column:before {
249 content: "\F038"
250 }
251
252 .van-icon-comment-circle-o:before {
253 content: "\F039"
254 }
255
256 .van-icon-comment-circle:before {
257 content: "\F03A"
258 }
259
260 .van-icon-comment-o:before {
261 content: "\F03B"
262 }
263
264 .van-icon-comment:before {
265 content: "\F03C"
266 }
267
268 .van-icon-completed:before {
269 content: "\F03D"
270 }
271
272 .van-icon-contact:before {
273 content: "\F03E"
274 }
275
276 .van-icon-coupon-o:before {
277 content: "\F03F"
278 }
279
280 .van-icon-coupon:before {
281 content: "\F040"
282 }
283
284 .van-icon-credit-pay:before {
285 content: "\F041"
286 }
287
288 .van-icon-cross:before {
289 content: "\F042"
290 }
291
292 .van-icon-debit-pay:before {
293 content: "\F043"
294 }
295
296 .van-icon-delete:before {
297 content: "\F044"
298 }
299
300 .van-icon-descending:before {
301 content: "\F045"
302 }
303
304 .van-icon-description:before {
305 content: "\F046"
306 }
307
308 .van-icon-desktop-o:before {
309 content: "\F047"
310 }
311
312 .van-icon-diamond-o:before {
313 content: "\F048"
314 }
315
316 .van-icon-diamond:before {
317 content: "\F049"
318 }
319
320 .van-icon-discount:before {
321 content: "\F04A"
322 }
323
324 .van-icon-down:before {
325 content: "\F04B"
326 }
327
328 .van-icon-ecard-pay:before {
329 content: "\F04C"
330 }
331
332 .van-icon-edit:before {
333 content: "\F04D"
334 }
335
336 .van-icon-ellipsis:before {
337 content: "\F04E"
338 }
339
340 .van-icon-empty:before {
341 content: "\F04F"
342 }
343
344 .van-icon-envelop-o:before {
345 content: "\F050"
346 }
347
348 .van-icon-exchange:before {
349 content: "\F051"
350 }
351
352 .van-icon-expand-o:before {
353 content: "\F052"
354 }
355
356 .van-icon-expand:before {
357 content: "\F053"
358 }
359
360 .van-icon-eye-o:before {
361 content: "\F054"
362 }
363
364 .van-icon-eye:before {
365 content: "\F055"
366 }
367
368 .van-icon-fail:before {
369 content: "\F056"
370 }
371
372 .van-icon-failure:before {
373 content: "\F057"
374 }
375
376 .van-icon-filter-o:before {
377 content: "\F058"
378 }
379
380 .van-icon-fire-o:before {
381 content: "\F059"
382 }
383
384 .van-icon-fire:before {
385 content: "\F05A"
386 }
387
388 .van-icon-flag-o:before {
389 content: "\F05B"
390 }
391
392 .van-icon-flower-o:before {
393 content: "\F05C"
394 }
395
396 .van-icon-free-postage:before {
397 content: "\F05D"
398 }
399
400 .van-icon-friends-o:before {
401 content: "\F05E"
402 }
403
404 .van-icon-friends:before {
405 content: "\F05F"
406 }
407
408 .van-icon-gem-o:before {
409 content: "\F060"
410 }
411
412 .van-icon-gem:before {
413 content: "\F061"
414 }
415
416 .van-icon-gift-card-o:before {
417 content: "\F062"
418 }
419
420 .van-icon-gift-card:before {
421 content: "\F063"
422 }
423
424 .van-icon-gift-o:before {
425 content: "\F064"
426 }
427
428 .van-icon-gift:before {
429 content: "\F065"
430 }
431
432 .van-icon-gold-coin-o:before {
433 content: "\F066"
434 }
435
436 .van-icon-gold-coin:before {
437 content: "\F067"
438 }
439
440 .van-icon-good-job-o:before {
441 content: "\F068"
442 }
443
444 .van-icon-good-job:before {
445 content: "\F069"
446 }
447
448 .van-icon-goods-collect-o:before {
449 content: "\F06A"
450 }
451
452 .van-icon-goods-collect:before {
453 content: "\F06B"
454 }
455
456 .van-icon-graphic:before {
457 content: "\F06C"
458 }
459
460 .van-icon-home-o:before {
461 content: "\F06D"
462 }
463
464 .van-icon-hot-o:before {
465 content: "\F06E"
466 }
467
468 .van-icon-hot-sale-o:before {
469 content: "\F06F"
470 }
471
472 .van-icon-hot-sale:before {
473 content: "\F070"
474 }
475
476 .van-icon-hot:before {
477 content: "\F071"
478 }
479
480 .van-icon-hotel-o:before {
481 content: "\F072"
482 }
483
484 .van-icon-idcard:before {
485 content: "\F073"
486 }
487
488 .van-icon-info-o:before {
489 content: "\F074"
490 }
491
492 .van-icon-info:before {
493 content: "\F075"
494 }
495
496 .van-icon-invition:before {
497 content: "\F076"
498 }
499
500 .van-icon-label-o:before {
501 content: "\F077"
502 }
503
504 .van-icon-label:before {
505 content: "\F078"
506 }
507
508 .van-icon-like-o:before {
509 content: "\F079"
510 }
511
512 .van-icon-like:before {
513 content: "\F07A"
514 }
515
516 .van-icon-live:before {
517 content: "\F07B"
518 }
519
520 .van-icon-location-o:before {
521 content: "\F07C"
522 }
523
524 .van-icon-location:before {
525 content: "\F07D"
526 }
527
528 .van-icon-lock:before {
529 content: "\F07E"
530 }
531
532 .van-icon-logistics:before {
533 content: "\F07F"
534 }
535
536 .van-icon-manager-o:before {
537 content: "\F080"
538 }
539
540 .van-icon-manager:before {
541 content: "\F081"
542 }
543
544 .van-icon-map-marked:before {
545 content: "\F082"
546 }
547
548 .van-icon-medal-o:before {
549 content: "\F083"
550 }
551
552 .van-icon-medal:before {
553 content: "\F084"
554 }
555
556 .van-icon-more-o:before {
557 content: "\F085"
558 }
559
560 .van-icon-more:before {
561 content: "\F086"
562 }
563
564 .van-icon-music-o:before {
565 content: "\F087"
566 }
567
568 .van-icon-music:before {
569 content: "\F088"
570 }
571
572 .van-icon-new-arrival-o:before {
573 content: "\F089"
574 }
575
576 .van-icon-new-arrival:before {
577 content: "\F08A"
578 }
579
580 .van-icon-new-o:before {
581 content: "\F08B"
582 }
583
584 .van-icon-new:before {
585 content: "\F08C"
586 }
587
588 .van-icon-newspaper-o:before {
589 content: "\F08D"
590 }
591
592 .van-icon-notes-o:before {
593 content: "\F08E"
594 }
595
596 .van-icon-orders-o:before {
597 content: "\F08F"
598 }
599
600 .van-icon-other-pay:before {
601 content: "\F090"
602 }
603
604 .van-icon-paid:before {
605 content: "\F091"
606 }
607
608 .van-icon-passed:before {
609 content: "\F092"
610 }
611
612 .van-icon-pause-circle-o:before {
613 content: "\F093"
614 }
615
616 .van-icon-pause-circle:before {
617 content: "\F094"
618 }
619
620 .van-icon-pause:before {
621 content: "\F095"
622 }
623
624 .van-icon-peer-pay:before {
625 content: "\F096"
626 }
627
628 .van-icon-pending-payment:before {
629 content: "\F097"
630 }
631
632 .van-icon-phone-circle-o:before {
633 content: "\F098"
634 }
635
636 .van-icon-phone-circle:before {
637 content: "\F099"
638 }
639
640 .van-icon-phone-o:before {
641 content: "\F09A"
642 }
643
644 .van-icon-phone:before {
645 content: "\F09B"
646 }
647
648 .van-icon-photo-o:before {
649 content: "\F09C"
650 }
651
652 .van-icon-photo:before {
653 content: "\F09D"
654 }
655
656 .van-icon-photograph:before {
657 content: "\F09E"
658 }
659
660 .van-icon-play-circle-o:before {
661 content: "\F09F"
662 }
663
664 .van-icon-play-circle:before {
665 content: "\F0A0"
666 }
667
668 .van-icon-play:before {
669 content: "\F0A1"
670 }
671
672 .van-icon-plus:before {
673 content: "\F0A2"
674 }
675
676 .van-icon-point-gift-o:before {
677 content: "\F0A3"
678 }
679
680 .van-icon-point-gift:before {
681 content: "\F0A4"
682 }
683
684 .van-icon-points:before {
685 content: "\F0A5"
686 }
687
688 .van-icon-printer:before {
689 content: "\F0A6"
690 }
691
692 .van-icon-qr-invalid:before {
693 content: "\F0A7"
694 }
695
696 .van-icon-qr:before {
697 content: "\F0A8"
698 }
699
700 .van-icon-question-o:before {
701 content: "\F0A9"
702 }
703
704 .van-icon-question:before {
705 content: "\F0AA"
706 }
707
708 .van-icon-records:before {
709 content: "\F0AB"
710 }
711
712 .van-icon-refund-o:before {
713 content: "\F0AC"
714 }
715
716 .van-icon-replay:before {
717 content: "\F0AD"
718 }
719
720 .van-icon-scan:before {
721 content: "\F0AE"
722 }
723
724 .van-icon-search:before {
725 content: "\F0AF"
726 }
727
728 .van-icon-send-gift-o:before {
729 content: "\F0B0"
730 }
731
732 .van-icon-send-gift:before {
733 content: "\F0B1"
734 }
735
736 .van-icon-service-o:before {
737 content: "\F0B2"
738 }
739
740 .van-icon-service:before {
741 content: "\F0B3"
742 }
743
744 .van-icon-setting-o:before {
745 content: "\F0B4"
746 }
747
748 .van-icon-setting:before {
749 content: "\F0B5"
750 }
751
752 .van-icon-share:before {
753 content: "\F0B6"
754 }
755
756 .van-icon-shop-collect-o:before {
757 content: "\F0B7"
758 }
759
760 .van-icon-shop-collect:before {
761 content: "\F0B8"
762 }
763
764 .van-icon-shop-o:before {
765 content: "\F0B9"
766 }
767
768 .van-icon-shop:before {
769 content: "\F0BA"
770 }
771
772 .van-icon-shopping-cart-o:before {
773 content: "\F0BB"
774 }
775
776 .van-icon-shopping-cart:before {
777 content: "\F0BC"
778 }
779
780 .van-icon-shrink:before {
781 content: "\F0BD"
782 }
783
784 .van-icon-sign:before {
785 content: "\F0BE"
786 }
787
788 .van-icon-smile-comment-o:before {
789 content: "\F0BF"
790 }
791
792 .van-icon-smile-comment:before {
793 content: "\F0C0"
794 }
795
796 .van-icon-smile-o:before {
797 content: "\F0C1"
798 }
799
800 .van-icon-smile:before {
801 content: "\F0C2"
802 }
803
804 .van-icon-star-o:before {
805 content: "\F0C3"
806 }
807
808 .van-icon-star:before {
809 content: "\F0C4"
810 }
811
812 .van-icon-stop-circle-o:before {
813 content: "\F0C5"
814 }
815
816 .van-icon-stop-circle:before {
817 content: "\F0C6"
818 }
819
820 .van-icon-stop:before {
821 content: "\F0C7"
822 }
823
824 .van-icon-success:before {
825 content: "\F0C8"
826 }
827
828 .van-icon-thumb-circle-o:before {
829 content: "\F0C9"
830 }
831
832 .van-icon-thumb-circle:before {
833 content: "\F0CA"
834 }
835
836 .van-icon-todo-list-o:before {
837 content: "\F0CB"
838 }
839
840 .van-icon-todo-list:before {
841 content: "\F0CC"
842 }
843
844 .van-icon-tosend:before {
845 content: "\F0CD"
846 }
847
848 .van-icon-tv-o:before {
849 content: "\F0CE"
850 }
851
852 .van-icon-umbrella-circle:before {
853 content: "\F0CF"
854 }
855
856 .van-icon-underway-o:before {
857 content: "\F0D0"
858 }
859
860 .van-icon-underway:before {
861 content: "\F0D1"
862 }
863
864 .van-icon-upgrade:before {
865 content: "\F0D2"
866 }
867
868 .van-icon-user-circle-o:before {
869 content: "\F0D3"
870 }
871
872 .van-icon-user-o:before {
873 content: "\F0D4"
874 }
875
876 .van-icon-video-o:before {
877 content: "\F0D5"
878 }
879
880 .van-icon-video:before {
881 content: "\F0D6"
882 }
883
884 .van-icon-vip-card-o:before {
885 content: "\F0D7"
886 }
887
888 .van-icon-vip-card:before {
889 content: "\F0D8"
890 }
891
892 .van-icon-volume-o:before {
893 content: "\F0D9"
894 }
895
896 .van-icon-volume:before {
897 content: "\F0DA"
898 }
899
900 .van-icon-wap-home-o:before {
901 content: "\F0DB"
902 }
903
904 .van-icon-wap-home:before {
905 content: "\F0DC"
906 }
907
908 .van-icon-wap-nav:before {
909 content: "\F0DD"
910 }
911
912 .van-icon-warn-o:before {
913 content: "\F0DE"
914 }
915
916 .van-icon-warning-o:before {
917 content: "\F0DF"
918 }
919
920 .van-icon-warning:before {
921 content: "\F0E0"
922 }
923
924 .van-icon-weapp-nav:before {
925 content: "\F0E1"
926 }
927
928 .van-icon-wechat:before {
929 content: "\F0E2"
930 }
931
932 .van-icon-youzan-shield:before {
933 content: "\F0E3"
934 }
935
936 :host {
937 display: -webkit-inline-flex;
938 display: inline-flex;
939 -webkit-align-items: center;
940 align-items: center;
941 -webkit-justify-content: center;
942 justify-content: center
943 }
944
945 .van-icon--image {
946 width: 1em;
947 height: 1em
948 }
949
950 .van-icon__image {
951 width: 100%;
952 height: 100%
953 }
954
955 .van-icon__info {
956 z-index: 1
957 }
958
src/wxcomponents/vant/info/index.d.ts
File was created 1 export {};
2
src/wxcomponents/vant/info/index.js
File was created 1 import { VantComponent } from '../common/component';
2 VantComponent({
3 props: {
4 dot: Boolean,
5 info: null,
6 customStyle: String
7 }
8 });
9
src/wxcomponents/vant/info/index.json
File was created 1 {
2 "component": true
3 }
4
src/wxcomponents/vant/info/index.vue
File was created 1 <template>
2 <uni-shadow-root class="vant-info-index"><view v-if="info !== null && info !== '' || dot" :class="'custom-class van-info '+(utils.bem('info', { dot }))" :style="customStyle">{{ dot ? '' : info }}</view></uni-shadow-root>
3 </template>
4 <wxs src="../wxs/utils.wxs" module="utils"></wxs>
5 <script>
6
7 global['__wxRoute'] = 'vant/info/index'
8 import { VantComponent } from '../common/component';
9 VantComponent({
10 props: {
11 dot: Boolean,
12 info: null,
13 customStyle: String
14 }
15 });
16 export default global['__wxComponents']['vant/info/index']
17 </script>
18 <style platform="mp-weixin">
19 @import '../common/index.css';.van-info{position:absolute;top:0;right:0;box-sizing:border-box;white-space:nowrap;text-align:center;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);-webkit-transform-origin:100%;transform-origin:100%;min-width:16px;min-width:var(--info-size,16px);padding:0 3px;padding:var(--info-padding,0 3px);color:#fff;color:var(--info-color,#fff);font-weight:500;font-weight:var(--info-font-weight,500);font-size:12px;font-size:var(--info-font-size,12px);font-family:PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--info-font-family,PingFang SC,Helvetica Neue,Arial,sans-serif);line-height:14px;line-height:calc(var(--info-size, 16px) - var(--info-border-width, 1px)*2);background-color:#ee0a24;background-color:var(--info-background-color,#ee0a24);border:1px solid #fff;border:var(--info-border-width,1px) solid var(--white,#fff);border-radius:16px;border-radius:var(--info-size,16px)}.van-info--dot{min-width:0;border-radius:100%;width:8px;width:var(--info-dot-size,8px);height:8px;height:var(--info-dot-size,8px);background-color:#ee0a24;background-color:var(--info-dot-color,#ee0a24)}
20 </style>
src/wxcomponents/vant/info/index.wxml
File was created 1 <wxs src="../wxs/utils.wxs" module="utils" />
2
3 <view
4 wx:if="{{ info !== null && info !== '' || dot }}"
5 class="custom-class van-info {{ utils.bem('info', { dot }) }}"
6 style="{{ customStyle }}"
7 >{{ dot ? '' : info }}</view>
8
src/wxcomponents/vant/info/index.wxss
File was created 1 @import '../common/index.wxss';.van-info{position:absolute;top:0;right:0;box-sizing:border-box;white-space:nowrap;text-align:center;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);-webkit-transform-origin:100%;transform-origin:100%;min-width:16px;min-width:var(--info-size,16px);padding:0 3px;padding:var(--info-padding,0 3px);color:#fff;color:var(--info-color,#fff);font-weight:500;font-weight:var(--info-font-weight,500);font-size:12px;font-size:var(--info-font-size,12px);font-family:PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--info-font-family,PingFang SC,Helvetica Neue,Arial,sans-serif);line-height:14px;line-height:calc(var(--info-size, 16px) - var(--info-border-width, 1px)*2);background-color:#ee0a24;background-color:var(--info-background-color,#ee0a24);border:1px solid #fff;border:var(--info-border-width,1px) solid var(--white,#fff);border-radius:16px;border-radius:var(--info-size,16px)}.van-info--dot{min-width:0;border-radius:100%;width:8px;width:var(--info-dot-size,8px);height:8px;height:var(--info-dot-size,8px);background-color:#ee0a24;background-color:var(--info-dot-color,#ee0a24)}
src/wxcomponents/vant/loading/index.d.ts
File was created 1 export {};
2
src/wxcomponents/vant/loading/index.js
File was created 1 import { VantComponent } from '../common/component';
2 import { addUnit } from '../common/utils';
3 VantComponent({
4 props: {
5 color: String,
6 vertical: Boolean,
7 type: {
8 type: String,
9 value: 'circular'
10 },
11 size: {
12 type: String,
13 observer: 'setSizeWithUnit'
14 },
15 textSize: {
16 type: String,
17 observer: 'setTextSizeWithUnit'
18 }
19 },
20 methods: {
21 setSizeWithUnit(size) {
22 this.setData({
23 sizeWithUnit: addUnit(size)
24 });
25 },
26 setTextSizeWithUnit(size) {
27 this.set({
28 textSizeWithUnit: addUnit(size)
29 });
30 }
31 }
32 });
33
src/wxcomponents/vant/loading/index.json
File was created 1 {
2 "component": true
3 }
src/wxcomponents/vant/loading/index.vue
File was created 1 <template>
2 <uni-shadow-root class="vant-loading-index"><view :class="'custom-class van-loading '+(vertical ? 'van-loading--vertical' : '')">
3 <view :class="'van-loading__spinner van-loading__spinner--'+(type)" :style="'color: '+(color)+'; width: '+(sizeWithUnit)+'; height: '+(sizeWithUnit)">
4 <view v-for="(item,index) in ('item in 12')" :key="item.index" v-if="type === 'spinner'" class="van-loading__dot"></view>
5 </view>
6 <view class="van-loading__text" :style="'font-size: '+(textSizeWithUnit)+';'">
7 <slot></slot>
8 </view>
9 </view></uni-shadow-root>
10 </template>
11
12 <script>
13
14 global['__wxRoute'] = 'vant/loading/index'
15 import { VantComponent } from '../common/component';
16 import { addUnit } from '../common/utils';
17 VantComponent({
18 props: {
19 color: String,
20 vertical: Boolean,
21 type: {
22 type: String,
23 value: 'circular'
24 },
25 size: {
26 type: String,
27 observer: 'setSizeWithUnit'
28 },
29 textSize: {
30 type: String,
31 observer: 'setTextSizeWithUnit'
32 }
33 },
34 methods: {
35 setSizeWithUnit(size) {
36 this.setData({
37 sizeWithUnit: addUnit(size)
38 });
39 },
40 setTextSizeWithUnit(size) {
41 this.set({
42 textSizeWithUnit: addUnit(size)
43 });
44 }
45 }
46 });
47 export default global['__wxComponents']['vant/loading/index']
48 </script>
49 <style platform="mp-weixin">
50 @import '../common/index.css';.vant-loading-index{font-size:0;line-height:1}.van-loading{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#c8c9cc;color:var(--loading-spinner-color,#c8c9cc)}.van-loading__spinner{position:relative;box-sizing:border-box;width:30px;width:var(--loading-spinner-size,30px);max-width:100%;max-height:100%;height:30px;height:var(--loading-spinner-size,30px);-webkit-animation:van-rotate .8s linear infinite;animation:van-rotate .8s linear infinite;-webkit-animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite;animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite}.van-loading__spinner--spinner{-webkit-animation-timing-function:steps(12);animation-timing-function:steps(12)}.van-loading__spinner--circular{border:1px solid transparent;border-top-color:initial;border-radius:100%}.van-loading__text{margin-left:8px;margin-left:var(--padding-xs,8px);color:#969799;color:var(--loading-text-color,#969799);font-size:14px;font-size:var(--loading-text-font-size,14px);line-height:20px;line-height:var(--loading-text-line-height,20px)}.van-loading__text:empty{display:none}.van-loading--vertical{-webkit-flex-direction:column;flex-direction:column}.van-loading--vertical .van-loading__text{margin:8px 0 0;margin:var(--padding-xs,8px) 0 0}.van-loading__dot{position:absolute;top:0;left:0;width:100%;height:100%}.van-loading__dot:before{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%;content:" "}.van-loading__dot:first-of-type{-webkit-transform:rotate(30deg);transform:rotate(30deg);opacity:1}.van-loading__dot:nth-of-type(2){-webkit-transform:rotate(60deg);transform:rotate(60deg);opacity:.9375}.van-loading__dot:nth-of-type(3){-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:.875}.van-loading__dot:nth-of-type(4){-webkit-transform:rotate(120deg);transform:rotate(120deg);opacity:.8125}.van-loading__dot:nth-of-type(5){-webkit-transform:rotate(150deg);transform:rotate(150deg);opacity:.75}.van-loading__dot:nth-of-type(6){-webkit-transform:rotate(180deg);transform:rotate(180deg);opacity:.6875}.van-loading__dot:nth-of-type(7){-webkit-transform:rotate(210deg);transform:rotate(210deg);opacity:.625}.van-loading__dot:nth-of-type(8){-webkit-transform:rotate(240deg);transform:rotate(240deg);opacity:.5625}.van-loading__dot:nth-of-type(9){-webkit-transform:rotate(270deg);transform:rotate(270deg);opacity:.5}.van-loading__dot:nth-of-type(10){-webkit-transform:rotate(300deg);transform:rotate(300deg);opacity:.4375}.van-loading__dot:nth-of-type(11){-webkit-transform:rotate(330deg);transform:rotate(330deg);opacity:.375}.van-loading__dot:nth-of-type(12){-webkit-transform:rotate(1turn);transform:rotate(1turn);opacity:.3125}@-webkit-keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}
51 </style>
src/wxcomponents/vant/loading/index.wxml
File was created 1 <view class="custom-class van-loading {{ vertical ? 'van-loading--vertical' : '' }}">
2 <view
3 class="van-loading__spinner van-loading__spinner--{{ type }}"
4 style="color: {{ color }}; width: {{ sizeWithUnit }}; height: {{ sizeWithUnit }}"
5 >
6 <view
7 wx:if="{{ type === 'spinner' }}"
8 wx:for="item in 12"
9 wx:key="index"
10 class="van-loading__dot"
11 />
12 </view>
13 <view class="van-loading__text" style="font-size: {{ textSizeWithUnit }};">
14 <slot />
15 </view>
16 </view>
17