├── README.md ├── app.js ├── app.json ├── app.wxss ├── images └── more │ ├── confirm-word1.png │ ├── loading.gif │ ├── title8.png │ └── wave.png ├── pages ├── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── logs │ ├── logs.js │ ├── logs.json │ ├── logs.wxml │ └── logs.wxss └── start │ ├── start.js │ ├── start.json │ ├── start.wxml │ └── start.wxss ├── project.config.json └── utils └── util.js /README.md: -------------------------------------------------------------------------------- 1 | 之前有用过小程序的欢迎页面,也是GitHub上找到的一个案例。近期有用到,简单的分享一下,可以让有需要的人避免重复造轮子和更好的创新学习。 2 | 3 | ### (一)效果预览 4 | 直接看效果如何,是否符合您的要求,不符合直接结束浏览,避免浪费您的时间。 5 | 6 | ![运行结果图](http://pbr0erxxq.bkt.clouddn.com/2018-07-29/02.gif) 7 | 8 | ### (二)代码目录 9 | 简单实用,直接下载工具打开预览,[代码下载](https://github.com/super456/wechatWeclomePage) 10 | 11 | ![代码目录](http://pbr0erxxq.bkt.clouddn.com/2018-07-29/01.png) 12 | 13 | ### (三)参考文献 14 | [微信小程序商城,微信小程序微店](https://github.com/EastWorld/wechat-app-mall) 15 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | // 展示本地存储能力 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | 9 | // 登录 10 | wx.login({ 11 | success: res => { 12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 13 | } 14 | }) 15 | // 获取用户信息 16 | wx.getSetting({ 17 | success: res => { 18 | if (res.authSetting['scope.userInfo']) { 19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 20 | wx.getUserInfo({ 21 | success: res => { 22 | // 可以将 res 发送给后台解码出 unionId 23 | this.globalData.userInfo = res.userInfo 24 | 25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 26 | // 所以此处加入 callback 以防止这种情况 27 | if (this.userInfoReadyCallback) { 28 | this.userInfoReadyCallback(res) 29 | } 30 | } 31 | }) 32 | } 33 | } 34 | }) 35 | }, 36 | globalData: { 37 | userInfo: null 38 | } 39 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/start/start", 4 | "pages/index/index", 5 | "pages/logs/logs" 6 | ], 7 | "window": { 8 | "backgroundTextStyle": "light", 9 | "navigationBarBackgroundColor": "#fff", 10 | "navigationBarTitleText": "WeChat欢迎页面", 11 | "navigationBarTextStyle": "black" 12 | }, 13 | "tabBar": { 14 | "list": [ 15 | { 16 | "pagePath": "pages/index/index", 17 | "text": "首页" 18 | }, 19 | { 20 | "pagePath": "pages/logs/logs", 21 | "text": "日志" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /images/more/confirm-word1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/super456/wechatWeclomePage/2d6a0c7d6cd014a3aa9302d25a0e75c51662b529/images/more/confirm-word1.png -------------------------------------------------------------------------------- /images/more/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/super456/wechatWeclomePage/2d6a0c7d6cd014a3aa9302d25a0e75c51662b529/images/more/loading.gif -------------------------------------------------------------------------------- /images/more/title8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/super456/wechatWeclomePage/2d6a0c7d6cd014a3aa9302d25a0e75c51662b529/images/more/title8.png -------------------------------------------------------------------------------- /images/more/wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/super456/wechatWeclomePage/2d6a0c7d6cd014a3aa9302d25a0e75c51662b529/images/more/wave.png -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | const app = getApp() 4 | 5 | Page({ 6 | data: { 7 | motto: 'Hello World', 8 | userInfo: {}, 9 | hasUserInfo: false, 10 | canIUse: wx.canIUse('button.open-type.getUserInfo') 11 | }, 12 | //事件处理函数 13 | bindViewTap: function() { 14 | wx.navigateTo({ 15 | url: '../logs/logs' 16 | }) 17 | }, 18 | onLoad: function () { 19 | if (app.globalData.userInfo) { 20 | this.setData({ 21 | userInfo: app.globalData.userInfo, 22 | hasUserInfo: true 23 | }) 24 | } else if (this.data.canIUse){ 25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 26 | // 所以此处加入 callback 以防止这种情况 27 | app.userInfoReadyCallback = res => { 28 | this.setData({ 29 | userInfo: res.userInfo, 30 | hasUserInfo: true 31 | }) 32 | } 33 | } else { 34 | // 在没有 open-type=getUserInfo 版本的兼容处理 35 | wx.getUserInfo({ 36 | success: res => { 37 | app.globalData.userInfo = res.userInfo 38 | this.setData({ 39 | userInfo: res.userInfo, 40 | hasUserInfo: true 41 | }) 42 | } 43 | }) 44 | } 45 | }, 46 | getUserInfo: function(e) { 47 | console.log(e) 48 | app.globalData.userInfo = e.detail.userInfo 49 | this.setData({ 50 | userInfo: e.detail.userInfo, 51 | hasUserInfo: true 52 | }) 53 | } 54 | }) 55 | -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{userInfo.nickName}} 8 | 9 | 10 | 11 | {{motto}} 12 | 13 | 14 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | } 7 | 8 | .userinfo-avatar { 9 | width: 128rpx; 10 | height: 128rpx; 11 | margin: 20rpx; 12 | border-radius: 50%; 13 | } 14 | 15 | .userinfo-nickname { 16 | color: #aaa; 17 | } 18 | 19 | .usermotto { 20 | margin-top: 200px; 21 | } -------------------------------------------------------------------------------- /pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | const util = require('../../utils/util.js') 3 | 4 | Page({ 5 | data: { 6 | logs: [] 7 | }, 8 | onLoad: function () { 9 | this.setData({ 10 | logs: (wx.getStorageSync('logs') || []).map(log => { 11 | return util.formatTime(new Date(log)) 12 | }) 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志" 3 | } -------------------------------------------------------------------------------- /pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /pages/start/start.js: -------------------------------------------------------------------------------- 1 | //login.js 2 | //获取应用实例 3 | var app = getApp(); 4 | Page({ 5 | data: { 6 | remind: '加载中', 7 | angle: 0, 8 | userInfo: {} 9 | }, 10 | goToIndex: function() { 11 | wx.switchTab({ 12 | url: '/pages/index/index', 13 | }); 14 | }, 15 | onLoad: function() { 16 | var that = this 17 | wx.setNavigationBarTitle({ 18 | title: wx.getStorageSync('mallName') 19 | }) 20 | }, 21 | onShow: function() { 22 | let that = this 23 | let userInfo = wx.getStorageSync('userInfo') 24 | if (!userInfo) { 25 | wx.getUserInfo({ 26 | success: res => { 27 | app.globalData.userInfo = res.userInfo 28 | this.setData({ 29 | userInfo: res.userInfo, 30 | }) 31 | } 32 | }) 33 | } else { 34 | that.setData({ 35 | userInfo: userInfo 36 | }) 37 | } 38 | }, 39 | onReady: function() { 40 | var that = this; 41 | setTimeout(function() { 42 | that.setData({ 43 | remind: '' 44 | }); 45 | }, 1000); 46 | wx.onAccelerometerChange(function(res) { 47 | var angle = -(res.x * 30).toFixed(1); 48 | if (angle > 14) { 49 | angle = 14; 50 | } else if (angle < -14) { 51 | angle = -14; 52 | } 53 | if (that.data.angle !== angle) { 54 | that.setData({ 55 | angle: angle 56 | }); 57 | } 58 | }); 59 | } 60 | }); -------------------------------------------------------------------------------- /pages/start/start.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": " ", 3 | "enablePullDownRefresh": false, 4 | "disableScroll": true 5 | } -------------------------------------------------------------------------------- /pages/start/start.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 进入店铺 18 | 19 | @qindiandadudu 贡献本页代码 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /pages/start/start.wxss: -------------------------------------------------------------------------------- 1 | /**start.wxss**/ 2 | page{ 3 | font-family: -apple-system-font, Helvetica Neue, Helvetica, sans-serif; 4 | font-size: 10pt; 5 | line-height: 150%; 6 | min-height: 100%; 7 | position: relative; 8 | display: flex; 9 | flex-direction: column; 10 | align-items: stretch; 11 | } 12 | .container { 13 | position: relative; 14 | flex: 1; 15 | display: flex; 16 | flex-direction: column; 17 | background: #69C3AA; 18 | align-items: stretch; 19 | padding: 0; 20 | height: 100%; 21 | overflow: hidden; 22 | justify-content: space-between; 23 | box-sizing: border-box; 24 | } 25 | .content{ 26 | flex: 1; 27 | display: flex; 28 | position: relative; 29 | z-index: 10; 30 | flex-direction: column; 31 | align-items: stretch; 32 | justify-content: center; 33 | width: 100%; 34 | height: 100%; 35 | padding-bottom: 450rpx; 36 | background: -webkit-gradient(linear, left top, left bottom, from(rgba(244,244,244,0)), color-stop(0.1, #f4f4f4), to(#f4f4f4)); 37 | opacity: 0; 38 | transform: translate3d(0,100%,0); 39 | animation: rise 3s cubic-bezier(0.19, 1, 0.22, 1) .25s forwards; 40 | } 41 | 42 | .remind-box { 43 | flex: 1; 44 | display: flex; 45 | flex-direction: column; 46 | align-items: center; 47 | justify-content: center; 48 | padding-bottom: 300rpx; 49 | } 50 | .remind-img { 51 | width: 250rpx; 52 | height: 250rpx; 53 | padding-bottom: 25rpx; 54 | } 55 | 56 | @keyframes rise{ 57 | 0% {opacity: 0;transform: translate3d(0,100%,0);} 58 | 50% {opacity: 1;} 59 | 100% {opacity: 1;transform: translate3d(0,450rpx,0);} 60 | } 61 | .title{ 62 | position: absolute; 63 | top: 30rpx; 64 | left: 50%; 65 | width: 600rpx; 66 | height: 200rpx; 67 | margin-left: -300rpx; 68 | opacity: 0; 69 | animation: show 2.5s cubic-bezier(0.19, 1, 0.22, 1) .5s forwards; 70 | } 71 | 72 | .smalltitle{ 73 | position: absolute; 74 | top: 50rpx; 75 | left: 50%; 76 | width: 600rpx; 77 | height: 200rpx; 78 | margin-left: -300rpx; 79 | opacity: 0; 80 | animation: show 2.5s cubic-bezier(0.19, 1, 0.22, 1) .5s forwards; 81 | } 82 | 83 | @keyframes show{ 84 | 0% {opacity: 0;} 85 | 100% {opacity: .95;} 86 | } 87 | 88 | .hd { 89 | position: absolute; 90 | top: 0; 91 | left: 50%; 92 | width: 1000rpx; 93 | margin-left: -500rpx; 94 | height: 200rpx; 95 | transition: all .35s ease; 96 | } 97 | .logo { 98 | position: absolute; 99 | z-index: 2; 100 | left: 50%; 101 | bottom: 200rpx; 102 | width: 160rpx; 103 | height: 160rpx; 104 | margin-left: -80rpx; 105 | border-radius: 160rpx; 106 | animation: sway 10s ease-in-out infinite; 107 | opacity: .95; 108 | } 109 | @keyframes sway{ 110 | 0% {transform: translate3d(0,20rpx,0) rotate(-15deg); } 111 | 17% {transform: translate3d(0,0rpx,0) rotate(25deg); } 112 | 34% {transform: translate3d(0,-20rpx,0) rotate(-20deg); } 113 | 50% {transform: translate3d(0,-10rpx,0) rotate(15deg); } 114 | 67% {transform: translate3d(0,10rpx,0) rotate(-25deg); } 115 | 84% {transform: translate3d(0,15rpx,0) rotate(15deg); } 116 | 100% {transform: translate3d(0,20rpx,0) rotate(-15deg); } 117 | } 118 | .wave { 119 | position: absolute; 120 | z-index: 3; 121 | right: 0; 122 | bottom: 0; 123 | opacity: 0.725; 124 | height: 260rpx; 125 | width: 2250rpx; 126 | animation: wave 10s linear infinite; 127 | } 128 | .wave-bg { 129 | z-index: 1; 130 | animation: wave-bg 10.25s linear infinite; 131 | } 132 | @keyframes wave{ 133 | from {transform: translate3d(125rpx,0,0);} 134 | to {transform: translate3d(1125rpx,0,0);} 135 | } 136 | @keyframes wave-bg{ 137 | from {transform: translate3d(375rpx,0,0);} 138 | to {transform: translate3d(1375rpx,0,0);} 139 | } 140 | 141 | .bd { 142 | position: relative; 143 | flex: 1; 144 | display: flex; 145 | flex-direction: column; 146 | align-items: stretch; 147 | animation: bd-rise 2s cubic-bezier(0.23,1,0.32,1) .75s forwards; 148 | opacity: 0; 149 | } 150 | @keyframes bd-rise{ 151 | from {opacity: 0; transform: translate3d(0,60rpx,0); } 152 | to {opacity: 1; transform: translate3d(0,0,0); } 153 | } 154 | 155 | .confirm-btn { 156 | font-size: 13pt; 157 | line-height: 85rpx; 158 | height: 85rpx; 159 | background: #69C3AA; 160 | color: #fff; 161 | text-align: center; 162 | border-radius: 100rpx; 163 | margin: 40% 20%; 164 | } 165 | .confirm-btn:active { 166 | opacity: .8; 167 | } 168 | 169 | 170 | .copyright { 171 | font-size: 28rpx; 172 | color: #999; 173 | position: fixed; 174 | bottom: 0; 175 | left: 0; 176 | right: 0; 177 | padding: 30rpx; 178 | text-align: center; 179 | } -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件。", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": true, 9 | "postcss": true, 10 | "minified": true, 11 | "newFeature": true 12 | }, 13 | "compileType": "miniprogram", 14 | "libVersion": "2.2.0", 15 | "appid": "wx5bba873c78aed429", 16 | "projectname": "%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%99%BB%E5%BD%95%E6%AC%A2%E8%BF%8E%E9%A1%B5%E9%9D%A2", 17 | "isGameTourist": false, 18 | "condition": { 19 | "search": { 20 | "current": -1, 21 | "list": [] 22 | }, 23 | "conversation": { 24 | "current": -1, 25 | "list": [] 26 | }, 27 | "game": { 28 | "currentL": -1, 29 | "list": [] 30 | }, 31 | "miniprogram": { 32 | "current": -1, 33 | "list": [] 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | const formatTime = date => { 2 | const year = date.getFullYear() 3 | const month = date.getMonth() + 1 4 | const day = date.getDate() 5 | const hour = date.getHours() 6 | const minute = date.getMinutes() 7 | const second = date.getSeconds() 8 | 9 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 10 | } 11 | 12 | const formatNumber = n => { 13 | n = n.toString() 14 | return n[1] ? n : '0' + n 15 | } 16 | 17 | function obj2uri(obj) { 18 | return Object.keys(obj).map(function (k) { 19 | return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 20 | }).join('&'); 21 | } 22 | 23 | 24 | //字符串转换为时间戳 25 | function getDateTimeStamp(dateStr) { 26 | return Date.parse(dateStr.replace(/-/gi, "/")); 27 | } 28 | //格式化时间 已存在格式化日期时间函数,但未调用2018/04/28 29 | function getDateDiff(dateStr) { 30 | var publishTime = getDateTimeStamp(dateStr) / 1000, 31 | d_seconds, 32 | d_minutes, 33 | d_hours, 34 | d_days, 35 | timeNow = parseInt(new Date().getTime() / 1000), 36 | d, 37 | 38 | date = new Date(publishTime * 1000), 39 | Y = date.getFullYear(), 40 | M = date.getMonth() + 1, 41 | D = date.getDate(), 42 | H = date.getHours(), 43 | m = date.getMinutes(), 44 | s = date.getSeconds(); 45 | //小于10的在前面补0 46 | if (M < 10) { 47 | M = '0' + M; 48 | } 49 | if (D < 10) { 50 | D = '0' + D; 51 | } 52 | if (H < 10) { 53 | H = '0' + H; 54 | } 55 | if (m < 10) { 56 | m = '0' + m; 57 | } 58 | if (s < 10) { 59 | s = '0' + s; 60 | } 61 | 62 | d = timeNow - publishTime; 63 | d_days = parseInt(d / 86400); 64 | d_hours = parseInt(d / 3600); 65 | d_minutes = parseInt(d / 60); 66 | d_seconds = parseInt(d); 67 | 68 | if (d_days > 0 && d_days < 3) { 69 | return d_days + '天前'; 70 | } else if (d_days <= 0 && d_hours > 0) { 71 | return d_hours + '小时前'; 72 | } else if (d_hours <= 0 && d_minutes > 0) { 73 | return d_minutes + '分钟前'; 74 | } else if (d_seconds < 60) { 75 | if (d_seconds <= 0) { 76 | return '刚刚'; 77 | } else { 78 | return d_seconds + '秒前'; 79 | } 80 | } else if (d_days >= 3 && d_days < 30) { 81 | return M + '-' + D + ' ' + H + ':' + m; 82 | } else if (d_days >= 30) { 83 | return Y + '-' + M + '-' + D + ' ' + H + ':' + m; 84 | } 85 | } 86 | 87 | function buttonClicked(self) { 88 | self.setData({ 89 | buttonClicked: true 90 | }) 91 | setTimeout(function () { 92 | self.setData({ 93 | buttonClicked: false 94 | }) 95 | }, 500) 96 | } 97 | 98 | module.exports = { 99 | formatTime: formatTime, 100 | getDateDiff: getDateDiff, 101 | buttonClicked: buttonClicked, 102 | } 103 | 104 | --------------------------------------------------------------------------------