Browse Source

小程序首页

luxf 4 months ago
parent
commit
1d5b4a8caf
100 changed files with 16060 additions and 71 deletions
  1. 2 2
      App.vue
  2. 23 0
      README.md
  3. 288 0
      components/common/u-dropdown-select/index.vue
  4. 78 0
      components/common/u-panel/index.vue
  5. 200 0
      components/common/u-swiper/index.vue
  6. 133 0
      components/common/u-tabs/index.vue
  7. 38 9
      components/layout/nav-bar.vue
  8. 147 0
      components/layout/tab-bar.vue
  9. 1 1
      manifest.json
  10. 13 2
      pages.json
  11. 131 0
      pages/components/index.vue
  12. 90 0
      pages/exhibitor/index.vue
  13. 398 0
      pages/index/home.vue
  14. 17 54
      pages/index/index.vue
  15. 38 0
      pages/index/webview.vue
  16. 109 0
      pages/news/components/news-recommend.vue
  17. 539 0
      static/font/demo.css
  18. 5732 0
      static/font/demo_index.html
  19. 980 0
      static/font/iconfont.css
  20. 1 0
      static/font/iconfont.js
  21. 1696 0
      static/font/iconfont.json
  22. 501 0
      static/font/iconfont.svg
  23. BIN
      static/font/iconfont.ttf
  24. BIN
      static/font/iconfont.woff
  25. BIN
      static/font/iconfont.woff2
  26. BIN
      static/img/example/album/1.jpeg
  27. BIN
      static/img/example/album/2.jpeg
  28. BIN
      static/img/example/album/3.jpeg
  29. BIN
      static/img/example/album/4.jpeg
  30. BIN
      static/img/example/album/5.jpeg
  31. BIN
      static/img/example/album/6.jpeg
  32. BIN
      static/img/example/banner.png
  33. 1 0
      static/img/example/icon/car_line.svg
  34. 29 0
      static/img/example/icon/event.svg
  35. 25 0
      static/img/example/icon/house.svg
  36. 17 0
      static/img/example/icon/layers.svg
  37. 9 0
      static/img/example/icon/list.svg
  38. 21 0
      static/img/example/icon/news.svg
  39. BIN
      static/img/example/video.jpeg
  40. BIN
      static/logo.jpg
  41. BIN
      static/logo.png
  42. 72 0
      static/style/app.scss
  43. 48 1
      uni.scss
  44. 116 0
      wxcomponents/vant/action-sheet/index.vue
  45. 234 0
      wxcomponents/vant/area/index.vue
  46. 92 0
      wxcomponents/vant/button/index.vue
  47. 37 0
      wxcomponents/vant/calendar/calendar.vue
  48. 64 0
      wxcomponents/vant/calendar/components/header/index.vue
  49. 194 0
      wxcomponents/vant/calendar/components/month/index.vue
  50. 388 0
      wxcomponents/vant/calendar/index.vue
  51. 105 0
      wxcomponents/vant/card/index.vue
  52. 246 0
      wxcomponents/vant/cascader/index.vue
  53. 28 0
      wxcomponents/vant/cell-group/index.vue
  54. 76 0
      wxcomponents/vant/cell/index.vue
  55. 50 0
      wxcomponents/vant/checkbox-group/index.vue
  56. 102 0
      wxcomponents/vant/checkbox/index.vue
  57. 215 0
      wxcomponents/vant/circle/index.vue
  58. 23 0
      wxcomponents/vant/col/index.vue
  59. 86 0
      wxcomponents/vant/collapse-item/index.vue
  60. 60 0
      wxcomponents/vant/collapse/index.vue
  61. 1 0
      wxcomponents/vant/common/index.css
  62. 1 0
      wxcomponents/vant/common/style/clearfix.css
  63. 1 0
      wxcomponents/vant/common/style/ellipsis.css
  64. 1 0
      wxcomponents/vant/common/style/hairline.css
  65. 0 0
      wxcomponents/vant/common/style/mixins/clearfix.css
  66. 0 0
      wxcomponents/vant/common/style/mixins/ellipsis.css
  67. 0 0
      wxcomponents/vant/common/style/mixins/hairline.css
  68. 0 0
      wxcomponents/vant/common/style/var.css
  69. 23 0
      wxcomponents/vant/config-provider/index.vue
  70. 115 0
      wxcomponents/vant/count-down/index.vue
  71. 309 0
      wxcomponents/vant/datetime-picker/index.vue
  72. 184 0
      wxcomponents/vant/dialog/index.vue
  73. 28 0
      wxcomponents/vant/divider/index.vue
  74. 157 0
      wxcomponents/vant/dropdown-item/index.vue
  75. 139 0
      wxcomponents/vant/dropdown-menu/index.vue
  76. 42 0
      wxcomponents/vant/empty/index.vue
  77. 1 1
      wxcomponents/vant/empty/index.wxss
  78. 182 0
      wxcomponents/vant/field/index.vue
  79. 15 0
      wxcomponents/vant/field/input.vue
  80. 15 0
      wxcomponents/vant/field/textarea.vue
  81. 61 0
      wxcomponents/vant/goods-action-button/index.vue
  82. 48 0
      wxcomponents/vant/goods-action-icon/index.vue
  83. 29 0
      wxcomponents/vant/goods-action/index.vue
  84. 82 0
      wxcomponents/vant/grid-item/index.vue
  85. 69 0
      wxcomponents/vant/grid/index.vue
  86. 38 0
      wxcomponents/vant/icon/index.vue
  87. 90 0
      wxcomponents/vant/image/index.vue
  88. 44 0
      wxcomponents/vant/index-anchor/index.vue
  89. 266 0
      wxcomponents/vant/index-bar/index.vue
  90. 20 0
      wxcomponents/vant/info/index.vue
  91. 35 0
      wxcomponents/vant/loading/index.vue
  92. 99 0
      wxcomponents/vant/nav-bar/index.vue
  93. 150 0
      wxcomponents/vant/notice-bar/index.vue
  94. 84 0
      wxcomponents/vant/notify/index.vue
  95. 1 1
      wxcomponents/vant/notify/notify.js
  96. 52 0
      wxcomponents/vant/overlay/index.vue
  97. 17 0
      wxcomponents/vant/overlay/overlay.vue
  98. 34 0
      wxcomponents/vant/panel/index.vue
  99. 134 0
      wxcomponents/vant/picker-column/index.vue
  100. 0 0
      wxcomponents/vant/picker/index.vue

+ 2 - 2
App.vue

@@ -12,6 +12,6 @@
 	}
 </script>
 
-<style>
-	/*每个页面公共css */
+<style lang="scss">
+  @import "@/static/style/app.scss";
 </style>

+ 23 - 0
README.md

@@ -0,0 +1,23 @@
+## process.env 配置
+## package.json 的 env节点
+`
+```json
+"uni-app": {
+	"scripts": {
+		"dev": {
+			"title": "小程序-开发环境",
+			"env": {
+				"UNI_PLATFORM": "mp-weixin",
+				"NAME": "dev",
+				"TOKEN_KEY": "token",
+				"BASE_API": "https://starify-api-dev.matchexpo.cn"
+			},
+			"define": {
+				"MP-CJN": true
+			}
+		},
+```
+`
+## 登录与授权
+store/user.js
+utils/auth.js

+ 288 - 0
components/common/u-dropdown-select/index.vue

@@ -0,0 +1,288 @@
+<template>
+	<view>
+		<view class="u-dropdown-select" :class="{ 'active': showOptions }" @touchstart="touchStart">
+			<view class="u-dropdown-label">{{ label || placeholder }} </view>
+			<van-icon name="arrow-down" />
+		</view>
+		<view v-if="showOptions" class="u-dropdown-select-mask" :style="{ 'top': offsetTop +'px' }" @click="showOptions = false"></view>
+		<view v-if="showOptions" class="u-dropdown-panel" :style="{ 'top': offsetTop +'px' }">
+			<view class="u-dropdown-tabs">
+				<u-tabs :active.sync="tabActive" :tabs="tabs" @change="tabChange"/>
+			</view>
+			<view class="u-dropdown-options">
+				<template v-if="list.length">
+					<template v-for="(item, index) in list">
+						<view class="u-dropdown-option" :class="{ 'active': item.active }" @click="clickOption(item)">
+							<view>{{ item.label }}</view>
+							<van-icon class="van-icon" name="arrow" />
+						</view>
+					</template>
+				</template>
+				<van-empty v-else class="van-empty" description="没有数据"/>
+			</view>
+			<view class="u-dropdown-action">
+				<van-button type="info" class="button-info" block @click="reset">重置</van-button>
+				<van-button type="primary" class="button-primary" block @click="confirm">确定</van-button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import UTabs from '@/components/common/u-tabs/index.vue'
+	
+	export default {
+		options: {
+			styleIsolation: 'shared'
+		},
+		components: {
+			UTabs
+		},
+		props: {
+			placeholder: String,
+			options: Array,
+			dataApi: Function,
+			dataParams: Object,
+			value: [String, Number]
+		},
+		
+		watch: {
+			options() {
+				this.initComponent()
+			}
+		},
+		data() {
+			return {
+				showOptions: false,
+				offsetTop: 0,
+				tabActive: 3,
+				tabs: [],
+				list: [],
+				label: ''
+			}
+		},
+		created() {
+			this.initComponent()
+			console.log('value:' + this.value)
+		},
+		mounted() {
+			  
+		},
+		methods: {
+			initComponent() {
+				if (this.options) {
+					this.setOptions(this.options)
+				}
+				if (this.value) {
+					this.setLabel(this.value)
+				}
+				if (this.dataApi) {
+					this.dataApi(this.dataParams || {}).then(res => {
+						this.setOptions(res.data)
+					})
+				}
+			},
+			tabChange(e) {
+				this.list = this.tabs[e.detail.index].children
+			},
+			setOptions(options) {
+				if (options) {
+					if (!options.length) {
+						this.tabs = []
+						this.list = []
+					} else if (!options[0].children || options[0].children.length === 0) {
+						this.tabs = []
+						this.list = options
+					} else {
+						this.tabs = options.map(v => {
+							return {
+								label: v.label,
+								value: v.value,
+								children: v.children || []
+							}
+						})
+						this.list = this.tabs[0].children
+						this.tabActive = this.tabs[0].value
+					}
+				}
+			},
+			setLabel(value) {
+				const option = this.getSelectOption(value)
+				if (option) {
+					if (option.tab) {
+						this.label = option.tab.label + ' / ' + option.item.label
+					} else {
+						this.label = option.item.label
+					}
+				} else {
+					this.label = ''
+				}
+			},
+			reset() {
+				this.cleanListActive()
+				this.label = ''
+				this.showOptions = false
+				this.$emit('input', null)
+				this.$emit('change', {
+					detail: {
+						value: null
+					}
+				})
+			},
+			confirm() {
+				this.showOptions = false
+				let val = null
+				const option = this.getSelectOption()
+				if (option) {
+					this.setLabel()
+					if (option.tab) {
+						val = option.item.value
+					} else {
+						val = option.value
+					}
+					this.$emit('input', val)
+				}
+				this.$emit('change', {
+					detail: {
+						value: val
+					}
+				})
+			},
+			getSelectOption(value) {
+				if (this.tabs.length) {
+					for (const tab of this.tabs) {
+						for (const item of tab.children) {
+							if (item.active || item.value === value) {
+								return {
+									tab: tab,
+									item: item
+								}
+							}
+						}
+					}
+				} else {
+					for (const item of this.list) {
+						if (item.active || item.value === value) {
+							return item
+						}
+					}
+				}
+			},
+			cleanListActive() {
+				this.list.forEach(item => {
+					this.$set(item, 'active', false)
+				})
+				this.$emit('change', {
+					detail: {
+						value: null
+					}
+				})
+				this.$emit('input', undefined)
+			},
+			clickOption(item) {
+				this.cleanListActive()
+				this.$set(item, 'active', true)
+			},
+			touchStart() {
+				this.showOptions = !this.showOptions
+				const query = uni.createSelectorQuery().in(this)
+				query.select('.u-dropdown-select').boundingClientRect(data => {
+					if (data) {
+						this.offsetTop = data.top + data.height
+						// data.top 就是元素的offsetTop
+						console.log('offsetTop:', data.top);
+					}
+				}).exec()
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.u-dropdown-tabs{
+		padding: 10rpx 0;
+		margin-top: 20rpx;
+	}
+	.van-empty{
+		--image-width: 160rpx;
+		--image-height: 160rpx;
+	}
+	.u-dropdown-select{
+		@extend .display-flex-between;
+		min-width: 211rpx;
+		height: 50rpx;
+		padding: 0 10rpx;
+		border: $borderLight;
+		border-radius: 8rpx;
+		background-color: #FFFFFF;
+		border-radius: 8rpx;
+		border: 1rpx solid #D9D9D9;
+		&.active{
+			background-color: $buttonPrimaryColor;
+			color: white;
+		}
+		.van-icon{
+			font-size: 15rpx;
+		}
+	}
+	.u-dropdown-label{
+		max-width: 100%;
+		@extend .text-ellipsis;
+		font-size: $fontSize1;
+	}
+	.u-dropdown-tabs{
+		--tabs-line-height: 44px;
+		--tabs-card-height: 30px;
+		--tabs-bottom-bar-height: 0rpx;
+		--tab-active-text-color: #E57519;
+	}
+	.u-dropdown-panel{
+		position: fixed;
+		left: 0;
+		top: 0;
+		display: block;
+		width: 100%;
+		z-index: 9999;
+		background-color: white;
+	}
+	.u-dropdown-options{
+		min-height: 100rpx;
+		max-height: 400rpx;
+		padding: 20rpx;
+		overflow-y: auto;
+	}
+	.u-dropdown-option{
+		line-height: 50rpx;
+		@extend .display-flex-between;
+		font-size: $fontSize2;
+		&.active{
+			color: $buttonPrimaryColor;
+		}
+	}
+	.u-dropdown-action{
+		display: grid;
+		grid-template-columns: 1fr 1fr;
+	}
+	.van-button{
+		border-radius: 0rpx;
+		height: 80rpx;
+		font-size: $fontSize2;
+	}
+	.van-empty__description{
+		font-size: $fontSize2;
+		margin-top: 0rpx;
+	}
+	.button-info{
+		--button-info-background-color: black;
+		--button-info-border-color: black;
+		--button-info-color: white;
+	}
+	.u-dropdown-select-mask{
+		position: fixed;
+		display: block;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 9998;
+		background-color: rgba(0, 0, 0, 0.5);
+	}
+</style>

+ 78 - 0
components/common/u-panel/index.vue

@@ -0,0 +1,78 @@
+<template>
+	<view class="u-panel">
+		<view class="u-panel-head display-flex-between">
+			<view class="u-panel-title">{{ title }}</view>
+			<view class="u-panel-link" @tap="onClickLink">
+				{{ linkText || '查看更多' }} <van-icon class="van-icon" name="arrow" />
+			</view>
+		</view>
+		<view class="u-panel-body">
+			<slot></slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		options: {
+			styleIsolation: 'shared'
+		},
+		props: {
+			title: String,
+			link: String,
+			linkText: String
+		},
+		computed: {
+			style() {
+			}
+		},
+		watch: {
+		},
+		data() {
+			return {
+			}
+		},
+		created() {
+		},
+		mounted() {
+		},
+		methods: {
+			onClickLink() {
+				if (this.link.indexOf('http') === -1) {
+					uni.navigateTo({
+						url: this.link
+					})
+				}
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.u-panel{
+		padding: 24rpx 28rpx;
+	}
+	.u-panel-head{
+		margin-bottom: 26rpx;
+		.u-panel-title{
+			position: relative;
+			padding-bottom: 20rpx;
+			font-size: $fontSize4;
+			font-weight: 500;
+			color: #000000;
+			&:after{
+				@extend .after;
+				left: 0;
+				right: 0;
+				bottom: 0;
+				width: 34rpx;
+				height: 0;
+				border: 4rpx solid $buttonPrimaryColor;
+				margin: auto;
+			}
+		}
+		.u-panel-link{
+			font-size: $fontSize1;
+			color: #7D7D7D;
+		}
+	}
+</style>

+ 200 - 0
components/common/u-swiper/index.vue

@@ -0,0 +1,200 @@
+<template>
+	<view class="swiper-container">
+		<swiper class="swiper" circular :indicator-dots="false" :circular="circular" :next-margin="nextMargin" :autoplay="autoplay" :interval="interval"
+					:duration="duration" :style="style" @change="onSwiperChange">
+			<template v-for="(item, index) in items">
+				<swiper-item>
+					<view class="image-wrapper">
+						<image v-if="item.src" :mode="imageMode" :src="item.src" :style="imageStyle" @tap="onImageClick(item)"/>
+						<template v-else>
+							<slot :scope="item" :style="style"></slot>
+						</template>
+						<view class="video-play" v-if="item.url && item.url.indexOf('.mp4') !== -1">
+						</view>
+					</view>
+				</swiper-item>
+			</template>
+		</swiper>
+		<!-- 自定义指示点 -->
+		<view v-if="indicatorDots" class="custom-indicator" :class="{ 'morphing': indicatoDotsStyle === 'morphing' }">
+			<view
+				v-for="(item, index) in items"
+				:key="index"
+				class="dot"
+				:class="{ 'active': current === index }"
+			></view>
+		</view>
+		<van-overlay :show="showOverlay" @tap="onClickHideOverlay">
+		  <view class="overlay-wrapper display-flex-center">
+				<video v-if="videoUrl" :src="videoUrl" controls autoplay loop @tap.stop></video>
+		  </view>
+		</van-overlay>
+	</view>
+</template>
+
+<script>
+	export default {
+		options: {
+			styleIsolation: 'shared'
+		},
+		props: {
+			items: Array,
+			borderRadius: {
+				type: Number
+			},
+			nextMargin: {
+				type: String,
+				default: ''
+			},
+			height: {
+				type: Number,
+				default: 400
+			},
+			imageWidth: {
+				type: Number,
+				default: 0
+			},
+			imageHeight: {
+				type: Number,
+				default: 0
+			},
+			imageMode: {
+				type: String,
+				default: 'aspectFill' // 参考https://zh.uniapp.dcloud.io/component/image.html
+			},
+			indicatoDotsStyle: {
+				type: String,
+				default: 'default' // or 'morphing'
+			},
+			indicatorDots: {
+				type: Boolean,
+				default: true
+			},
+			circular: {
+				type: Boolean,
+				default: true
+			},
+			autoplay: {
+				type: Boolean,
+				default: true
+			},
+			interval: {
+				type: Number,
+				default: 5000
+			},
+			duration: {
+				type: Number,
+				default: 500
+			}
+		},
+		computed: {
+			style() {
+				return 'height:' + this.height + 'rpx;'
+			},
+			imageStyle() {
+				let style = 'height:' + (this.imageHeight || this.height) + 'rpx;'
+				if (this.imageWidth) {
+					style += 'width:' + this.imageWidth + 'rpx;'
+				}
+				if (this.borderRadius) {
+					style += 'border-radius:' + this.borderRadius + 'rpx;'
+				}
+				return style
+			}
+		},
+		watch: {
+		},
+		data() {
+			return {
+				showOverlay: false,
+				videoUrl: '',
+				current: 0
+			}
+		},
+		created() {
+		},
+		mounted() {
+		},
+		methods: {
+			onClickHideOverlay() {
+				this.showOverlay = false
+			},
+			onSwiperChange(e) {
+				this.current = e.detail.current
+			},
+			onImageClick(item) {
+				if (item.url) {
+					if (item.url.indexOf('.mp4') !== -1) {
+						this.videoUrl = item.url
+						this.showOverlay = true
+					} else if (item.url.indexOf('http') === -1) {
+						uni.navigateTo({
+							url: item.url
+						})
+					} else {
+						uni.navigateTo({
+							url: '/pages/index/webview?url=' + item.url
+						})
+					}
+				}
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.image-wrapper {
+		position: relative;
+		.video-play{
+			position: absolute;
+			top: 0;
+			bottom: 0;
+			right: 0;
+			left: 0;
+			width: 82rpx;
+			height: 82rpx;
+			border-radius: 50%;
+			margin: auto;
+			background-color: rgba(229, 117, 25, 0.5);
+			z-index: 1;
+		}
+		image{
+			width: 100%;
+		}
+	}
+	.overlay-wrapper{
+		height: 100%;
+		video{
+			width: 100%;
+		}
+	}
+	.swiper-container{
+		position: relative;
+	}
+	/* 自定义指示点样式 */
+	.custom-indicator {
+		position: absolute;
+		bottom: 24rpx;
+		width: 100%;
+	  display: flex;
+	  justify-content: center;
+	  margin-top: 10rpx;
+		&.morphing {
+			margin: 0 4rpx;
+			.dot.active{
+				 width: 26rpx;
+				 border-radius: 4rpx;
+				 background-color: white;
+			}
+		}
+	}
+	.dot {
+	  width: 10rpx;
+	  height: 10rpx;
+	  border-radius: 50%;
+	  background-color: #D9D9D9;
+	  margin: 0 2.5rpx;
+		&.active {
+		  background-color: $buttonPrimaryColor; /* 当前激活的指示点颜色 */
+		}
+	}
+</style>

+ 133 - 0
components/common/u-tabs/index.vue

@@ -0,0 +1,133 @@
+<template>
+	<van-tabs :class="clazz" :active="tabActive" :ellipsis="false" @change="tabChange">
+		<template v-for="(item, index) in tabs">
+			<van-tab class="u-tab" :title="item.label" :name="item.value"></van-tab>
+		</template>
+	</van-tabs>
+</template>
+
+<script>
+	export default {
+		options: {
+			styleIsolation: 'shared'
+		},
+		props: {
+			tabStyle: String,
+			active: [String, Number],
+			tabs: [Array]
+		},
+		computed: {
+			clazz() {
+				if (this.tabStyle === 'default') {
+					return 'u-tabs u-tabs-detault'
+				} else {
+					return 'u-tabs'
+				}
+			}
+		},
+		watch: {
+			active(val) {
+				// this.tabActive = val
+			}
+		},
+		data() {
+			return {
+				tabActive: undefined,
+				data: [{
+					label: '表面贴装',
+					value: 1
+				}, {
+					label: '线束加工',
+					value: 2
+				}, {
+					label: '工厂自动化',
+					value: 3
+				}, {
+					label: '点胶注胶',
+					value: 4
+				}, {
+					label: '电子制造服务',
+					value: 5
+				}, {
+					label: '未来服务',
+					value: 6
+				}]
+			}
+		},
+		created() {
+			// this.tabActive = this.active
+			console.log("===================")
+			console.log(this.tabStyle)
+		},
+		mounted() {
+		},
+		methods: {
+			tabChange(e) {
+				const detail = e.detail
+				e.detail = {
+					index: detail.index,
+					label: detail.title,
+					value: detail.name
+				}
+				this.tabActive = e.detail.name
+				this.$emit('update:active', this.tabActive)
+				this.$emit('change', e)
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.u-tabs{
+		--tabs-line-height: 64rpx;
+		--tabs-card-height: 64rpx;
+		--tabs-bottom-bar-height: rpx;
+		--tab-active-text-color: #E57519;
+		--tab-background-color: #F5F5F5;
+		--tab-active-background-color: #F9E3D1;
+		--tab-margin-right: 10rpx;
+		--tab-border-radius: 20rpx;
+		.van-tab{
+			font-size: $fontSize2;
+			line-height: 50rpx;
+		}
+		.van-tabs--line{
+			height: 50rpx;
+		}
+		.van-tabs__scroll--line{
+			height: 100%;
+		}
+	}
+	.u-tabs.u-tabs-detault{
+		--tabs-line-height: 48rpx;
+		--tabs-card-height: 50rpx;
+		--tabs-bottom-bar-height: 0;
+		--tab-active-text-color: #FFFFFF;
+		--tab-background-color: #FFFFFF;
+		--tab-active-background-color: #E57519;
+		--tab-margin-right: 13rpx;
+		--tab-border-radius: 6rpx;
+		.van-tabs__nav{
+			padding: 0;
+		}
+		.van-tab{
+			font-size: $fontSize1;
+			border: 1rpx solid #7D7D7D;
+			height: 50rpx;
+			color: #7D7D7D;
+		}
+		.van-tab--active{
+			border-color: #E57519!important;
+			color: #FFFFFF;
+		}
+		.van-tabs__wrap--scrollable .van-tab--complete{
+			flex: none!important;
+			padding: 0 32rpx;
+		}
+		.van-tabs--line{
+			height: 50rpx;
+		}
+	}
+	.u-tab{
+		margin-right: 20rpx;
+	}
+</style>

+ 38 - 9
components/layout/nav-bar.vue

@@ -3,16 +3,30 @@
 		<view class="nav-bar-status" :style="{ height: statusBarHeight + 'px' }">
 		</view>
 		<view class="nav-bar-title" :style="{ height: titleBarHeight +'px' }">
-			<view></view>
-			<view>慕尼黑展览公司</view>
-			<view></view>
+			<template v-if="title">
+				<view>
+					<van-icon v-if="hasParent" name="arrow-left" @click="goBack"/>
+				</view>
+				<view class="nav-bar-title-text">{{ title }}</view>
+				<view></view>
+			</template>
+			<template v-else>
+				 <view><slot></slot></view>
+			</template>
 		</view>
 	</view>
 </template>
 
 <script>
 	export default {
-		props: {},
+		props: {
+			title: String
+		},
+		computed: {
+			hasParent() {
+				return getCurrentPages().length > 1
+			}
+		},
 		data() {
 			return {
 				titleBarHeight: 0,
@@ -24,21 +38,36 @@
 			const systemInfo = uni.getSystemInfoSync()
 			this.statusBarHeight = systemInfo.statusBarHeight
 			const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
-			this.titleBarHeight = (menuButtonInfo.top - this.statusBarHeight) * 2 + menuButtonInfo.height
-			console.log(systemInfo)
+			this.titleBarHeight = (menuButtonInfo.top - this.statusBarHeight) * 2 + menuButtonInfo.height + (systemInfo.screenWidth / 750 * 16)
+		},
+		methods: {
+			goBack() {
+				uni.navigateBack()
+			}
 		}
 	}
 </script>
 
 <style lang="scss" scoped>
 	.nav-bar {
-		background-color: $primary-color;
+		background: linear-gradient( 270deg, #2b2359 9%, #405491 44%, #2b2359 92%), rgba(0,0,0,0.2);
 	}
-	
 	.nav-bar-title{
 		display: flex;
 		justify-content: space-between;
 		align-items: center;
-		color: #ffffff;
+		padding: 0 32rpx;
+		view{
+			color: #ffffff;
+		}
+	}
+	.nav-bar-title-text{
+		flex: 1;
+		font-weight: 500;
+		font-size: $fontSize5;
+		line-height: 42rpx;
+		text-align: left;
+		text-transform: none;
+		padding-left: 8rpx;
 	}
 </style>

+ 147 - 0
components/layout/tab-bar.vue

@@ -0,0 +1,147 @@
+<template>
+	<van-tabbar :active="tabbarActive" @change="onChange" :placeholder="true" active-color="#E57519"
+		inactive-color="#7D7D7D">
+		<template v-for="(item, index) in list">
+			<van-tabbar-item v-if="index !== 2" :name="item.name" :key="index" :icon="item.icon" icon-prefix="tabbar-icon">
+				{{ item.text }}
+			</van-tabbar-item>
+			<template v-else>
+				<view class="tabbar-center-item" :class="{ 'active': tabbarActive === item.name } " hover-class="active"
+					@click="onClickCenter">
+					<view class="tabbar-center-round">
+						<view>
+							<van-icon :name="item.icon" class-prefix="tabbar-icon" />
+						</view>
+					</view>
+					<view class="tabbar-center-text">
+						{{ item.text }}
+					</view>
+				</view>
+			</template>
+		</template>
+	</van-tabbar>
+</template>
+
+<script>
+	export default {
+		options: {
+			styleIsolation: 'shared'
+		},
+		props: {
+			active: String
+		},
+		data() {
+			return {
+				tabbarActive: 'home',
+				list: [{
+						name: 'home',
+						icon: 'home',
+						text: '首页',
+						url: '/pages/index'
+					}, {
+						name: 'exhibitor',
+						icon: 'exhibitor',
+						text: '展商',
+						url: '/pages/signup/signup'
+					},
+					{
+						name: 'registration',
+						icon: 'registration',
+						text: '观众预登记',
+						url: '/pages/test'
+					},
+					{
+						name: 'activity',
+						icon: 'activity',
+						text: '同期活动',
+						url: '/pages/test'
+					},
+					{
+						name: 'user',
+						icon: 'user',
+						text: '个人中心',
+						url: '/pages/test'
+					}
+				]
+			}
+		},
+		created() {
+			this.tabbarActive = this.active
+		},
+		methods: {
+			onChange(e) {
+				this.tabbarActive = e.detail
+				this.$emit('update:active', e.detail)
+				this.$emit('change', e.detail)
+			},
+			onClickCenter() {
+				uni.navigateTo({
+					url: '/pages/components/index'
+				})
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.van-tabbar-item__text {
+		font-size: $fontSize2;
+		color: #7D7D7D;
+	}
+
+	.van-tabbar-item--active {
+		.van-tabbar-item__text {
+			color: $textActionColor;
+		}
+	}
+
+	.tabbar-center-item {
+		position: relative;
+		top: -50rpx;
+		z-index: 1;
+		flex: 1;
+
+		&.active {
+			.tabbar-center-text {
+				color: $textActionColor;
+			}
+		}
+	}
+
+	.tabbar-center-text {
+		font-size: $fontSize2;
+		color: #7D7D7D;
+		margin-top: 10rpx;
+		text-align: center;
+	}
+
+	.tabbar-center-round {
+		@extend .display-flex-center;
+		width: 100rpx;
+		height: 100rpx;
+		border-radius: 50%;
+		background-color: $buttonPrimaryColor;
+		margin: auto;
+
+		&>view {
+			@extend .display-flex-center;
+			width: 96rpx;
+			height: 96rpx;
+			border-radius: 50%;
+			border: 1rpx solid #FFFFFF;
+			color: #FFFFFF;
+			background-color: $buttonPrimaryColor;
+
+			.tabbar-icon {
+				font-size: 60rpx;
+			}
+		}
+	}
+
+	.tabbar-icon-activity {
+		font-size: 40rpx;
+	}
+
+	.tabbar-icon-user {
+		font-size: 48rpx;
+	}
+</style>

+ 1 - 1
manifest.json

@@ -50,7 +50,7 @@
     "quickapp" : {},
     /* 小程序特有相关 */
     "mp-weixin" : {
-        "appid" : "",
+        "appid" : "wxb75cc4008ddb9669",
         "setting" : {
             "urlCheck" : false
         },

+ 13 - 2
pages.json

@@ -5,7 +5,11 @@
 			"style": {
 				"navigationBarTitleText": "uni-app"
 			}
-		}
+		},
+		// 组件页面
+		{ "path": "pages/components/index" },
+		// WEBVIEW
+		{ "path": "pages/index/webview", "style": { "navigationStyle": "default", "navigationBarTitleText": "加载中...", "navigationBarBackgroundColor": "#332968" }}
 	],
 	"globalStyle": {
 		"navigationStyle": "custom",
@@ -15,10 +19,17 @@
 		"backgroundColor": "#F8F8F8",
 		"usingComponents": {
 			"van-icon": "/wxcomponents/vant/icon/index",
+			"van-tabs": "/wxcomponents/vant/tabs/index",
+			"van-tab": "/wxcomponents/vant/tab/index",
+			"van-empty": "/wxcomponents/vant/empty/index",
 			"van-button": "/wxcomponents/vant/button/index",
 			"van-picker": "/wxcomponents/vant/picker/index",
 			"van-tabbar": "/wxcomponents/vant/tabbar/index",
-			"van-tabbar-item": "/wxcomponents/vant/tabbar-item/index"
+			"van-tabbar-item": "/wxcomponents/vant/tabbar-item/index",
+			"van-collapse": "/wxcomponents/vant/collapse/index",
+			"van-collapse-item": "/wxcomponents/vant/collapse-item/index",
+			"van-search": "/wxcomponents/vant/search/index",
+			"van-overlay": "/wxcomponents/vant/overlay/index"	
 		}
 	},
 	"uniIdRouter": {}

+ 131 - 0
pages/components/index.vue

@@ -0,0 +1,131 @@
+<template>
+	<view>
+		<nav-bar>
+		</nav-bar>
+		<van-collapse :value="activeNames" @change="onCollapseChange">
+			<van-collapse-item title="轮播图" name="1">
+				<u-swiper :items="images"/>
+			</van-collapse-item>	
+		  <van-collapse-item title="分类下拉组件" name="2">
+				<u-dropdown-select v-model="categoryId" placeholder="产品分类" :options="categories" /> 
+				<view>选中的ID:{{ categoryId }}</view>
+				<view>事件:change</view>
+				<view>动态数据:data-api(Function 请求方法),data-params(Object 请求参数)</view>
+		  </van-collapse-item>
+			<van-collapse-item title="导航组件" name="3">
+				<nav-bar />
+			</van-collapse-item>	 
+		  <van-collapse-item title="环境变量" name="4">
+				 <view>通过 process.env.*,获取</view>
+				 <view>接口服务器:{{ apiUrl }}</view>
+		  </van-collapse-item>
+		  <van-collapse-item title="国际化" name="5">
+				<view>通过 $t(key(国际化key), msg(默认消息), params(替换参数))</view>
+				<view>当前语言:{{ locale }}</view>
+				<view>国际化内容:{{ $t('common.close', '关闭') }}</view>
+				<van-button type="primary" @click="selectLanguage('zh-cn')">中文</van-button>
+				<van-button type="warning" @click="selectLanguage('en-us')">英文</van-button>
+		  </van-collapse-item>
+		</van-collapse>
+		<!-- <u-dropdown-select v-model="categoryId" placeholder="产品分类" :options="categories" /> {{ categoryId }} -->
+	</view>
+</template>
+
+<script>
+	import { getLocale, setLocale } from '../../locales/i18n'
+	import UDropdownSelect from '@/components/common/u-dropdown-select/index.vue'
+	import USwiper from '@/components/common/u-swiper/index.vue'
+	import NavBar from '@/components/layout/nav-bar.vue'
+
+	export default {
+		components: {
+			UDropdownSelect,
+			USwiper,
+			NavBar
+		},
+		data() {
+			return {
+				locale: '',
+				activeNames: ['1'],
+				apiUrl: '',
+				images: [{
+					src: 'https://matchexpo.obs.cn-north-1.myhuaweicloud.com/common/2023/1123/655ebb47a7b70.jpg?x-image-process=image/resize,m_lfit,h_214,w_380'
+				}, {
+					src: 'https://matchexpo.obs.cn-north-1.myhuaweicloud.com/common/2023/1123/655ec5b54c527.jpg?x-image-process=image/resize,m_lfit,h_214,w_380'
+				}, {
+					src: 'https://matchexpo.obs.cn-north-1.myhuaweicloud.com/common/2023/1123/655ec1b9d558f.jpg?x-image-process=image/resize,m_lfit,h_214,w_380'
+				}],
+				categoryId: 11,
+				categories: [{
+					label: '表面贴装',
+					value: 1,
+					children: [{
+						label: '表面贴装技术',
+						value: 11
+					}, {
+						label: 'PCB焊接和连接技术',
+						value: 12
+					}, {
+						label: '测试测量和质量保证',
+						value: 13
+					}, {
+						label: '电子组装自动化',
+						value: 14
+					}, {
+						label: '生产物流和物流技术',
+						value: 15
+					}, {
+						label: '清洗技术',
+						value: 16
+					}]
+				}, {
+					label: '线束加工',
+					value: 2
+				}, {
+					label: '工厂自动化',
+					value: 3
+				}, {
+					label: '点胶注胶',
+					value: 4
+				}, {
+					label: '电子制造服务',
+					value: 5
+				}, {
+					label: '未来服务',
+					value: 6
+				}]
+			}
+		},
+		created() {
+			this.locale = getLocale()
+			this.apiUrl = process.env.BASE_API
+			console.log('当前环境的API URL: ', this.apiUrl)
+		},
+		methods: {
+			onChange(e) {
+				this.active = e.detail
+			},
+			selectLanguage(language) {
+				setLocale(language)
+			},
+			onCollapseChange(e) {
+				console.log('onCollapseChange')
+				console.log(e.detail)
+				this.activeNames = e.detail
+			},
+			selectLanguage(language) {
+				setLocale(language)
+				this.locale = language
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		font-size: 24rpx;
+	}
+	.tab-class{
+		background-color: red!important;
+	}
+</style>

+ 90 - 0
pages/exhibitor/index.vue

@@ -0,0 +1,90 @@
+<template>
+	<view class="exhibitor-index">
+		<nav-bar title="展商信息"></nav-bar>
+		<view class="main-container">
+			<view class="exhibitor-filter">
+				<view>
+					<view>展馆号</view>
+					<u-dropdown-select v-model="categoryId" placeholder="产品分类" :options="categories" /> 
+				</view>
+				<view>
+					<view>产品类别</view>
+					<u-dropdown-select v-model="categoryId" placeholder="产品分类" :options="categories" /> 
+				</view>
+				<view>
+					<view>应用领域</view>
+					<u-dropdown-select v-model="categoryId" placeholder="产品分类" :options="categories" /> 
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import NavBar from '@/components/layout/nav-bar.vue'
+	import UDropdownSelect from '@/components/common/u-dropdown-select/index.vue'
+
+	export default {
+		options: {
+			// styleIsolation: 'shared'
+		},
+		components: {
+			NavBar,
+			UDropdownSelect
+		},
+		data() {
+			return {
+				categories: [{
+					label: '表面贴装',
+					value: 1,
+					children: [{
+						label: '表面贴装技术',
+						value: 11
+					}, {
+						label: 'PCB焊接和连接技术',
+						value: 12
+					}, {
+						label: '测试测量和质量保证',
+						value: 13
+					}, {
+						label: '电子组装自动化',
+						value: 14
+					}, {
+						label: '生产物流和物流技术',
+						value: 15
+					}, {
+						label: '清洗技术',
+						value: 16
+					}]
+				}, {
+					label: '线束加工',
+					value: 2
+				}, {
+					label: '工厂自动化',
+					value: 3
+				}, {
+					label: '点胶注胶',
+					value: 4
+				}, {
+					label: '电子制造服务',
+					value: 5
+				}, {
+					label: '未来服务',
+					value: 6
+				}]
+			}
+		},
+		created() {},
+		methods: {}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.exhibitor-filter{
+		display: grid;
+		grid-template-columns: repeat(3, 1fr);
+		grid-gap: 29rpx;
+		font-size: $fontSize2;
+		color: #333333;
+	}
+</style>

+ 398 - 0
pages/index/home.vue

@@ -0,0 +1,398 @@
+<template>
+	<view class="content">
+		<nav-bar>
+			<view class="top-container">
+				<image class="logo" src="/static/logo.png" />
+				<view class="countdown">
+					距开幕 <view class="days"> 168 </view> 天
+				</view>
+			</view>
+		</nav-bar>
+		<u-swiper :items="images" indicato-dots-style="morphing" :height="387" />
+		<view class="main-container">
+			<view class="search-container">
+				<view class="search-input">
+					<van-search :value="searchKeyword" placeholder="搜索展商 / 展品名称 / 会议" use-action-slot class="van-search">
+						<view class="search-text" slot="action" @tap="onClickSearch">搜索</view>
+					</van-search>
+				</view>
+			</view>
+			<view class="nav-icons">
+				<template v-for="(item, index) in navIcons">
+					<view class="nav-icon-wrapper display-flex-center" :key="index">
+						<view class="nav-icon display-flex-center">
+							<view v-if="item.icon.indexOf('.svg') !== -1" :style="'background-image:url(' + item.icon +  ')'"></view>
+							<view v-else-if="item.icon.indexOf('icon-') !== -1" :class="'iconfont ' + item.icon"></view>
+						</view>
+						<view class="nav-text">
+							{{ item.name }}
+						</view>
+					</view>
+				</template>
+			</view>
+			<u-panel title="精彩视频" link="/pages/components/index">
+				<u-swiper :items="videos" :height="360" :autoplay="false" :border-radius="10" :image-width="508" :image-height="286"
+					next-margin="100rpx" />
+			</u-panel>
+			<u-panel title="精彩图集" link="/pages/components/index">
+				<view class="album">
+					<template v-for="(item, index) in albumPics">
+						<view class="album-pic">
+							<image :src="item.src" mode="aspectFill" />
+						</view>
+					</template>
+				</view>
+			</u-panel>
+			<u-panel title="新闻" link="/pages/components/index">
+				<news-recommend />
+			</u-panel>
+			<u-panel title="战略合作方" link="/pages/components/index">
+				<u-swiper :items="partners" :height="250">
+					<template v-slot="{ scope }">
+						<view class="partners">
+							<template v-for="item in scope.children">
+								<view class="partner">
+									<image :src="item.icon" />
+								</view>
+							</template>
+						</view>
+					</template>
+				</u-swiper>
+			</u-panel>
+			<u-panel title="推荐展商" link="/pages/components/index">
+				<u-swiper :items="partners" :height="250">
+					<template v-slot="{ scope }">
+						<view class="partners">
+							<template v-for="item in scope.children">
+								<view class="partner">
+									<image :src="item.icon" />
+								</view>
+							</template>
+						</view>
+					</template>
+				</u-swiper>
+			</u-panel>
+			<u-panel title="合作媒体" link="/pages/components/index">
+				<u-swiper :items="partners" :autoplay="false" :height="250">
+					<template v-slot="{ scope }">
+						<view class="partners">
+							<template v-for="item in scope.children">
+								<view class="partner">
+									<image :src="item.icon" />
+								</view>
+							</template>
+						</view>
+					</template>
+				</u-swiper>
+			</u-panel>
+		</view>
+	</view>
+</template>
+
+<script>
+	import NavBar from '@/components/layout/nav-bar.vue'
+	import USwiper from '@/components/common/u-swiper/index.vue'
+	import UPanel from '@/components/common/u-panel/index.vue'
+	import NewsRecommend from '@/pages/news/components/news-recommend.vue'
+
+	export default {
+		options: {
+			styleIsolation: 'shared'
+		},
+		components: {
+			NavBar,
+			USwiper,
+			UPanel,
+			NewsRecommend
+		},
+		data() {
+			return {
+				searchKeyword: '',
+				navIcons: [{
+					icon: 'icon-xiaochengxu-guanyuzhanhuiicon',
+					name: '关于展会',
+					url: ''
+				}, {
+					icon: 'icon-xiaochengxu-zhanshangmingluicon',
+					name: '展商名录',
+					url: ''
+				}, {
+					icon: 'icon-zhanpinziliaoicon',
+					name: '展商产品',
+					url: ''
+				}, {
+					icon: 'icon-zhantaihuodongicon',
+					name: '同期活动',
+					url: ''
+				}, {
+					icon: 'icon-zhanshangxinwenicon',
+					name: '展商新闻',
+					url: ''
+				}, {
+					icon: 'icon-xiaochengxu-zhanguanpingmiantuicon',
+					name: '展馆平面图',
+					url: ''
+				}, {
+					icon: 'icon-xiaochengxu-guanzhongzhinanicon',
+					name: '观众指南',
+					url: ''
+				}, {
+					icon: 'icon-xiaochengxu-jiaotongzhinanicon',
+					name: '交通指南',
+					url: ''
+				}],
+				images: [{
+					src: '/static/img/example/banner.png',
+					url: 'https://www.productronicachina.com.cn/',
+					
+				}, {
+					src: '/static/img/example/banner.png',
+					url: 'https://www.productronicachina.com.cn/'
+				}, {
+					src: '/static/img/example/banner.png',
+					url: 'https://www.productronicachina.com.cn/'
+				}],
+				videos: [{
+					src: '/static/img/example/video.jpeg',
+					url: 'https://matchexpo.obs.cn-north-1.myhuaweicloud.com/common/2023/1113/655190052f376.mp4'
+				}, {
+					src: '/static/img/example/video.jpeg',
+					url: 'https://matchexpo.obs.cn-north-1.myhuaweicloud.com/common/2023/1113/655190052f376.mp4'
+				}],
+				albumPics: [{
+					src: '/static/img/example/album/1.jpeg'
+				}, {
+					src: '/static/img/example/album/2.jpeg'
+				}, {
+					src: '/static/img/example/album/3.jpeg'
+				}, {
+					src: '/static/img/example/album/4.jpeg'
+				}, {
+					src: '/static/img/example/album/5.jpeg'
+				}, {
+					src: '/static/img/example/album/6.jpeg'
+				}],
+				// 合作方列表
+				partners: [{
+					name: '第一页',
+					children: [{
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a454718d/1 中国工控网.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b806511810/2 智汇工业.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a4536d7e/4 SMT China&化合物半导体.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a451f071/3 中国电子制造&亚洲控制.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a454718d/1 中国工控网.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b806511810/2 智汇工业.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a4536d7e/4 SMT China&化合物半导体.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a451f071/3 中国电子制造&亚洲控制.png'
+					}]
+				}, {
+					name: '第二页',
+					children: [{
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a454718d/1 中国工控网.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b806511810/2 智汇工业.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a4536d7e/4 SMT China&化合物半导体.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a451f071/3 中国电子制造&亚洲控制.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a454718d/1 中国工控网.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b806511810/2 智汇工业.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a4536d7e/4 SMT China&化合物半导体.png'
+					}, {
+						icon: 'https://www.productronicachina.com.cn/resources/files/0626/667b7a451f071/3 中国电子制造&亚洲控制.png'
+					}]
+				}],
+			}
+		},
+		created() {},
+		methods: {
+			onClickSearch() {
+
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.logo {
+		width: 150rpx;
+		height: 37rpx;
+	}
+
+	.top-container {
+		display: flex;
+		align-items: center;
+		.countdown {
+			display: flex;
+			align-items: center;
+			margin-left: 27rpx;
+			font-size: $fontSize2;
+			.days {
+				color: #F97316;
+				font-size: $fontSize5;
+				font-weight: bold;
+				padding: 0 4rpx;
+			}
+		}
+	}
+
+	.search-container {
+		.search-input {
+			height: 64rpx;
+			border-radius: 50rpx;
+			background-color: #FFFFFF;
+			box-shadow: 0 4rpx 4rpx 0 rgba(0, 0, 0, 0.15);
+			border: 2rpx solid #D9D9D9;
+			padding: 4rpx;
+			overflow: hidden;
+			.van-field__placeholder{
+				font-size: $fontSize1;
+			}
+			.van-cell__left-icon-wrap{
+				height: 50rpx;
+			}
+			.van-field__control{
+				font-size: $fontSize1;
+				height: 50rpx;
+			}
+		}
+		
+		.van-search {
+			--search-padding: 0rpx;
+			--search-input-height: 34rpx;
+			--search-background-color: #FFFFFF;
+			padding-right: 24rpx;
+			font-size: $fontSize1;
+		}
+		.search-text{
+			font-size: $fontSize1;
+		}
+
+		.van-search__action {
+			color: #333333;
+		}
+
+		.van-icon {
+			color: #D4D4D6;
+		}
+
+		.van-cell {
+			padding: 2rpx 0rpx 2rpx !important;
+		}
+	}
+
+	.nav-icons {
+		display: grid;
+		grid-template-columns: 1fr 1fr 1fr 1fr;
+		grid-row-gap: 53rpx;
+		margin-top: 47rpx;
+		margin-bottom: 41rpx;
+
+		.nav-icon-wrapper {
+			flex-direction: column;
+		}
+
+		.nav-text {
+			margin-top: 20rpx;
+			font-size: $fontSize2;
+			color: #555555;
+		}
+
+		.nav-icon {
+			width: 73rpx;
+			height: 73rpx;
+			border-radius: 50%;
+			overflow: hidden;
+			background-color: $buttonPrimaryColor;
+			.iconfont{
+				font-size: 46rpx;
+				color: #FFFFFF;
+			}
+			&>view {
+				width: 46rpx;
+				height: 46rpx;
+				background-size: 46rpx 46rpx;
+			}
+		}
+	}
+
+	.album {
+		display: grid;
+		grid-auto-flow: row;
+		grid-gap: 15rpx;
+		height: 500rpx;
+		width: fit-content;
+		grid-template-areas: "a b b" "c d f" "c e f";
+
+		.album-pic {
+			width: 196rpx;
+			height: 155rpx;
+			border-radius: 10rpx;
+			overflow: hidden;
+
+			&:nth-child(1) {
+				grid-area: a;
+			}
+
+			&:nth-child(2) {
+				width: 418rpx;
+				height: 155rpx;
+				grid-area: b;
+			}
+
+			&:nth-child(3) {
+				grid-area: c;
+			}
+
+			&:nth-child(4) {
+				grid-area: d;
+			}
+
+			&:nth-child(5) {
+				grid-area: e;
+			}
+
+			&:nth-child(6) {
+				grid-area: f;
+			}
+
+			&:nth-child(3),
+			&:nth-child(6) {
+				width: 196rpx;
+				height: 324rpx;
+			}
+		}
+
+		image {
+			width: 100%;
+			height: 100%;
+		}
+	}
+
+	.partners {
+		display: grid;
+		grid-template-columns: repeat(4, 1fr);
+		grid-column-gap: 9rpx;
+		grid-row-gap: 13rpx;
+		.partner{
+			@extend .display-flex-center;
+			width: 150rpx;
+			height: 91rpx;
+		}
+		image {
+			width: 127rpx;
+			height: 25rpx;
+		}
+	}
+	
+</style>

+ 17 - 54
pages/index/index.vue

@@ -1,75 +1,38 @@
 <template>
 	<view class="content">
-		<nav-bar></nav-bar>
-		<view class="main">
-			{{ $t('common.close') }}
-		</view>
-		<van-button type="primary" @click="selectLanguage('zh-cn')">中文</van-button>
-		<van-button type="warning" @click="selectLanguage('en-us')">英文</van-button>
-		<van-tabbar :active="active" @change="onChange" :placeholder="true" active-color="#3856ff" inactive-color="#666666">
-			<van-tabbar-item v-for="(item, index) in list" :name="item.name" :key="index" :icon="item.icon">
-				{{ item.text }}
-			</van-tabbar-item>
-		</van-tabbar>
+		<home v-if="tabbarActive === 'home'" />
+		<exhibitor v-if="tabbarActive === 'exhibitor'" />
+		<tab-bar :active.sync="tabbarActive"></tab-bar>
 	</view>
 </template>
 
 <script>
-	import { setLocale } from '../../locales/i18n'
-import {
-		login
-	} from '@/api/user'
-	import NavBar from '@/components/layout/nav-bar.vue'
+	import TabBar from '@/components/layout/tab-bar.vue'
+	import Home from '@/pages/index/home.vue'
+	import Exhibitor from '@/pages/exhibitor/index.vue'
 
 	export default {
+		options: {
+			// styleIsolation: 'shared'
+		},
 		components: {
-			NavBar
+			TabBar,
+			Home,
+			Exhibitor
 		},
 		data() {
 			return {
-				active: 'home',
-				title: 'Hello',
-				list: [{
-						name: 'home',
-						icon: 'home-o',
-						text: '首页',
-						url: '/pages/index'
-					}, {
-						name: 'search',
-						icon: 'search',
-						text: '示例2',
-						url: '/pages/signup/signup'
-					},
-					{
-						name: 'friends',
-						icon: 'friends-o',
-						text: '示例3',
-						url: '/pages/test'
-					},
-					{
-						name: 'setting',
-						icon: 'setting-o',
-						text: '示例3',
-						url: '/pages/test'
-					}
-				]
+				tabbarActive: 'home'
 			}
 		},
-		created() {
-			const apiUrl = process.env.BASE_API
-			console.log('当前环境的API URL: ', apiUrl)
-			console.log(uni.getLocale())
-		},
+		created() {},
 		methods: {
-			onChange(e) {
-				this.active = e.detail
-			},
-			selectLanguage(language) {
-				setLocale(language)
+			onClickSearch() {
+
 			}
 		}
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 </style>

+ 38 - 0
pages/index/webview.vue

@@ -0,0 +1,38 @@
+<template>
+	<view class="webview-container">
+		<web-view class="webview" :src="url"></web-view>
+	</view>
+</template>
+
+<script>
+	import NavBar from '@/components/layout/nav-bar.vue'
+
+	export default {
+		components: {
+			NavBar
+		},
+		data() {
+			return {
+				url: ''
+			}
+		},
+		onLoad(options) {
+			this.url = options.url
+			console.log(options.url)
+		},
+		created() {
+		},
+		methods: {
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.webview-container{
+		display: flex;
+		flex-direction: column;
+	}
+	.webview{
+		flex: 1;
+	}
+</style>

+ 109 - 0
pages/news/components/news-recommend.vue

@@ -0,0 +1,109 @@
+<template>
+	<view class="news-recommend">
+		<view class="news-tab">
+			<u-tabs :active.sync="tabActive" :tabs="tabs" tab-style="default" @change="tabChange"/>
+		</view>
+		<view class="news-list">
+			<template v-for="item in [1, 2, 3]">
+					<view class="news-item">
+						<view class="news-title">组装自动化与测试测量深度融合,赋能电子制造业高质量发展2024</view>
+						<view class="news-time">2024年6月28日</view>
+						<view class="news-summary">
+							<view class="text">在人类历史长河中,工业生产一直是社会进步的重要驱动力,而自动化技术的飞速发展,使其正在经历前所未有的变革。特别是在电子生产制造领域,传统的人工操作由于易疲劳、品质不稳定以及</view>
+							<view class="to-detail"><view>了解详情</view> <view class="arrow iconfont icon-a-righticon_huaban11"></view></view>
+						</view>
+					</view>
+			</template>
+		</view>
+	</view>
+</template>
+
+<script>
+	import UTabs from '@/components/common/u-tabs/index.vue'
+	
+	export default {
+		components: {
+			UTabs
+		},
+		data() {
+			return {
+				tabActive: '1',
+				tabs: [{
+					label: '展会新闻',
+					value: 1
+				}, {
+					label: '展商新闻',
+					value: 2
+				}]
+			}
+		},
+		created() {
+		},
+		methods: {
+			tabChange() {
+				
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.news-list{
+		display: grid;
+		grid-template-columns: 1fr;
+		grid-row-gap: 18rpx;
+		margin-top: 28rpx;
+	}
+	.news-item{
+		display: flex;
+		flex-direction: column;
+		height: 210rpx;
+		background-color: #F6F6F6;
+		border-radius: 10rpx;
+		padding: 24rpx 30rpx;
+	}
+	.news-summary{
+		display: flex;
+		align-items: center;
+	}
+	.news-title{
+		@extend .text-ellipsis-line;
+		font-family: Arial, Arial;
+		font-weight: bold;
+		font-size: $fontSize2;
+		line-height: 35rpx;
+	}
+	.news-time{
+		font-size: $fontSize0;
+		color: #555555;
+		margin: 12rpx 0;
+	}
+	.news-summary{
+		font-size: 18rpx;
+		line-height: 25rpx;
+		.text{
+			padding-right: 30rpx;
+			color: #555555;
+			@extend .text-ellipsis-line;
+			-webkit-line-clamp: 2;  
+		}
+		.to-detail{
+			display: flex;
+			align-items: center;
+			flex-shrink: 0;
+			color: $buttonPrimaryColor;
+			font-size: 16rpx;
+			font-weight: bold;
+			padding: 0 24rpx;
+		}
+		.arrow{
+			margin-left: 12rpx;
+			font-size: $fontSize0;
+		}
+	}
+	
+	.news-tab{
+		van-button{
+			margin-right: 13rpx;
+		}
+	}
+</style>

+ 539 - 0
static/font/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

File diff suppressed because it is too large
+ 5732 - 0
static/font/demo_index.html


+ 980 - 0
static/font/iconfont.css

@@ -0,0 +1,980 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 4563472 */
+  src: url('~@/static/font/iconfont.woff2') format('woff2'),
+       url('~@/static/font/iconfont.woff') format('woff'),
+       url('~@/static/font/iconfont.ttf') format('truetype'),
+       url('~@/static/font/iconfont.svg') format('svg');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-xiaochengxu-renqiicon:before {
+  content: "\e693";
+}
+
+.icon-xiaochengxu-fubiaoguanliicon:before {
+  content: "\e692";
+}
+
+.icon-xiaochengxu-tiaokuanguanliicon:before {
+  content: "\e690";
+}
+
+.icon-xiaochengxu-guanggaoguanliicon:before {
+  content: "\e691";
+}
+
+.icon-xiaochengxu-danchuangguanliicon:before {
+  content: "\e68f";
+}
+
+.icon-xiaochengxu-toupiaoicon:before {
+  content: "\e68e";
+}
+
+.icon-xiaochengxu-guanzhongyudengjiicon:before {
+  content: "\e68d";
+}
+
+.icon-xiaochengxu-gerenzhongxinicon:before {
+  content: "\e68c";
+}
+
+.icon-xiaochengxu-jiaotongzhinanicon:before {
+  content: "\e68b";
+}
+
+.icon-xiaochengxu-guanzhongzhinanicon:before {
+  content: "\e68a";
+}
+
+.icon-xiaochengxu-zhanguanpingmiantuicon:before {
+  content: "\e689";
+}
+
+.icon-xiaochengxu-zhanshangmingluicon:before {
+  content: "\e688";
+}
+
+.icon-xiaochengxu-guanyuzhanhuiicon:before {
+  content: "\e687";
+}
+
+.icon-qiyehaibaodingzhiicon:before {
+  content: "\e686";
+}
+
+.icon-xiazaizhongxinicon1:before {
+  content: "\e685";
+}
+
+.icon-guibinguanzhongyaoqingicon:before {
+  content: "\e683";
+}
+
+.icon-xiongkashenqingicon:before {
+  content: "\e682";
+}
+
+.icon-zhantaihuodongicon:before {
+  content: "\e681";
+}
+
+.icon-zhanshangxinwenicon:before {
+  content: "\e680";
+}
+
+.icon-zhanpinziliaoicon:before {
+  content: "\e67f";
+}
+
+.icon-zhanshangzhongxinzonglanicon:before {
+  content: "\e67e";
+}
+
+.icon-zhanshangxinxiicon:before {
+  content: "\e67d";
+}
+
+.icon-xinwen:before {
+  content: "\e667";
+}
+
+.icon-xitongxiaoxishezhi:before {
+  content: "\e726";
+}
+
+.icon-a-righticon_huaban11:before {
+  content: "\e679";
+}
+
+.icon-a-righticon_huaban11-copy:before {
+  content: "\ee4a";
+}
+
+.icon-a-righticon_huaban1:before {
+  content: "\e678";
+}
+
+.icon-a-righticon_huaban1-copy:before {
+  content: "\ee4b";
+}
+
+.icon-wechat-fill:before {
+  content: "\e885";
+}
+
+.icon-lingying:before {
+  content: "\ee48";
+}
+
+.icon-a-Top100:before {
+  content: "\e666";
+}
+
+.icon-qiyeku:before {
+  content: "\e665";
+}
+
+.icon-gongsiku:before {
+  content: "\e664";
+}
+
+.icon-Record:before {
+  content: "\e87c";
+}
+
+.icon-Registration:before {
+  content: "\e87d";
+}
+
+.icon-Pause-Circle:before {
+  content: "\e87e";
+}
+
+.icon-Bookmark:before {
+  content: "\e87f";
+}
+
+.icon-Bookmark-Filled:before {
+  content: "\e880";
+}
+
+.icon-Sound:before {
+  content: "\e881";
+}
+
+.icon-Map:before {
+  content: "\e837";
+}
+
+.icon-Route:before {
+  content: "\e838";
+}
+
+.icon-Print:before {
+  content: "\e83a";
+}
+
+.icon-Transport:before {
+  content: "\e83b";
+}
+
+.icon-Edit:before {
+  content: "\e842";
+}
+
+.icon-GeoLocation:before {
+  content: "\e851";
+}
+
+.icon-Share:before {
+  content: "\e863";
+}
+
+.icon-Search:before {
+  content: "\e86f";
+}
+
+.icon-BookmarkCheck:before {
+  content: "\e87a";
+}
+
+.icon-Archive:before {
+  content: "\e835";
+}
+
+.icon-Play-Circle:before {
+  content: "\e87b";
+}
+
+.icon-Vector:before {
+  content: "\e662";
+}
+
+.icon-Placeholder-Icon:before {
+  content: "\e663";
+}
+
+.icon-Favourites-Add-Alt-Large:before {
+  content: "\e660";
+}
+
+.icon-Favourites-Add-Large:before {
+  content: "\e661";
+}
+
+.icon-a-MecialMask:before {
+  content: "\e65f";
+}
+
+.icon-Exclamation-Circle-Large-1:before {
+  content: "\e883";
+}
+
+.icon-Checkmak-Circle-Large:before {
+  content: "\e65d";
+}
+
+.icon-Exclamation-Circle-Large:before {
+  content: "\e65e";
+}
+
+.icon-Calendar-No-Slots-Large:before {
+  content: "\e65b";
+}
+
+.icon-Calendar-Add-Large:before {
+  content: "\e65c";
+}
+
+.icon-Rocket-Launch-Large:before {
+  content: "\e65a";
+}
+
+.icon-medium:before {
+  content: "\e657";
+}
+
+.icon-a-XehemalsTwitter:before {
+  content: "\e658";
+}
+
+.icon-Vimeo:before {
+  content: "\e659";
+}
+
+.icon-a-ThumbUp:before {
+  content: "\e655";
+}
+
+.icon-a-ThumbDown:before {
+  content: "\e656";
+}
+
+.icon-Soundcloud:before {
+  content: "\e652";
+}
+
+.icon-Spotify:before {
+  content: "\e653";
+}
+
+.icon-Deezer:before {
+  content: "\e654";
+}
+
+.icon-Pinterest:before {
+  content: "\e64f";
+}
+
+.icon-Xing:before {
+  content: "\e650";
+}
+
+.icon-Apple-Podcast:before {
+  content: "\e651";
+}
+
+.icon-Podigee:before {
+  content: "\e64e";
+}
+
+.icon-Instagram1:before {
+  content: "\e64b";
+}
+
+.icon-Facebook1:before {
+  content: "\e64c";
+}
+
+.icon-a-Registration2:before {
+  content: "\e64d";
+}
+
+.icon-Instagram:before {
+  content: "\e646";
+}
+
+.icon-Facebook:before {
+  content: "\e648";
+}
+
+.icon-YouTube-Block:before {
+  content: "\e649";
+}
+
+.icon-YouTube:before {
+  content: "\e64a";
+}
+
+.icon-Exhibitor:before {
+  content: "\e642";
+}
+
+.icon-Chairman:before {
+  content: "\e643";
+}
+
+.icon-AddContact:before {
+  content: "\e644";
+}
+
+.icon-Group:before {
+  content: "\e645";
+}
+
+.icon-DeleteContact:before {
+  content: "\e647";
+}
+
+.icon-Profile:before {
+  content: "\e641";
+}
+
+.icon-Contacts:before {
+  content: "\e63e";
+}
+
+.icon-Speaker:before {
+  content: "\e63f";
+}
+
+.icon-User-Placeholder:before {
+  content: "\e640";
+}
+
+.icon-CalendarCheck1:before {
+  content: "\e63d";
+}
+
+.icon-Mobility:before {
+  content: "\e638";
+}
+
+.icon-Car:before {
+  content: "\e639";
+}
+
+.icon-Plane:before {
+  content: "\e63a";
+}
+
+.icon-Train:before {
+  content: "\e63b";
+}
+
+.icon-Bus:before {
+  content: "\e63c";
+}
+
+.icon-HourglassFull:before {
+  content: "\e637";
+}
+
+.icon-Clock:before {
+  content: "\e636";
+}
+
+.icon-Calendar:before {
+  content: "\e632";
+}
+
+.icon-CalendarPending:before {
+  content: "\e633";
+}
+
+.icon-CalendarDelete:before {
+  content: "\e634";
+}
+
+.icon-Date:before {
+  content: "\e635";
+}
+
+.icon-CalendarAdd1:before {
+  content: "\e631";
+}
+
+.icon-CalendarAdd:before {
+  content: "\e62d";
+}
+
+.icon-Wait:before {
+  content: "\e62e";
+}
+
+.icon-Hourglass:before {
+  content: "\e62f";
+}
+
+.icon-CalendarCheck:before {
+  content: "\e630";
+}
+
+.icon-Unlocked:before {
+  content: "\e62b";
+}
+
+.icon-Locked:before {
+  content: "\e62c";
+}
+
+.icon-Flag:before {
+  content: "\e62a";
+}
+
+.icon-Rocket:before {
+  content: "\e623";
+}
+
+.icon-Present:before {
+  content: "\e628";
+}
+
+.icon-Light:before {
+  content: "\e629";
+}
+
+.icon-World:before {
+  content: "\e624";
+}
+
+.icon-Award:before {
+  content: "\e625";
+}
+
+.icon-Ticket:before {
+  content: "\e626";
+}
+
+.icon-Beverages:before {
+  content: "\e627";
+}
+
+.icon-Compass:before {
+  content: "\e619";
+}
+
+.icon-Mountain:before {
+  content: "\e61a";
+}
+
+.icon-Diamond:before {
+  content: "\e61b";
+}
+
+.icon-Star-Filled:before {
+  content: "\e61c";
+}
+
+.icon-Beer:before {
+  content: "\e61d";
+}
+
+.icon-Food:before {
+  content: "\e61e";
+}
+
+.icon-Shopping:before {
+  content: "\e61f";
+}
+
+.icon-Star:before {
+  content: "\e620";
+}
+
+.icon-megaphone:before {
+  content: "\e621";
+}
+
+.icon-Heart:before {
+  content: "\e622";
+}
+
+.icon-FilterHoriz:before {
+  content: "\e618";
+}
+
+.icon-Exit:before {
+  content: "\e60b";
+}
+
+.icon-Left-1:before {
+  content: "\e884";
+}
+
+.icon-Center:before {
+  content: "\e60c";
+}
+
+.icon-Down:before {
+  content: "\e60d";
+}
+
+.icon-FullscreenExit:before {
+  content: "\e60e";
+}
+
+.icon-Filter:before {
+  content: "\e60f";
+}
+
+.icon-DownSmall:before {
+  content: "\e610";
+}
+
+.icon-FullscreenEnter:before {
+  content: "\e611";
+}
+
+.icon-LeftSmall:before {
+  content: "\e612";
+}
+
+.icon-Grid:before {
+  content: "\e613";
+}
+
+.icon-Left:before {
+  content: "\e614";
+}
+
+.icon-PointMenu:before {
+  content: "\e615";
+}
+
+.icon-PictureInPicture:before {
+  content: "\e616";
+}
+
+.icon-BackToSource-1:before {
+  content: "\e617";
+}
+
+.icon-Cancel-copy:before {
+  content: "\ee4c";
+}
+
+.icon-DotMenu:before {
+  content: "\e607";
+}
+
+.icon-BurgerMenu:before {
+  content: "\e608";
+}
+
+.icon-Cancel:before {
+  content: "\e609";
+}
+
+.icon-DotMenuHoriz:before {
+  content: "\e60a";
+}
+
+.icon-ArrowRight:before {
+  content: "\e604";
+}
+
+.icon-ArrowLeft:before {
+  content: "\e603";
+}
+
+.icon-BackToSource:before {
+  content: "\e606";
+}
+
+.icon-ArrowUp:before {
+  content: "\e605";
+}
+
+.icon-BackToSource-copy:before {
+  content: "\e882";
+}
+
+.icon-ArrowDown:before {
+  content: "\e602";
+}
+
+.icon-Apps:before {
+  content: "\e601";
+}
+
+.icon-MailOpen:before {
+  content: "\e84d";
+}
+
+.icon-Desktop:before {
+  content: "\e86d";
+}
+
+.icon-Workshop:before {
+  content: "\e867";
+}
+
+.icon-Presentation:before {
+  content: "\e860";
+}
+
+.icon-Percent:before {
+  content: "\e85f";
+}
+
+.icon-Cards1:before {
+  content: "\e879";
+}
+
+.icon-Card:before {
+  content: "\e865";
+}
+
+.icon-Notification:before {
+  content: "\e85a";
+}
+
+.icon-a-Iconsource:before {
+  content: "\e878";
+}
+
+.icon-Apple:before {
+  content: "\e873";
+}
+
+.icon-Office365:before {
+  content: "\e874";
+}
+
+.icon-Google-Calendar:before {
+  content: "\e875";
+}
+
+.icon-ICS:before {
+  content: "\e876";
+}
+
+.icon-a-LocationPlaceholder:before {
+  content: "\e877";
+}
+
+.icon-a-101_twitter:before {
+  content: "\e871";
+}
+
+.icon-a-92_twitter:before {
+  content: "\e872";
+}
+
+.icon-a-Size180:before {
+  content: "\e870";
+}
+
+.icon-Graph2:before {
+  content: "\e862";
+}
+
+.icon-Graph:before {
+  content: "\e864";
+}
+
+.icon-Hybrid:before {
+  content: "\e866";
+}
+
+.icon-Chatbot:before {
+  content: "\e868";
+}
+
+.icon-Mail:before {
+  content: "\e869";
+}
+
+.icon-Inbox:before {
+  content: "\e86a";
+}
+
+.icon-Fax:before {
+  content: "\e86b";
+}
+
+.icon-Live:before {
+  content: "\e86c";
+}
+
+.icon-VIP:before {
+  content: "\e86e";
+}
+
+.icon-Briefcase:before {
+  content: "\e852";
+}
+
+.icon-Alert:before {
+  content: "\e853";
+}
+
+.icon-Y-Axis:before {
+  content: "\e854";
+}
+
+.icon-NotificationsOff:before {
+  content: "\e855";
+}
+
+.icon-Bill:before {
+  content: "\e856";
+}
+
+.icon-VideoDisabled:before {
+  content: "\e857";
+}
+
+.icon-Yahoo:before {
+  content: "\e858";
+}
+
+.icon-Stop:before {
+  content: "\e859";
+}
+
+.icon-Error:before {
+  content: "\e85b";
+}
+
+.icon-Match:before {
+  content: "\e85c";
+}
+
+.icon-Partners:before {
+  content: "\e85d";
+}
+
+.icon-Fee:before {
+  content: "\e85e";
+}
+
+.icon-Graph3:before {
+  content: "\e861";
+}
+
+.icon-Message1:before {
+  content: "\e84a";
+}
+
+.icon-MailSent:before {
+  content: "\e84b";
+}
+
+.icon-Smartphone:before {
+  content: "\e84c";
+}
+
+.icon-Phone:before {
+  content: "\e84e";
+}
+
+.icon-Senden:before {
+  content: "\e84f";
+}
+
+.icon-Message-Filled:before {
+  content: "\e850";
+}
+
+.icon-CheckCircle-Filled:before {
+  content: "\e848";
+}
+
+.icon-Check:before {
+  content: "\e849";
+}
+
+.icon-Attachment:before {
+  content: "\e83c";
+}
+
+.icon-Folder:before {
+  content: "\e83d";
+}
+
+.icon-Filled:before {
+  content: "\e83e";
+}
+
+.icon-Blank:before {
+  content: "\e83f";
+}
+
+.icon-Circle:before {
+  content: "\e840";
+}
+
+.icon-Info:before {
+  content: "\e841";
+}
+
+.icon-DownloadCompletet:before {
+  content: "\e843";
+}
+
+.icon-Download:before {
+  content: "\e844";
+}
+
+.icon-Delete:before {
+  content: "\e845";
+}
+
+.icon-Copy:before {
+  content: "\e846";
+}
+
+.icon-CheckCircle:before {
+  content: "\e847";
+}
+
+.icon-Translate:before {
+  content: "\e82e";
+}
+
+.icon-Volume-Mute:before {
+  content: "\e82f";
+}
+
+.icon-Volume-Low:before {
+  content: "\e831";
+}
+
+.icon-Typing:before {
+  content: "\e832";
+}
+
+.icon-Volume:before {
+  content: "\e833";
+}
+
+.icon-View:before {
+  content: "\e834";
+}
+
+.icon-Video:before {
+  content: "\e836";
+}
+
+.icon-Table:before {
+  content: "\e839";
+}
+
+.icon-Building1:before {
+  content: "\e82d";
+}
+
+.icon-Target:before {
+  content: "\e827";
+}
+
+.icon-MapCluster:before {
+  content: "\e828";
+}
+
+.icon-Home:before {
+  content: "\e829";
+}
+
+.icon-Factory:before {
+  content: "\e82a";
+}
+
+.icon-Building2:before {
+  content: "\e82c";
+}
+
+.icon-Booth:before {
+  content: "\e81e";
+}
+
+.icon-Upload:before {
+  content: "\e81f";
+}
+
+.icon-Settings:before {
+  content: "\e812";
+}
+
+.icon-Shuffle:before {
+  content: "\e820";
+}
+
+.icon-Spinner:before {
+  content: "\e821";
+}
+
+.icon-Reload:before {
+  content: "\e822";
+}
+
+.icon-Replay:before {
+  content: "\e823";
+}
+
+.icon-Link-Broken:before {
+  content: "\e814";
+}
+
+.icon-Picture:before {
+  content: "\e815";
+}
+
+.icon-Plus:before {
+  content: "\e816";
+}
+
+.icon-Photo:before {
+  content: "\e817";
+}
+
+.icon-Play:before {
+  content: "\e819";
+}
+
+.icon-Pause:before {
+  content: "\e81b";
+}
+
+.icon-Link:before {
+  content: "\e81c";
+}
+
+.icon-Minus:before {
+  content: "\e81d";
+}
+
+.icon-oe-a:before {
+  content: "\e802";
+}
+

File diff suppressed because it is too large
+ 1 - 0
static/font/iconfont.js


File diff suppressed because it is too large
+ 1696 - 0
static/font/iconfont.json


File diff suppressed because it is too large
+ 501 - 0
static/font/iconfont.svg


BIN
static/font/iconfont.ttf


BIN
static/font/iconfont.woff


BIN
static/font/iconfont.woff2


BIN
static/img/example/album/1.jpeg


BIN
static/img/example/album/2.jpeg


BIN
static/img/example/album/3.jpeg


BIN
static/img/example/album/4.jpeg


BIN
static/img/example/album/5.jpeg


BIN
static/img/example/album/6.jpeg


BIN
static/img/example/banner.png


File diff suppressed because it is too large
+ 1 - 0
static/img/example/icon/car_line.svg


+ 29 - 0
static/img/example/icon/event.svg

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#ffffff;}
+</style>
+<g>
+	<path class="st0" d="M739.92,110.02l-13.44,11.2c-3.8,3.18-9.32,3.23-13.18,0.1l-51.56-41.25c-26.67-21.3-64.48-21.3-91.15,0
+		l-52.08,41.72c-3.8,3.02-9.22,3.02-13.02,0l-52.08-41.72c-26.67-21.3-64.48-21.3-91.15,0l-51.56,41.25
+		c-3.85,3.13-9.38,3.07-13.18-0.1l-13.44-11.2c-54.27-45.26-136.67-6.67-136.67,64.01v675.94c0,70.68,82.4,109.27,136.67,64.01
+		l13.44-11.2c3.8-3.18,9.32-3.23,13.18-0.1l51.56,41.25c26.67,21.3,64.48,21.3,91.15,0l52.08-41.72c3.8-3.02,9.22-3.02,13.02,0
+		l52.08,41.72c26.67,21.3,64.48,21.3,91.15,0l51.56-41.25c3.85-3.13,9.38-3.07,13.18,0.1l13.44,11.2
+		c54.27,45.26,136.67,6.67,136.67-64.01V174.03C876.58,103.35,794.19,64.76,739.92,110.02z M814.08,849.97
+		c0,17.66-20.62,27.29-34.17,15.99l-13.44-11.2c-26.62-22.19-65.16-22.55-92.24-0.89l-51.56,41.25c-3.8,3.02-9.22,3.02-13.02,0
+		l-52.08-41.72c-26.67-21.3-64.48-21.3-91.15,0l-52.08,41.72c-3.8,3.02-9.22,3.02-13.02,0l-51.56-41.25
+		c-27.08-21.67-65.63-21.3-92.24,0.89l-13.44,11.2c-13.54,11.3-34.17,1.67-34.17-15.99V174.03c0-17.66,20.62-27.29,34.17-15.99
+		l13.44,11.2c26.61,22.19,65.16,22.55,92.24,0.89l51.56-41.25c3.8-3.02,9.22-3.02,13.02,0l52.08,41.72
+		c26.67,21.3,64.48,21.3,91.15,0l52.08-41.72c3.8-3.02,9.22-3.02,13.02,0l51.56,41.25c27.08,21.67,65.63,21.3,92.24-0.89l13.44-11.2
+		c13.54-11.3,34.17-1.67,34.17,15.99V849.97z"/>
+	<path class="st0" d="M686.27,440l-99.43-24.84l-48.85-73.28c-5.78-8.7-15.52-13.91-25.99-13.91c-10.47,0-20.21,5.21-25.99,13.91
+		l-48.85,73.28L337.73,440c-10.89,2.76-19.53,11.15-22.5,21.98c-3.02,10.83,0.05,22.5,8.02,30.47l70.83,70.78l-23.49,93.96
+		c-2.87,11.46,0.94,23.59,9.9,31.25c8.96,7.71,21.51,9.74,32.4,5.21l99.11-41.3l99.11,41.3c10.89,4.53,23.44,2.5,32.4-5.21
+		c8.96-7.66,12.76-19.79,9.9-31.25l-23.49-93.96l70.83-70.78c7.97-7.97,11.04-19.64,8.02-30.47
+		C705.8,451.15,697.16,442.76,686.27,440z M573.25,531.56c-7.76,7.76-10.89,19.01-8.23,29.69l12.71,50.73l-53.7-22.34
+		c-7.71-3.23-16.36-3.23-24.06,0l-53.7,22.34l12.71-50.73c2.66-10.68-0.47-21.93-8.23-29.69l-44.27-44.32l57.55-14.38
+		c7.55-1.88,14.11-6.51,18.44-12.97L512,415.57l29.53,44.32c4.32,6.46,10.89,11.09,18.44,12.97l57.55,14.38L573.25,531.56z"/>
+</g>
+</svg>

+ 25 - 0
static/img/example/icon/house.svg

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#ffffff;}
+</style>
+<path class="st0" d="M953.92,328.06c-3.18-15-7.66-32.81-12.66-51.72c-10.05-37.92-22.81-81.25-33.54-116.82
+	c-17.19-56.82-69.69-94.95-128.54-94.95H243.97c-58.85,0-111.35,38.12-128.54,94.95c-10.73,35.57-23.49,78.91-33.54,116.82
+	c-5,18.91-9.48,36.72-12.66,51.72c-3.02,14.01-5.57,28.28-5.57,38.59c0,70.73,27.6,115.52,62.5,142.19v274.48
+	c0,97.81,79.27,177.08,177.08,177.08h135.19v-73.93h0.23V741.66c0-17.24,14.01-31.25,31.25-31.25h83.33
+	c17.24,0,31.25,14.01,31.25,31.25v144.82h0v73.93h135.42c97.81,0,177.08-79.27,177.08-177.08V509.16
+	c34.95-26.67,62.5-71.56,62.5-142.5C959.49,356.34,956.94,342.07,953.92,328.06z M834.49,783.32c0,63.28-51.3,114.58-114.58,114.58
+	h-72.92V741.66c0-51.77-41.98-93.75-93.75-93.75h-83.33c-51.77,0-93.75,41.98-93.75,93.75v156.25h-72.92
+	c-63.28,0-114.58-51.3-114.58-114.58v-244.9c12.81,3.18,23.39,4.43,29.69,4.95c4.06,0.31,8.07,0.52,12.19,0.62
+	c19.64,0.57,87.86-1.88,135.99-57.71c37.5,40.78,92.5,60.05,145.05,60.05s107.6-19.27,145.1-60.1
+	c48.07,55.78,116.35,58.33,136.15,57.81c4.22-0.16,8.33-0.37,12.55-0.68c6.25-0.52,16.62-1.72,29.12-4.79V783.32z M856.73,461.24
+	c-21.56,15.36-46.3,19.06-56.25,19.84c-3.12,0.21-6.2,0.36-9.32,0.47c-18.23,0.47-77.6-2.97-105.21-65.1
+	c-5-11.25-16.09-18.49-28.39-18.54c-12.34-0.05-23.49,7.14-28.59,18.33c-19.74,43.39-66.41,67.6-117.4,67.6s-97.66-24.22-117.4-67.6
+	c-5.1-11.2-16.25-18.39-28.59-18.33c-12.29,0.05-23.39,7.29-28.39,18.54c-27.71,62.29-86.98,65.62-104.9,65.1
+	c-3.02-0.1-5.99-0.26-9.01-0.47c-9.9-0.78-34.79-4.48-56.56-19.95c-19.9-14.11-40.57-40.36-40.57-94.48
+	c0-2.81,1.09-11.04,4.17-25.52c2.92-13.54,7.08-30.31,11.98-48.75c9.79-36.88,22.29-79.43,32.97-114.79
+	c9.06-30,36.88-50.52,68.7-50.52h535.21c31.82,0,59.64,20.52,68.7,50.52c10.68,35.37,23.18,77.92,32.97,114.79
+	c4.9,18.44,9.06,35.21,11.98,48.75c3.07,14.48,4.17,22.71,4.17,25.52C896.99,420.93,876.42,447.18,856.73,461.24z"/>
+</svg>

+ 17 - 0
static/img/example/icon/layers.svg

@@ -0,0 +1,17 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729242510996"
+	class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2977"
+	xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
+	<path
+		fill="#ffffff"
+		d="M106.88 317.76l400 184a41.6 41.6 0 0 0 17.6 3.84 39.68 39.68 0 0 0 16-3.2l375.36-160a40.96 40.96 0 0 0 25.28-36.8 41.6 41.6 0 0 0-22.72-38.72l-384-192a42.88 42.88 0 0 0-34.88 0L107.84 241.92a41.6 41.6 0 0 0 0 75.84z m408-160L800 301.44l-275.52 117.12-297.6-137.28z"
+		p-id="2978"></path>
+	<path
+	fill="#ffffff"
+		d="M883.52 490.56l-358.4 152-384-176.32a41.6 41.6 0 0 0-34.88 75.52l400 184a41.6 41.6 0 0 0 17.6 3.84 39.68 39.68 0 0 0 16-3.2l375.36-160a41.6 41.6 0 0 0-32-76.48z"
+		p-id="2979"></path>
+	<path
+		fill="#ffffff"
+		d="M883.52 714.56l-358.4 152-384-176.32a41.6 41.6 0 0 0-34.88 75.52l400 184a41.6 41.6 0 0 0 17.6 3.84 39.68 39.68 0 0 0 16-3.2l375.36-160a41.6 41.6 0 1 0-32-76.48z"
+		p-id="2980"></path>
+</svg>

File diff suppressed because it is too large
+ 9 - 0
static/img/example/icon/list.svg


+ 21 - 0
static/img/example/icon/news.svg

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:#ffffff;}
+</style>
+<g>
+	<path class="st0" d="M907.83,522.42H772.42V199.4c0-74.84-60.68-135.31-135.42-135.31H199.5c-74.79,0-135.42,60.62-135.42,135.42
+		v583.33c0,97.81,79.27,177.08,177.08,177.08H824.5c1.15,0,2.34-0.05,3.49-0.21c2.29,0.16,4.58,0.21,6.93,0.21
+		c69.01,0,125-55.99,125-125V574.5C959.92,545.75,936.58,522.42,907.83,522.42z M241.17,897.42c-63.28,0-114.58-51.3-114.58-114.58
+		V199.5c0-40.26,32.66-72.92,72.92-72.92H637c40.31,0,72.92,32.6,72.92,72.81v635.52c0,22.76,6.09,44.11,16.72,62.5H241.17z
+		 M897.42,834.92c0,34.53-27.97,62.5-62.5,62.5c-34.53,0-62.5-27.97-62.5-62.5v-250h125V834.92z"/>
+	<path class="st0" d="M579.77,309.07h-312.5c-17.24,0-31.25,14.01-31.25,31.25c0,17.24,14.01,31.25,31.25,31.25h312.5
+		c17.24,0,31.25-14.01,31.25-31.25C611.02,323.08,597.01,309.07,579.77,309.07z"/>
+	<path class="st0" d="M579.77,475.74h-312.5c-17.24,0-31.25,14.01-31.25,31.25s14.01,31.25,31.25,31.25h312.5
+		c17.24,0,31.25-14.01,31.25-31.25S597.01,475.74,579.77,475.74z"/>
+	<path class="st0" d="M413.11,642.4H267.27c-17.24,0-31.25,14.01-31.25,31.25s14.01,31.25,31.25,31.25h145.83
+		c17.24,0,31.25-14.01,31.25-31.25S430.35,642.4,413.11,642.4z"/>
+</g>
+</svg>

BIN
static/img/example/video.jpeg


BIN
static/logo.jpg


BIN
static/logo.png


+ 72 - 0
static/style/app.scss

@@ -0,0 +1,72 @@
+@import "~@/static/font/iconfont.css";
+
+.tabbar-icon {
+  font-family: "iconfont";
+}
+.tabbar-icon-home::before {
+  content: "\e67e";
+}
+.tabbar-icon-exhibitor::before{
+	content: "\e682";
+}
+.tabbar-icon-activity::before{
+	content: "\e681";
+}
+.tabbar-icon-user::before{
+	content: "\e68c";
+}
+.tabbar-icon-registration:before{
+	content: "\e68d";
+}
+
+$fontSize1: 20rpx;
+$fontSize2: 24rpx;
+$fontSize3: 28rpx;
+$fontSize4: 32rpx;
+$fontSize5: 36rpx;
+
+* {
+	font-family: Inter, Inter;
+	box-sizing: border-box;
+}
+view,input{
+  box-sizing: border-box;
+	font-family: Inter, Inter;
+}
+.main-container {
+	padding: 30rpx;
+}
+// 字体大小
+.font-size-1{
+	font-size: $fontSize1;
+}
+.font-size-2{
+	font-size: $fontSize2;
+}
+.font-size-3{
+	font-size: $fontSize3;
+}
+.font-size-4{
+	font-size: $fontSize4;
+}
+.font-size-5{
+	font-size: $fontSize5;
+}
+
+.van-button{
+	font-size: 20rpx;
+}
+.van-button--primary {
+	--button-primary-background-color: #E57519;
+	--button-primary-border-color: #E57519;
+	--button-primary-color: #ffffff;
+	--button-border-radius: 6rpx;
+	--button-default-height: 50rpx;
+}
+.van-button--default {
+	--button-primary-background-color: #FFFFFF;
+	--button-primary-border-color: #7D7D7D;
+	--button-primary-color: #ffffff;
+	--button-border-radius: 6rpx;
+	--button-default-height: 50rpx;
+}

+ 48 - 1
uni.scss

@@ -1 +1,48 @@
-$primary-color: #123456;
+// 继承样式
+$primaryColor: #123456;
+$buttonPrimaryColor: #E57519;
+$textActionColor: #E57519;
+$border: 2rpx solid #aaaaaa;
+$borderLight: 2rpx solid #dddddd;
+$bgLightColor: #F5F5F5;
+
+$fontSize0: 16rpx;
+$fontSize1: 20rpx;
+$fontSize2: 24rpx;
+$fontSize3: 28rpx;
+$fontSize4: 32rpx;
+$fontSize5: 36rpx;
+
+.display-flex-center {
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+
+.display-flex-between {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+}
+
+.text-ellipsis {
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+
+.text-ellipsis-line {
+  display: -webkit-box;
+	width: 100%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 2;
+}
+
+.after{
+	position: absolute;
+	display: block;
+	content: ' ';
+	z-index: 1;
+}

File diff suppressed because it is too large
+ 116 - 0
wxcomponents/vant/action-sheet/index.vue


File diff suppressed because it is too large
+ 234 - 0
wxcomponents/vant/area/index.vue


File diff suppressed because it is too large
+ 92 - 0
wxcomponents/vant/button/index.vue


+ 37 - 0
wxcomponents/vant/calendar/calendar.vue

@@ -0,0 +1,37 @@
+<template>
+<uni-shadow-root class="vant-calendar-calendar"><view class="van-calendar">
+  <header :title="title" :showTitle="showTitle" :subtitle="subtitle" :showSubtitle="showSubtitle" :firstDayOfWeek="firstDayOfWeek" @click-subtitle="onClickSubtitle">
+    <slot name="title" slot="title"></slot>
+  </header>
+
+  <scroll-view class="van-calendar__body" scroll-y :scroll-into-view="scrollIntoView">
+    <month v-for="(item,index) in (computed.getMonths(minDate, maxDate))" :key="item.index" :id="'month'+(index)" class="month" :data-date="item" :date="item" :type="type" :color="color" :minDate="minDate" :maxDate="maxDate" :showMark="showMark" :formatter="formatter" :rowHeight="rowHeight" :currentDate="currentDate" :showSubtitle="showSubtitle" :allowSameDay="allowSameDay" :showMonthTitle="index !== 0 || !showSubtitle" :firstDayOfWeek="firstDayOfWeek" @click="onClickDay"></month>
+  </scroll-view>
+
+  <view :class="utils.bem('calendar__footer', { safeAreaInsetBottom })">
+    <slot name="footer"></slot>
+  </view>
+
+  <view :class="utils.bem('calendar__footer', { safeAreaInsetBottom })">
+    <van-button v-if="showConfirm" round block type="danger" :color="color" custom-class="van-calendar__confirm" :disabled="computed.getButtonDisabled(type, currentDate, minRange)" nativeType="text" @click="onConfirm">
+      {{
+        computed.getButtonDisabled(type, currentDate, minRange)
+          ? confirmDisabledText
+          : confirmText
+      }}
+    </van-button>
+  </view>
+</view></uni-shadow-root>
+</template>
+<wxs src="./index.wxs" module="computed"></wxs><wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/calendar/calendar'
+
+Component({})
+
+export default global['__wxComponents']['vant/calendar/calendar']
+</script>
+<style platform="mp-weixin">
+
+</style>

File diff suppressed because it is too large
+ 64 - 0
wxcomponents/vant/calendar/components/header/index.vue


File diff suppressed because it is too large
+ 194 - 0
wxcomponents/vant/calendar/components/month/index.vue


File diff suppressed because it is too large
+ 388 - 0
wxcomponents/vant/calendar/index.vue


File diff suppressed because it is too large
+ 105 - 0
wxcomponents/vant/card/index.vue


File diff suppressed because it is too large
+ 246 - 0
wxcomponents/vant/cascader/index.vue


+ 28 - 0
wxcomponents/vant/cell-group/index.vue

@@ -0,0 +1,28 @@
+<template>
+<uni-shadow-root class="vant-cell-group-index"><view v-if="title" :class="utils.bem('cell-group__title', { inset })">
+  {{ title }}
+</view>
+<view :class="'custom-class '+(utils.bem('cell-group', { inset }))+' '+(border ? 'van-hairline--top-bottom' : '')">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/cell-group/index'
+import { VantComponent } from '../common/component';
+VantComponent({
+    props: {
+        title: String,
+        border: {
+            type: Boolean,
+            value: true,
+        },
+        inset: Boolean,
+    },
+});
+export default global['__wxComponents']['vant/cell-group/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-cell-group--inset{border-radius:var(--cell-group-inset-border-radius,8px);margin:var(--cell-group-inset-padding,0 16px);overflow:hidden}.van-cell-group__title{color:var(--cell-group-title-color,#969799);font-size:var(--cell-group-title-font-size,14px);line-height:var(--cell-group-title-line-height,16px);padding:var(--cell-group-title-padding,16px 16px 8px)}.van-cell-group__title--inset{padding:var(--cell-group-inset-title-padding,16px 16px 8px 32px)}
+</style>

File diff suppressed because it is too large
+ 76 - 0
wxcomponents/vant/cell/index.vue


+ 50 - 0
wxcomponents/vant/checkbox-group/index.vue

@@ -0,0 +1,50 @@
+<template>
+<uni-shadow-root class="vant-checkbox-group-index"><view :class="utils.bem('checkbox-group', [{ horizontal: direction === 'horizontal' }])">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/checkbox-group/index'
+import { useChildren } from '../common/relation';
+import { VantComponent } from '../common/component';
+VantComponent({
+    field: true,
+    relation: useChildren('checkbox', function (target) {
+        this.updateChild(target);
+    }),
+    props: {
+        max: Number,
+        value: {
+            type: Array,
+            observer: 'updateChildren',
+        },
+        disabled: {
+            type: Boolean,
+            observer: 'updateChildren',
+        },
+        direction: {
+            type: String,
+            value: 'vertical',
+        },
+    },
+    methods: {
+        updateChildren() {
+            this.children.forEach((child) => this.updateChild(child));
+        },
+        updateChild(child) {
+            const { value, disabled, direction } = this.data;
+            child.setData({
+                value: value.indexOf(child.data.name) !== -1,
+                parentDisabled: disabled,
+                direction,
+            });
+        },
+    },
+});
+export default global['__wxComponents']['vant/checkbox-group/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-checkbox-group--horizontal{display:flex;flex-wrap:wrap}
+</style>

File diff suppressed because it is too large
+ 102 - 0
wxcomponents/vant/checkbox/index.vue


+ 215 - 0
wxcomponents/vant/circle/index.vue

@@ -0,0 +1,215 @@
+<template>
+<uni-shadow-root class="vant-circle-index"><view class="van-circle">
+  <canvas class="van-circle__canvas" :type="type" :style="'width: '+(utils.addUnit(size))+';height:'+(utils.addUnit(size))" id="van-circle" canvas-id="van-circle"></canvas>
+  <view v-if="(!text)" class="van-circle__text">
+    <slot></slot>
+  </view>
+  <cover-view v-else class="van-circle__text">{{ text }}</cover-view>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/circle/index'
+import { BLUE, WHITE } from '../common/color';
+import { VantComponent } from '../common/component';
+import { getSystemInfoSync } from '../common/utils';
+import { isObj } from '../common/validator';
+import { canIUseCanvas2d } from '../common/version';
+import { adaptor } from './canvas';
+function format(rate) {
+    return Math.min(Math.max(rate, 0), 100);
+}
+const PERIMETER = 2 * Math.PI;
+const BEGIN_ANGLE = -Math.PI / 2;
+const STEP = 1;
+VantComponent({
+    props: {
+        text: String,
+        lineCap: {
+            type: String,
+            value: 'round',
+        },
+        value: {
+            type: Number,
+            value: 0,
+            observer: 'reRender',
+        },
+        speed: {
+            type: Number,
+            value: 50,
+        },
+        size: {
+            type: Number,
+            value: 100,
+            observer() {
+                this.drawCircle(this.currentValue);
+            },
+        },
+        fill: String,
+        layerColor: {
+            type: String,
+            value: WHITE,
+        },
+        color: {
+            type: null,
+            value: BLUE,
+            observer() {
+                this.setHoverColor().then(() => {
+                    this.drawCircle(this.currentValue);
+                });
+            },
+        },
+        type: {
+            type: String,
+            value: '',
+        },
+        strokeWidth: {
+            type: Number,
+            value: 4,
+        },
+        clockwise: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    data: {
+        hoverColor: BLUE,
+    },
+    methods: {
+        getContext() {
+            const { type, size } = this.data;
+            if (type === '' || !canIUseCanvas2d()) {
+                const ctx = wx.createCanvasContext('van-circle', this);
+                return Promise.resolve(ctx);
+            }
+            const dpr = getSystemInfoSync().pixelRatio;
+            return new Promise((resolve) => {
+                wx.createSelectorQuery()
+                    .in(this)
+                    .select('#van-circle')
+                    .node()
+                    .exec((res) => {
+                    const canvas = res[0].node;
+                    const ctx = canvas.getContext(type);
+                    if (!this.inited) {
+                        this.inited = true;
+                        canvas.width = size * dpr;
+                        canvas.height = size * dpr;
+                        ctx.scale(dpr, dpr);
+                    }
+                    resolve(adaptor(ctx));
+                });
+            });
+        },
+        setHoverColor() {
+            const { color, size } = this.data;
+            if (isObj(color)) {
+                return this.getContext().then((context) => {
+                    if (!context)
+                        return;
+                    const LinearColor = context.createLinearGradient(size, 0, 0, 0);
+                    Object.keys(color)
+                        .sort((a, b) => parseFloat(a) - parseFloat(b))
+                        .map((key) => LinearColor.addColorStop(parseFloat(key) / 100, color[key]));
+                    this.hoverColor = LinearColor;
+                });
+            }
+            this.hoverColor = color;
+            return Promise.resolve();
+        },
+        presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
+            const { strokeWidth, lineCap, clockwise, size } = this.data;
+            const position = size / 2;
+            const radius = position - strokeWidth / 2;
+            context.setStrokeStyle(strokeStyle);
+            context.setLineWidth(strokeWidth);
+            context.setLineCap(lineCap);
+            context.beginPath();
+            context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
+            context.stroke();
+            if (fill) {
+                context.setFillStyle(fill);
+                context.fill();
+            }
+        },
+        renderLayerCircle(context) {
+            const { layerColor, fill } = this.data;
+            this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
+        },
+        renderHoverCircle(context, formatValue) {
+            const { clockwise } = this.data;
+            // 结束角度
+            const progress = PERIMETER * (formatValue / 100);
+            const endAngle = clockwise
+                ? BEGIN_ANGLE + progress
+                : 3 * Math.PI - (BEGIN_ANGLE + progress);
+            this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
+        },
+        drawCircle(currentValue) {
+            const { size } = this.data;
+            this.getContext().then((context) => {
+                if (!context)
+                    return;
+                context.clearRect(0, 0, size, size);
+                this.renderLayerCircle(context);
+                const formatValue = format(currentValue);
+                if (formatValue !== 0) {
+                    this.renderHoverCircle(context, formatValue);
+                }
+                context.draw();
+            });
+        },
+        reRender() {
+            // tofector 动画暂时没有想到好的解决方案
+            const { value, speed } = this.data;
+            if (speed <= 0 || speed > 1000) {
+                this.drawCircle(value);
+                return;
+            }
+            this.clearMockInterval();
+            this.currentValue = this.currentValue || 0;
+            const run = () => {
+                this.interval = setTimeout(() => {
+                    if (this.currentValue !== value) {
+                        if (Math.abs(this.currentValue - value) < STEP) {
+                            this.currentValue = value;
+                        }
+                        else if (this.currentValue < value) {
+                            this.currentValue += STEP;
+                        }
+                        else {
+                            this.currentValue -= STEP;
+                        }
+                        this.drawCircle(this.currentValue);
+                        run();
+                    }
+                    else {
+                        this.clearMockInterval();
+                    }
+                }, 1000 / speed);
+            };
+            run();
+        },
+        clearMockInterval() {
+            if (this.interval) {
+                clearTimeout(this.interval);
+                this.interval = null;
+            }
+        },
+    },
+    mounted() {
+        this.currentValue = this.data.value;
+        this.setHoverColor().then(() => {
+            this.drawCircle(this.currentValue);
+        });
+    },
+    destroyed() {
+        this.clearMockInterval();
+    },
+});
+export default global['__wxComponents']['vant/circle/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-circle{display:inline-block;position:relative;text-align:center}.van-circle__text{color:var(--circle-text-color,#323233);left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%}
+</style>

File diff suppressed because it is too large
+ 23 - 0
wxcomponents/vant/col/index.vue


File diff suppressed because it is too large
+ 86 - 0
wxcomponents/vant/collapse-item/index.vue


+ 60 - 0
wxcomponents/vant/collapse/index.vue

@@ -0,0 +1,60 @@
+<template>
+<uni-shadow-root class="vant-collapse-index"><view :class="'custom-class van-collapse '+(border ? 'van-hairline--top-bottom' : '')">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/collapse/index'
+import { VantComponent } from '../common/component';
+import { useChildren } from '../common/relation';
+VantComponent({
+    relation: useChildren('collapse-item'),
+    props: {
+        value: {
+            type: null,
+            observer: 'updateExpanded',
+        },
+        accordion: {
+            type: Boolean,
+            observer: 'updateExpanded',
+        },
+        border: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    methods: {
+        updateExpanded() {
+            this.children.forEach((child) => {
+                child.updateExpanded();
+            });
+        },
+        switch(name, expanded) {
+            const { accordion, value } = this.data;
+            const changeItem = name;
+            if (!accordion) {
+                name = expanded
+                    ? (value || []).concat(name)
+                    : (value || []).filter((activeName) => activeName !== name);
+            }
+            else {
+                name = expanded ? name : '';
+            }
+            if (expanded) {
+                this.$emit('open', changeItem);
+            }
+            else {
+                this.$emit('close', changeItem);
+            }
+            this.$emit('change', name);
+            this.$emit('input', name);
+        },
+    },
+});
+export default global['__wxComponents']['vant/collapse/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';
+</style>

File diff suppressed because it is too large
+ 1 - 0
wxcomponents/vant/common/index.css


+ 1 - 0
wxcomponents/vant/common/style/clearfix.css

@@ -0,0 +1 @@
+.van-clearfix:after{clear:both;content:"";display:table}

+ 1 - 0
wxcomponents/vant/common/style/ellipsis.css

@@ -0,0 +1 @@
+.van-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden;text-overflow:ellipsis}.van-multi-ellipsis--l3{-webkit-line-clamp:3}

File diff suppressed because it is too large
+ 1 - 0
wxcomponents/vant/common/style/hairline.css


+ 0 - 0
wxcomponents/vant/common/style/mixins/clearfix.css


+ 0 - 0
wxcomponents/vant/common/style/mixins/ellipsis.css


+ 0 - 0
wxcomponents/vant/common/style/mixins/hairline.css


+ 0 - 0
wxcomponents/vant/common/style/var.css


+ 23 - 0
wxcomponents/vant/config-provider/index.vue

@@ -0,0 +1,23 @@
+<template>
+<uni-shadow-root class="vant-config-provider-index"><view class="van-config-provider" :style="computed.mapThemeVarsToCSSVars(themeVars)">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+<wxs src="./index.wxs" module="computed"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/config-provider/index'
+import { VantComponent } from '../common/component';
+VantComponent({
+    props: {
+        themeVars: {
+            type: Object,
+            value: {},
+        },
+    },
+});
+export default global['__wxComponents']['vant/config-provider/index']
+</script>
+<style platform="mp-weixin">
+
+</style>

+ 115 - 0
wxcomponents/vant/count-down/index.vue

@@ -0,0 +1,115 @@
+<template>
+<uni-shadow-root class="vant-count-down-index"><view class="van-count-down">
+  <slot v-if="useSlot"></slot>
+  <block v-else>{{ formattedTime }}</block>
+</view></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/count-down/index'
+import { VantComponent } from '../common/component';
+import { isSameSecond, parseFormat, parseTimeData } from './utils';
+function simpleTick(fn) {
+    return setTimeout(fn, 30);
+}
+VantComponent({
+    props: {
+        useSlot: Boolean,
+        millisecond: Boolean,
+        time: {
+            type: Number,
+            observer: 'reset',
+        },
+        format: {
+            type: String,
+            value: 'HH:mm:ss',
+        },
+        autoStart: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    data: {
+        timeData: parseTimeData(0),
+        formattedTime: '0',
+    },
+    destroyed() {
+        clearTimeout(this.tid);
+        this.tid = null;
+    },
+    methods: {
+        // 开始
+        start() {
+            if (this.counting) {
+                return;
+            }
+            this.counting = true;
+            this.endTime = Date.now() + this.remain;
+            this.tick();
+        },
+        // 暂停
+        pause() {
+            this.counting = false;
+            clearTimeout(this.tid);
+        },
+        // 重置
+        reset() {
+            this.pause();
+            this.remain = this.data.time;
+            this.setRemain(this.remain);
+            if (this.data.autoStart) {
+                this.start();
+            }
+        },
+        tick() {
+            if (this.data.millisecond) {
+                this.microTick();
+            }
+            else {
+                this.macroTick();
+            }
+        },
+        microTick() {
+            this.tid = simpleTick(() => {
+                this.setRemain(this.getRemain());
+                if (this.remain !== 0) {
+                    this.microTick();
+                }
+            });
+        },
+        macroTick() {
+            this.tid = simpleTick(() => {
+                const remain = this.getRemain();
+                if (!isSameSecond(remain, this.remain) || remain === 0) {
+                    this.setRemain(remain);
+                }
+                if (this.remain !== 0) {
+                    this.macroTick();
+                }
+            });
+        },
+        getRemain() {
+            return Math.max(this.endTime - Date.now(), 0);
+        },
+        setRemain(remain) {
+            this.remain = remain;
+            const timeData = parseTimeData(remain);
+            if (this.data.useSlot) {
+                this.$emit('change', timeData);
+            }
+            this.setData({
+                formattedTime: parseFormat(this.data.format, timeData),
+            });
+            if (remain === 0) {
+                this.pause();
+                this.$emit('finish');
+            }
+        },
+    },
+});
+export default global['__wxComponents']['vant/count-down/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-count-down{color:var(--count-down-text-color,#323233);font-size:var(--count-down-font-size,14px);line-height:var(--count-down-line-height,20px)}
+</style>

+ 309 - 0
wxcomponents/vant/datetime-picker/index.vue

@@ -0,0 +1,309 @@
+<template>
+<uni-shadow-root class="vant-datetime-picker-index"><van-picker class="van-datetime-picker" active-class="active-class" toolbar-class="toolbar-class" column-class="column-class" :title="title" :columns="columns" :item-height="itemHeight" :show-toolbar="showToolbar" :visible-item-count="visibleItemCount" :confirm-button-text="confirmButtonText" :cancel-button-text="cancelButtonText" @change="onChange" @confirm="onConfirm" @cancel="onCancel"></van-picker></uni-shadow-root>
+</template>
+
+<script>
+import VanPicker from '../picker/index.vue'
+global['__wxVueOptions'] = {components:{'van-picker': VanPicker}}
+
+global['__wxRoute'] = 'vant/datetime-picker/index'
+import { VantComponent } from '../common/component';
+import { isDef } from '../common/validator';
+import { pickerProps } from '../picker/shared';
+const currentYear = new Date().getFullYear();
+function isValidDate(date) {
+    return isDef(date) && !isNaN(new Date(date).getTime());
+}
+function range(num, min, max) {
+    return Math.min(Math.max(num, min), max);
+}
+function padZero(val) {
+    return `00${val}`.slice(-2);
+}
+function times(n, iteratee) {
+    let index = -1;
+    const result = Array(n < 0 ? 0 : n);
+    while (++index < n) {
+        result[index] = iteratee(index);
+    }
+    return result;
+}
+function getTrueValue(formattedValue) {
+    if (formattedValue === undefined) {
+        formattedValue = '1';
+    }
+    while (isNaN(parseInt(formattedValue, 10))) {
+        formattedValue = formattedValue.slice(1);
+    }
+    return parseInt(formattedValue, 10);
+}
+function getMonthEndDay(year, month) {
+    return 32 - new Date(year, month - 1, 32).getDate();
+}
+const defaultFormatter = (type, value) => value;
+VantComponent({
+    classes: ['active-class', 'toolbar-class', 'column-class'],
+    props: Object.assign(Object.assign({}, pickerProps), { value: {
+            type: null,
+            observer: 'updateValue',
+        }, filter: null, type: {
+            type: String,
+            value: 'datetime',
+            observer: 'updateValue',
+        }, showToolbar: {
+            type: Boolean,
+            value: true,
+        }, formatter: {
+            type: null,
+            value: defaultFormatter,
+        }, minDate: {
+            type: Number,
+            value: new Date(currentYear - 10, 0, 1).getTime(),
+            observer: 'updateValue',
+        }, maxDate: {
+            type: Number,
+            value: new Date(currentYear + 10, 11, 31).getTime(),
+            observer: 'updateValue',
+        }, minHour: {
+            type: Number,
+            value: 0,
+            observer: 'updateValue',
+        }, maxHour: {
+            type: Number,
+            value: 23,
+            observer: 'updateValue',
+        }, minMinute: {
+            type: Number,
+            value: 0,
+            observer: 'updateValue',
+        }, maxMinute: {
+            type: Number,
+            value: 59,
+            observer: 'updateValue',
+        } }),
+    data: {
+        innerValue: Date.now(),
+        columns: [],
+    },
+    methods: {
+        updateValue() {
+            const { data } = this;
+            const val = this.correctValue(data.value);
+            const isEqual = val === data.innerValue;
+            this.updateColumnValue(val).then(() => {
+                if (!isEqual) {
+                    this.$emit('input', val);
+                }
+            });
+        },
+        getPicker() {
+            if (this.picker == null) {
+                this.picker = this.selectComponent('.van-datetime-picker');
+                const { picker } = this;
+                const { setColumnValues } = picker;
+                picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]);
+            }
+            return this.picker;
+        },
+        updateColumns() {
+            const { formatter = defaultFormatter } = this.data;
+            const results = this.getOriginColumns().map((column) => ({
+                values: column.values.map((value) => formatter(column.type, value)),
+            }));
+            return this.set({ columns: results });
+        },
+        getOriginColumns() {
+            const { filter } = this.data;
+            const results = this.getRanges().map(({ type, range }) => {
+                let values = times(range[1] - range[0] + 1, (index) => {
+                    const value = range[0] + index;
+                    return type === 'year' ? `${value}` : padZero(value);
+                });
+                if (filter) {
+                    values = filter(type, values);
+                }
+                return { type, values };
+            });
+            return results;
+        },
+        getRanges() {
+            const { data } = this;
+            if (data.type === 'time') {
+                return [
+                    {
+                        type: 'hour',
+                        range: [data.minHour, data.maxHour],
+                    },
+                    {
+                        type: 'minute',
+                        range: [data.minMinute, data.maxMinute],
+                    },
+                ];
+            }
+            const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = this.getBoundary('max', data.innerValue);
+            const { minYear, minDate, minMonth, minHour, minMinute, } = this.getBoundary('min', data.innerValue);
+            const result = [
+                {
+                    type: 'year',
+                    range: [minYear, maxYear],
+                },
+                {
+                    type: 'month',
+                    range: [minMonth, maxMonth],
+                },
+                {
+                    type: 'day',
+                    range: [minDate, maxDate],
+                },
+                {
+                    type: 'hour',
+                    range: [minHour, maxHour],
+                },
+                {
+                    type: 'minute',
+                    range: [minMinute, maxMinute],
+                },
+            ];
+            if (data.type === 'date')
+                result.splice(3, 2);
+            if (data.type === 'year-month')
+                result.splice(2, 3);
+            return result;
+        },
+        correctValue(value) {
+            const { data } = this;
+            // validate value
+            const isDateType = data.type !== 'time';
+            if (isDateType && !isValidDate(value)) {
+                value = data.minDate;
+            }
+            else if (!isDateType && !value) {
+                const { minHour } = data;
+                value = `${padZero(minHour)}:00`;
+            }
+            // time type
+            if (!isDateType) {
+                let [hour, minute] = value.split(':');
+                hour = padZero(range(hour, data.minHour, data.maxHour));
+                minute = padZero(range(minute, data.minMinute, data.maxMinute));
+                return `${hour}:${minute}`;
+            }
+            // date type
+            value = Math.max(value, data.minDate);
+            value = Math.min(value, data.maxDate);
+            return value;
+        },
+        getBoundary(type, innerValue) {
+            const value = new Date(innerValue);
+            const boundary = new Date(this.data[`${type}Date`]);
+            const year = boundary.getFullYear();
+            let month = 1;
+            let date = 1;
+            let hour = 0;
+            let minute = 0;
+            if (type === 'max') {
+                month = 12;
+                date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
+                hour = 23;
+                minute = 59;
+            }
+            if (value.getFullYear() === year) {
+                month = boundary.getMonth() + 1;
+                if (value.getMonth() + 1 === month) {
+                    date = boundary.getDate();
+                    if (value.getDate() === date) {
+                        hour = boundary.getHours();
+                        if (value.getHours() === hour) {
+                            minute = boundary.getMinutes();
+                        }
+                    }
+                }
+            }
+            return {
+                [`${type}Year`]: year,
+                [`${type}Month`]: month,
+                [`${type}Date`]: date,
+                [`${type}Hour`]: hour,
+                [`${type}Minute`]: minute,
+            };
+        },
+        onCancel() {
+            this.$emit('cancel');
+        },
+        onConfirm() {
+            this.$emit('confirm', this.data.innerValue);
+        },
+        onChange() {
+            const { data } = this;
+            let value;
+            const picker = this.getPicker();
+            const originColumns = this.getOriginColumns();
+            if (data.type === 'time') {
+                const indexes = picker.getIndexes();
+                value = `${+originColumns[0].values[indexes[0]]}:${+originColumns[1]
+                    .values[indexes[1]]}`;
+            }
+            else {
+                const indexes = picker.getIndexes();
+                const values = indexes.map((value, index) => originColumns[index].values[value]);
+                const year = getTrueValue(values[0]);
+                const month = getTrueValue(values[1]);
+                const maxDate = getMonthEndDay(year, month);
+                let date = getTrueValue(values[2]);
+                if (data.type === 'year-month') {
+                    date = 1;
+                }
+                date = date > maxDate ? maxDate : date;
+                let hour = 0;
+                let minute = 0;
+                if (data.type === 'datetime') {
+                    hour = getTrueValue(values[3]);
+                    minute = getTrueValue(values[4]);
+                }
+                value = new Date(year, month - 1, date, hour, minute);
+            }
+            value = this.correctValue(value);
+            this.updateColumnValue(value).then(() => {
+                this.$emit('input', value);
+                this.$emit('change', picker);
+            });
+        },
+        updateColumnValue(value) {
+            let values = [];
+            const { type } = this.data;
+            const formatter = this.data.formatter || defaultFormatter;
+            const picker = this.getPicker();
+            if (type === 'time') {
+                const pair = value.split(':');
+                values = [formatter('hour', pair[0]), formatter('minute', pair[1])];
+            }
+            else {
+                const date = new Date(value);
+                values = [
+                    formatter('year', `${date.getFullYear()}`),
+                    formatter('month', padZero(date.getMonth() + 1)),
+                ];
+                if (type === 'date') {
+                    values.push(formatter('day', padZero(date.getDate())));
+                }
+                if (type === 'datetime') {
+                    values.push(formatter('day', padZero(date.getDate())), formatter('hour', padZero(date.getHours())), formatter('minute', padZero(date.getMinutes())));
+                }
+            }
+            return this.set({ innerValue: value })
+                .then(() => this.updateColumns())
+                .then(() => picker.setValues(values));
+        },
+    },
+    created() {
+        const innerValue = this.correctValue(this.data.value);
+        this.updateColumnValue(innerValue).then(() => {
+            this.$emit('input', innerValue);
+        });
+    },
+});
+export default global['__wxComponents']['vant/datetime-picker/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';
+</style>

File diff suppressed because it is too large
+ 184 - 0
wxcomponents/vant/dialog/index.vue


File diff suppressed because it is too large
+ 28 - 0
wxcomponents/vant/divider/index.vue


+ 157 - 0
wxcomponents/vant/dropdown-item/index.vue

@@ -0,0 +1,157 @@
+<template>
+<uni-shadow-root class="vant-dropdown-item-index"><view v-if="showWrapper" :class="(utils.bem('dropdown-item', direction))+' custom-class'" :style="wrapperStyle">
+  <van-popup :show="showPopup" :custom-style="'position: absolute;'+(popupStyle)" overlay-style="position: absolute;" :overlay="overlay" :position="direction === 'down' ? 'top' : 'bottom'" :duration="transition ? duration : 0" :safe-area-tab-bar="safeAreaTabBar" :close-on-click-overlay="closeOnClickOverlay" :rootPortal="rootPortal" @enter="onOpen" @leave="onClose" @close="toggle" @after-enter="onOpened" @after-leave="onClosed">
+    <van-cell v-for="(item,index) in (options)" :key="item.value" :data-option="item" :class="utils.bem('dropdown-item__option', { active: item.value === value } )" clickable :icon="item.icon" @click.native="onOptionTap">
+      <view slot="title" class="van-dropdown-item__title item-title-class" :style="item.value === value  ? 'color:' + activeColor : ''">
+        {{ item.text }}
+      </view>
+      <van-icon v-if="item.value === value" name="success" class="van-dropdown-item__icon" :color="activeColor"></van-icon>
+    </van-cell>
+
+    <slot></slot>
+  </van-popup>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+import VanPopup from '../popup/index.vue'
+import VanCell from '../cell/index.vue'
+import VanIcon from '../icon/index.vue'
+global['__wxVueOptions'] = {components:{'van-popup': VanPopup,'van-cell': VanCell,'van-icon': VanIcon}}
+
+global['__wxRoute'] = 'vant/dropdown-item/index'
+import { useParent } from '../common/relation';
+import { VantComponent } from '../common/component';
+VantComponent({
+    classes: ['item-title-class'],
+    field: true,
+    relation: useParent('dropdown-menu', function () {
+        this.updateDataFromParent();
+    }),
+    props: {
+        value: {
+            type: null,
+            observer: 'rerender',
+        },
+        title: {
+            type: String,
+            observer: 'rerender',
+        },
+        disabled: Boolean,
+        titleClass: {
+            type: String,
+            observer: 'rerender',
+        },
+        options: {
+            type: Array,
+            value: [],
+            observer: 'rerender',
+        },
+        popupStyle: String,
+        useBeforeToggle: {
+            type: Boolean,
+            value: false,
+        },
+        rootPortal: {
+            type: Boolean,
+            value: false,
+        },
+    },
+    data: {
+        transition: true,
+        showPopup: false,
+        showWrapper: false,
+        displayTitle: '',
+        safeAreaTabBar: false,
+    },
+    methods: {
+        rerender() {
+            wx.nextTick(() => {
+                var _a;
+                (_a = this.parent) === null || _a === void 0 ? void 0 : _a.updateItemListData();
+            });
+        },
+        updateDataFromParent() {
+            if (this.parent) {
+                const { overlay, duration, activeColor, closeOnClickOverlay, direction, safeAreaTabBar, } = this.parent.data;
+                this.setData({
+                    overlay,
+                    duration,
+                    activeColor,
+                    closeOnClickOverlay,
+                    direction,
+                    safeAreaTabBar,
+                });
+            }
+        },
+        onOpen() {
+            this.$emit('open');
+        },
+        onOpened() {
+            this.$emit('opened');
+        },
+        onClose() {
+            this.$emit('close');
+        },
+        onClosed() {
+            this.$emit('closed');
+            this.setData({ showWrapper: false });
+        },
+        onOptionTap(event) {
+            const { option } = event.currentTarget.dataset;
+            const { value } = option;
+            const shouldEmitChange = this.data.value !== value;
+            this.setData({ showPopup: false, value });
+            this.$emit('close');
+            this.rerender();
+            if (shouldEmitChange) {
+                this.$emit('change', value);
+            }
+        },
+        toggle(show, options = {}) {
+            const { showPopup } = this.data;
+            if (typeof show !== 'boolean') {
+                show = !showPopup;
+            }
+            if (show === showPopup) {
+                return;
+            }
+            this.onBeforeToggle(show).then((status) => {
+                var _a;
+                if (!status) {
+                    return;
+                }
+                this.setData({
+                    transition: !options.immediate,
+                    showPopup: show,
+                });
+                if (show) {
+                    (_a = this.parent) === null || _a === void 0 ? void 0 : _a.getChildWrapperStyle().then((wrapperStyle) => {
+                        this.setData({ wrapperStyle, showWrapper: true });
+                        this.rerender();
+                    });
+                }
+                else {
+                    this.rerender();
+                }
+            });
+        },
+        onBeforeToggle(status) {
+            const { useBeforeToggle } = this.data;
+            if (!useBeforeToggle) {
+                return Promise.resolve(true);
+            }
+            return new Promise((resolve) => {
+                this.$emit('before-toggle', {
+                    status,
+                    callback: (value) => resolve(value),
+                });
+            });
+        },
+    },
+});
+export default global['__wxComponents']['vant/dropdown-item/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-dropdown-item{left:0;overflow:hidden;position:fixed;right:0}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:var(--dropdown-menu-option-active-color,#ee0a24)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit}
+</style>

File diff suppressed because it is too large
+ 139 - 0
wxcomponents/vant/dropdown-menu/index.vue


File diff suppressed because it is too large
+ 42 - 0
wxcomponents/vant/empty/index.vue


File diff suppressed because it is too large
+ 1 - 1
wxcomponents/vant/empty/index.wxss


File diff suppressed because it is too large
+ 182 - 0
wxcomponents/vant/field/index.vue


File diff suppressed because it is too large
+ 15 - 0
wxcomponents/vant/field/input.vue


File diff suppressed because it is too large
+ 15 - 0
wxcomponents/vant/field/textarea.vue


File diff suppressed because it is too large
+ 61 - 0
wxcomponents/vant/goods-action-button/index.vue


File diff suppressed because it is too large
+ 48 - 0
wxcomponents/vant/goods-action-icon/index.vue


+ 29 - 0
wxcomponents/vant/goods-action/index.vue

@@ -0,0 +1,29 @@
+<template>
+<uni-shadow-root class="vant-goods-action-index"><view :class="'custom-class '+(utils.bem('goods-action', { safe: safeAreaInsetBottom }))">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/goods-action/index'
+import { VantComponent } from '../common/component';
+import { useChildren } from '../common/relation';
+VantComponent({
+    relation: useChildren('goods-action-button', function () {
+        this.children.forEach((item) => {
+            item.updateStyle();
+        });
+    }),
+    props: {
+        safeAreaInsetBottom: {
+            type: Boolean,
+            value: true,
+        },
+    },
+});
+export default global['__wxComponents']['vant/goods-action/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-goods-action{align-items:center;background-color:var(--goods-action-background-color,#fff);bottom:0;box-sizing:initial;display:flex;height:var(--goods-action-height,50px);left:0;position:fixed;right:0}.van-goods-action--safe{padding-bottom:env(safe-area-inset-bottom)}
+</style>

File diff suppressed because it is too large
+ 82 - 0
wxcomponents/vant/grid-item/index.vue


+ 69 - 0
wxcomponents/vant/grid/index.vue

@@ -0,0 +1,69 @@
+<template>
+<uni-shadow-root class="vant-grid-index"><view :class="'van-grid custom-class '+(border && !gutter ? 'van-hairline--top' : '')" :style="computed.rootStyle({ gutter })">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+<wxs src="./index.wxs" module="computed"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/grid/index'
+import { VantComponent } from '../common/component';
+import { useChildren } from '../common/relation';
+VantComponent({
+    relation: useChildren('grid-item'),
+    props: {
+        square: {
+            type: Boolean,
+            observer: 'updateChildren',
+        },
+        gutter: {
+            type: null,
+            value: 0,
+            observer: 'updateChildren',
+        },
+        clickable: {
+            type: Boolean,
+            observer: 'updateChildren',
+        },
+        columnNum: {
+            type: Number,
+            value: 4,
+            observer: 'updateChildren',
+        },
+        center: {
+            type: Boolean,
+            value: true,
+            observer: 'updateChildren',
+        },
+        border: {
+            type: Boolean,
+            value: true,
+            observer: 'updateChildren',
+        },
+        direction: {
+            type: String,
+            observer: 'updateChildren',
+        },
+        iconSize: {
+            type: String,
+            observer: 'updateChildren',
+        },
+        reverse: {
+            type: Boolean,
+            value: false,
+            observer: 'updateChildren',
+        },
+    },
+    methods: {
+        updateChildren() {
+            this.children.forEach((child) => {
+                child.updateStyle();
+            });
+        },
+    },
+});
+export default global['__wxComponents']['vant/grid/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-grid{box-sizing:border-box;overflow:hidden;position:relative}
+</style>

File diff suppressed because it is too large
+ 38 - 0
wxcomponents/vant/icon/index.vue


File diff suppressed because it is too large
+ 90 - 0
wxcomponents/vant/image/index.vue


File diff suppressed because it is too large
+ 44 - 0
wxcomponents/vant/index-anchor/index.vue


+ 266 - 0
wxcomponents/vant/index-bar/index.vue

@@ -0,0 +1,266 @@
+<template>
+<uni-shadow-root class="vant-index-bar-index"><view class="van-index-bar">
+  <slot></slot>
+
+  <view v-if="showSidebar" class="van-index-bar__sidebar" @click.stop.prevent="onClick" @touchmove.stop.prevent="onTouchMove" @touchend.stop.prevent="onTouchStop" @touchcancel.stop.prevent="onTouchStop">
+    <view v-for="(item,index) in (indexList)" :key="item.index" class="van-index-bar__index" :style="'z-index: '+(zIndex + 1)+'; color: '+(activeAnchorIndex === index ? highlightColor : '')" :data-index="index">
+      {{ item }}
+    </view>
+  </view>
+</view></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/index-bar/index'
+import { GREEN } from '../common/color';
+import { VantComponent } from '../common/component';
+import { useChildren } from '../common/relation';
+import { getRect, isDef } from '../common/utils';
+import { pageScrollMixin } from '../mixins/page-scroll';
+const indexList = () => {
+    const indexList = [];
+    const charCodeOfA = 'A'.charCodeAt(0);
+    for (let i = 0; i < 26; i++) {
+        indexList.push(String.fromCharCode(charCodeOfA + i));
+    }
+    return indexList;
+};
+VantComponent({
+    relation: useChildren('index-anchor', function () {
+        this.updateData();
+    }),
+    props: {
+        sticky: {
+            type: Boolean,
+            value: true,
+        },
+        zIndex: {
+            type: Number,
+            value: 1,
+        },
+        highlightColor: {
+            type: String,
+            value: GREEN,
+        },
+        stickyOffsetTop: {
+            type: Number,
+            value: 0,
+        },
+        indexList: {
+            type: Array,
+            value: indexList(),
+        },
+    },
+    mixins: [
+        pageScrollMixin(function (event) {
+            this.scrollTop = (event === null || event === void 0 ? void 0 : event.scrollTop) || 0;
+            this.onScroll();
+        }),
+    ],
+    data: {
+        activeAnchorIndex: null,
+        showSidebar: false,
+    },
+    created() {
+        this.scrollTop = 0;
+    },
+    methods: {
+        updateData() {
+            wx.nextTick(() => {
+                if (this.timer != null) {
+                    clearTimeout(this.timer);
+                }
+                this.timer = setTimeout(() => {
+                    this.setData({
+                        showSidebar: !!this.children.length,
+                    });
+                    this.setRect().then(() => {
+                        this.onScroll();
+                    });
+                }, 0);
+            });
+        },
+        setRect() {
+            return Promise.all([
+                this.setAnchorsRect(),
+                this.setListRect(),
+                this.setSiderbarRect(),
+            ]);
+        },
+        setAnchorsRect() {
+            return Promise.all(this.children.map((anchor) => getRect(anchor, '.van-index-anchor-wrapper').then((rect) => {
+                Object.assign(anchor, {
+                    height: rect.height,
+                    top: rect.top + this.scrollTop,
+                });
+            })));
+        },
+        setListRect() {
+            return getRect(this, '.van-index-bar').then((rect) => {
+                if (!isDef(rect)) {
+                    return;
+                }
+                Object.assign(this, {
+                    height: rect.height,
+                    top: rect.top + this.scrollTop,
+                });
+            });
+        },
+        setSiderbarRect() {
+            return getRect(this, '.van-index-bar__sidebar').then((res) => {
+                if (!isDef(res)) {
+                    return;
+                }
+                this.sidebar = {
+                    height: res.height,
+                    top: res.top,
+                };
+            });
+        },
+        setDiffData({ target, data }) {
+            const diffData = {};
+            Object.keys(data).forEach((key) => {
+                if (target.data[key] !== data[key]) {
+                    diffData[key] = data[key];
+                }
+            });
+            if (Object.keys(diffData).length) {
+                target.setData(diffData);
+            }
+        },
+        getAnchorRect(anchor) {
+            return getRect(anchor, '.van-index-anchor-wrapper').then((rect) => ({
+                height: rect.height,
+                top: rect.top,
+            }));
+        },
+        getActiveAnchorIndex() {
+            const { children, scrollTop } = this;
+            const { sticky, stickyOffsetTop } = this.data;
+            for (let i = this.children.length - 1; i >= 0; i--) {
+                const preAnchorHeight = i > 0 ? children[i - 1].height : 0;
+                const reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0;
+                if (reachTop + scrollTop >= children[i].top) {
+                    return i;
+                }
+            }
+            return -1;
+        },
+        onScroll() {
+            const { children = [], scrollTop } = this;
+            if (!children.length) {
+                return;
+            }
+            const { sticky, stickyOffsetTop, zIndex, highlightColor } = this.data;
+            const active = this.getActiveAnchorIndex();
+            this.setDiffData({
+                target: this,
+                data: {
+                    activeAnchorIndex: active,
+                },
+            });
+            if (sticky) {
+                let isActiveAnchorSticky = false;
+                if (active !== -1) {
+                    isActiveAnchorSticky =
+                        children[active].top <= stickyOffsetTop + scrollTop;
+                }
+                children.forEach((item, index) => {
+                    if (index === active) {
+                        let wrapperStyle = '';
+                        let anchorStyle = `
+              color: ${highlightColor};
+            `;
+                        if (isActiveAnchorSticky) {
+                            wrapperStyle = `
+                height: ${children[index].height}px;
+              `;
+                            anchorStyle = `
+                position: fixed;
+                top: ${stickyOffsetTop}px;
+                z-index: ${zIndex};
+                color: ${highlightColor};
+              `;
+                        }
+                        this.setDiffData({
+                            target: item,
+                            data: {
+                                active: true,
+                                anchorStyle,
+                                wrapperStyle,
+                            },
+                        });
+                    }
+                    else if (index === active - 1) {
+                        const currentAnchor = children[index];
+                        const currentOffsetTop = currentAnchor.top;
+                        const targetOffsetTop = index === children.length - 1
+                            ? this.top
+                            : children[index + 1].top;
+                        const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
+                        const translateY = parentOffsetHeight - currentAnchor.height;
+                        const anchorStyle = `
+              position: relative;
+              transform: translate3d(0, ${translateY}px, 0);
+              z-index: ${zIndex};
+              color: ${highlightColor};
+            `;
+                        this.setDiffData({
+                            target: item,
+                            data: {
+                                active: true,
+                                anchorStyle,
+                            },
+                        });
+                    }
+                    else {
+                        this.setDiffData({
+                            target: item,
+                            data: {
+                                active: false,
+                                anchorStyle: '',
+                                wrapperStyle: '',
+                            },
+                        });
+                    }
+                });
+            }
+        },
+        onClick(event) {
+            this.scrollToAnchor(event.target.dataset.index);
+        },
+        onTouchMove(event) {
+            const sidebarLength = this.children.length;
+            const touch = event.touches[0];
+            const itemHeight = this.sidebar.height / sidebarLength;
+            let index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
+            if (index < 0) {
+                index = 0;
+            }
+            else if (index > sidebarLength - 1) {
+                index = sidebarLength - 1;
+            }
+            this.scrollToAnchor(index);
+        },
+        onTouchStop() {
+            this.scrollToAnchorIndex = null;
+        },
+        scrollToAnchor(index) {
+            if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
+                return;
+            }
+            this.scrollToAnchorIndex = index;
+            const anchor = this.children.find((item) => item.data.index === this.data.indexList[index]);
+            if (anchor) {
+                anchor.scrollIntoView(this.scrollTop);
+                this.$emit('select', anchor.data.index);
+            }
+        },
+    },
+});
+export default global['__wxComponents']['vant/index-bar/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-index-bar{position:relative}.van-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.van-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,14px);padding:0 var(--padding-base,4px) 0 var(--padding-md,16px)}
+</style>

File diff suppressed because it is too large
+ 20 - 0
wxcomponents/vant/info/index.vue


File diff suppressed because it is too large
+ 35 - 0
wxcomponents/vant/loading/index.vue


File diff suppressed because it is too large
+ 99 - 0
wxcomponents/vant/nav-bar/index.vue


File diff suppressed because it is too large
+ 150 - 0
wxcomponents/vant/notice-bar/index.vue


File diff suppressed because it is too large
+ 84 - 0
wxcomponents/vant/notify/index.vue


+ 1 - 1
wxcomponents/vant/notify/notify.js

@@ -32,7 +32,7 @@ export default function Notify(options) {
     delete options.selector;
     if (notify) {
         notify.setData(options);
-        notify.show();
+        notify.showNotify();
         return notify;
     }
     console.warn('未找到 van-notify 节点,请确认 selector 及 context 是否正确');

+ 52 - 0
wxcomponents/vant/overlay/index.vue

@@ -0,0 +1,52 @@
+<template>
+<uni-shadow-root class="vant-overlay-index"><root-portal v-if="rootPortal">
+  <include src="./overlay.wxml"></include>
+</root-portal>
+
+<include v-else src="./overlay.wxml"></include></uni-shadow-root>
+</template>
+
+<script>
+
+const __wxTemplateComponentProps = {}
+import __wxTemplateComponent0 from './overlay.vue'
+
+import VanTransition from '../transition/index.vue'
+global['__wxVueOptions'] = {components:{'van-transition': VanTransition,}}
+
+global['__wxRoute'] = 'vant/overlay/index'
+import { VantComponent } from '../common/component';
+VantComponent({
+    props: {
+        show: Boolean,
+        customStyle: String,
+        duration: {
+            type: null,
+            value: 300,
+        },
+        zIndex: {
+            type: Number,
+            value: 1,
+        },
+        lockScroll: {
+            type: Boolean,
+            value: true,
+        },
+        rootPortal: {
+            type: Boolean,
+            value: false,
+        },
+    },
+    methods: {
+        onClick() {
+            this.$emit('click');
+        },
+        // for prevent touchmove
+        noop() { },
+    },
+});
+export default global['__wxComponents']['vant/overlay/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-overlay{background-color:var(--overlay-background-color,rgba(0,0,0,.7));height:100%;left:0;position:fixed;top:0;width:100%}
+</style>

+ 17 - 0
wxcomponents/vant/overlay/overlay.vue

@@ -0,0 +1,17 @@
+<template>
+<uni-shadow-root class="vant-overlay-overlay"><van-transition :show="show" custom-class="van-overlay custom-class" :custom-style="'z-index: '+(zIndex)+'; '+(customStyle)" :duration="duration" @click.native="onClick" @touchmove.native.stop.prevent="_$self[(lockScroll ? 'noop' : '')||'_$noop']($event)">
+  <slot></slot>
+</van-transition></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/overlay/overlay'
+
+Component({})
+
+export default global['__wxComponents']['vant/overlay/overlay']
+</script>
+<style platform="mp-weixin">
+
+</style>

+ 34 - 0
wxcomponents/vant/panel/index.vue

@@ -0,0 +1,34 @@
+<template>
+<uni-shadow-root class="vant-panel-index"><view class="van-panel van-hairline--top-bottom custom-class">
+  <van-cell v-if="title || desc || status" :title="title" :label="desc" :value="status" custom-class="header-class" value-class="van-panel__header-value"></van-cell>
+  <slot v-else name="header"></slot>
+
+  <view class="van-panel__content">
+    <slot></slot>
+  </view>
+
+  <view class="van-panel__footer van-hairline--top footer-class">
+    <slot name="footer"></slot>
+  </view>
+</view></uni-shadow-root>
+</template>
+
+<script>
+import VanCell from '../cell/index.vue'
+global['__wxVueOptions'] = {components:{'van-cell': VanCell}}
+
+global['__wxRoute'] = 'vant/panel/index'
+import { VantComponent } from '../common/component';
+VantComponent({
+    classes: ['header-class', 'footer-class'],
+    props: {
+        desc: String,
+        title: String,
+        status: String,
+    },
+});
+export default global['__wxComponents']['vant/panel/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-panel{background:var(--panel-background-color,#fff)}.van-panel__header-value{color:var(--panel-header-value-color,#ee0a24)}.van-panel__footer{padding:var(--panel-footer-padding,8px 16px)}.van-panel__footer:empty{display:none}
+</style>

+ 134 - 0
wxcomponents/vant/picker-column/index.vue

@@ -0,0 +1,134 @@
+<template>
+<uni-shadow-root class="vant-picker-column-index"><view class="van-picker-column custom-class" :style="computed.rootStyle({ itemHeight, visibleItemCount })" @touchstart="onTouchStart" @touchmove.stop.prevent="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd">
+  <view :style="computed.wrapperStyle({ offset, itemHeight, visibleItemCount, duration })">
+    <view v-for="(option,index) in (options)" :key="option.index" :data-index="index" :style="'height: '+(itemHeight)+'px'" :class="'van-ellipsis '+(utils.bem('picker-column__item', { disabled: option && option.disabled, selected: index === currentIndex }))+' '+(index === currentIndex ? 'active-class' : '')" @click="onClickItem">{{ computed.optionText(option, valueKey) }}</view>
+  </view>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs><wxs src="./index.wxs" module="computed"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/picker-column/index'
+import { VantComponent } from '../common/component';
+import { range } from '../common/utils';
+import { isObj } from '../common/validator';
+const DEFAULT_DURATION = 200;
+VantComponent({
+    classes: ['active-class'],
+    props: {
+        valueKey: String,
+        className: String,
+        itemHeight: Number,
+        visibleItemCount: Number,
+        initialOptions: {
+            type: Array,
+            value: [],
+        },
+        defaultIndex: {
+            type: Number,
+            value: 0,
+            observer(value) {
+                this.setIndex(value);
+            },
+        },
+    },
+    data: {
+        startY: 0,
+        offset: 0,
+        duration: 0,
+        startOffset: 0,
+        options: [],
+        currentIndex: 0,
+    },
+    created() {
+        const { defaultIndex, initialOptions } = this.data;
+        this.set({
+            currentIndex: defaultIndex,
+            options: initialOptions,
+        }).then(() => {
+            this.setIndex(defaultIndex);
+        });
+    },
+    methods: {
+        getCount() {
+            return this.data.options.length;
+        },
+        onTouchStart(event) {
+            this.setData({
+                startY: event.touches[0].clientY,
+                startOffset: this.data.offset,
+                duration: 0,
+            });
+        },
+        onTouchMove(event) {
+            const { data } = this;
+            const deltaY = event.touches[0].clientY - data.startY;
+            this.setData({
+                offset: range(data.startOffset + deltaY, -(this.getCount() * data.itemHeight), data.itemHeight),
+            });
+        },
+        onTouchEnd() {
+            const { data } = this;
+            if (data.offset !== data.startOffset) {
+                this.setData({ duration: DEFAULT_DURATION });
+                const index = range(Math.round(-data.offset / data.itemHeight), 0, this.getCount() - 1);
+                this.setIndex(index, true);
+            }
+        },
+        onClickItem(event) {
+            const { index } = event.currentTarget.dataset;
+            this.setIndex(index, true);
+        },
+        adjustIndex(index) {
+            const { data } = this;
+            const count = this.getCount();
+            index = range(index, 0, count);
+            for (let i = index; i < count; i++) {
+                if (!this.isDisabled(data.options[i]))
+                    return i;
+            }
+            for (let i = index - 1; i >= 0; i--) {
+                if (!this.isDisabled(data.options[i]))
+                    return i;
+            }
+        },
+        isDisabled(option) {
+            return isObj(option) && option.disabled;
+        },
+        getOptionText(option) {
+            const { data } = this;
+            return isObj(option) && data.valueKey in option
+                ? option[data.valueKey]
+                : option;
+        },
+        setIndex(index, userAction) {
+            const { data } = this;
+            index = this.adjustIndex(index) || 0;
+            const offset = -index * data.itemHeight;
+            if (index !== data.currentIndex) {
+                return this.set({ offset, currentIndex: index }).then(() => {
+                    userAction && this.$emit('change', index);
+                });
+            }
+            return this.set({ offset });
+        },
+        setValue(value) {
+            const { options } = this.data;
+            for (let i = 0; i < options.length; i++) {
+                if (this.getOptionText(options[i]) === value) {
+                    return this.setIndex(i);
+                }
+            }
+            return Promise.resolve();
+        },
+        getValue() {
+            const { data } = this;
+            return data.options[data.currentIndex];
+        },
+    },
+});
+export default global['__wxComponents']['vant/picker-column/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-picker-column{color:var(--picker-option-text-color,#000);font-size:var(--picker-option-font-size,16px);overflow:hidden;text-align:center}.van-picker-column__item{padding:0 5px}.van-picker-column__item--selected{color:var(--picker-option-selected-text-color,#323233);font-weight:var(--font-weight-bold,500)}.van-picker-column__item--disabled{opacity:var(--picker-option-disabled-opacity,.3)}
+</style>

+ 0 - 0
wxcomponents/vant/picker/index.vue


Some files were not shown because too many files changed in this diff