├── .gitignore
├── README.md
├── app.js
├── app.json
├── app.wxss
├── components
└── statusLayout
│ ├── statusLayout.js
│ ├── statusLayout.json
│ ├── statusLayout.wxml
│ └── statusLayout.wxss
├── img
├── empty.png
├── error.png
└── loading.png
├── pages
└── index
│ ├── index.js
│ ├── index.json
│ ├── index.wxml
│ └── index.wxss
├── preview
└── preview.gif
└── utils
└── util.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *swp
2 | *~
3 | .idea
4 | node_modules
5 | npm-debug.log
6 | jsconfig.json
7 | project.config.json
8 | .vscode/
9 | typings/
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wx-statuslayout
2 | 微信小程序页面状态切换组件, 如果对您有帮助的话, 就赏个star吧~
3 |
4 | ## 效果图
5 |
6 | 
7 |
8 | ## 自定义属性
9 | - `rootStyle` 根容器样式, 可用来设置组件宽高等
10 | - `status` 默认状态
11 | - `emptyImage` 无数据时的图片
12 | - `emptyText` 无数据时的文案
13 | - `emptyImageWidth` 无数据时图片宽度
14 | - `emptyImageHeight` 无数据时图片高度
15 | - `errorImage` 发生错误时的图片
16 | - `errorText` 发生错误时的文案
17 | - `errorImageWidth` 错误图片宽
18 | - `errorImageHeight` 错误图片高
19 | - `loadingText` 加载文案
20 | - `loadingImage` 加载图片
21 | - `loadingImageWidth` 加载图片宽
22 | - `loadingImageHeight` 加载图片高
23 |
24 | ## 使用
25 | 1. 将`statusLayout`组件拷贝到自己项目中
26 | 2. 修改`statuslayout.js` 中的属性默认值, 状态图片、文案及图片宽高
27 | 3. 在需要使用的页面json文件中添加引用
28 | ``` json
29 | "usingComponents": {
30 | "statusLayout": "../../components/statusLayout/statusLayout"
31 | }
32 | ```
33 | 4. 在页面wxss文件中添加`statusLayout`布局
34 | ``` json
35 |
36 | //内容
37 |
38 | {{item}}
39 |
40 |
41 | ```
42 |
43 | 5. 在js文件中使用
44 |
45 | 1. 获取statusLayout组件对象 `statusLayout = this.selectComponent("#statusLayout")`
46 |
47 | 2. 切换布局`(两种切换布局的方法)`
48 |
49 | - 一个方法通过不同参数切换
50 | ```js
51 | statusLayout.setStatus("LOADING")
52 |
53 | statusLayout.setStatus("CONTENT")
54 |
55 | statusLayout.setStatus("ERROR")
56 |
57 | statusLayout.setStatus("EMPTY")
58 | ```
59 | - 直接调不同的方法切换
60 |
61 | ``` js
62 | statusLayout.showLoading()
63 |
64 | statusLayout.showContent()
65 |
66 | statusLayout.showError()
67 |
68 | statusLayout.showEmpty()
69 |
70 | ```
71 | 3. 绑定点击重新加载的回调
72 | ``` js
73 |
74 |
75 | //testStatusLayout 为页面js文件中加载数据的方法
76 | ```
77 |
78 | ### 在不同页面设置不同的状态图片及文案等
79 | ``` js
80 |
81 | //内容
82 |
83 | ```
84 |
85 |
86 |
--------------------------------------------------------------------------------
/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/index/index"
4 | ],
5 | "window":{
6 | "backgroundTextStyle":"light",
7 | "navigationBarBackgroundColor": "#fff",
8 | "navigationBarTitleText": "WeChat",
9 | "navigationBarTextStyle":"black"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 | .container {
3 | height: 100%;
4 | width: 100%;
5 | position: absolute
6 | }
7 |
--------------------------------------------------------------------------------
/components/statusLayout/statusLayout.js:
--------------------------------------------------------------------------------
1 | // components/statusLayout/statusLayout.js
2 | Component({
3 | /**
4 | * 组件的属性列表
5 | */
6 | properties: {
7 | rootStyle: {
8 | type: String,
9 | value:''
10 | },
11 | status: {
12 | type: String,
13 | value: 'CONTENT', //LOADING、CONTENT、EMPTY、ERROR
14 | observer: function (newVal, oldVal) {
15 | console.log(newVal)
16 | if (newVal == oldVal) return
17 | this.setStatus(newVal)
18 | }
19 | },
20 | emptyImage:{
21 | type: String,
22 | value: '../../img/empty.png'
23 | },
24 | emptyText: {
25 | type: String,
26 | value: '没有数据哦!'
27 | },
28 | emptyImageWidth: {
29 | type: Number,
30 | value: 64
31 | },
32 | emptyImageHeight: {
33 | type: Number,
34 | value: 64
35 | },
36 | errorImage: {
37 | type: String,
38 | value: '../../img/error.png'
39 | },
40 | errorText: {
41 | type: String,
42 | value: '操作失败, 请稍后重试!'
43 | },
44 | errorImageWidth: {
45 | type: Number,
46 | value: 64
47 | },
48 | errorImageHeight: {
49 | type: Number,
50 | value: 64
51 | },
52 | loadingText:{
53 | type: String,
54 | value: '加载中, 请稍后!'
55 | },
56 | loadingImage: {
57 | type: String,
58 | value: '../../img/loading.png'
59 | },
60 | loadingImageWidth: {
61 | type: Number,
62 | value: 40
63 | },
64 | loadingImageHeight: {
65 | type: Number,
66 | value: 40
67 | },
68 | },
69 |
70 | /**
71 | * 组件的初始数据
72 | */
73 | data: {
74 | statusText: '',
75 | statusImage: '',
76 | loadingAnimation:'',
77 | imgWidth:100,
78 | imgHeight: 100,
79 | },
80 |
81 | /**
82 | * 组件的方法列表
83 | */
84 | methods: {
85 | setStatus: function(status) {
86 | switch(status) {
87 | case 'LOADING':
88 | this.showLoading()
89 | break
90 | case 'EMPTY':
91 | this.showEmpty()
92 | break
93 | case 'ERROR':
94 | this.showError()
95 | break
96 | case 'CONTENT':
97 | this.showContent()
98 | break
99 | default:
100 | console.log("error: 未找到该status")
101 | break
102 | }
103 | },
104 | showLoading: function(){
105 | this.setData({
106 | status: "LOADING",
107 | statusText: this.properties.loadingText,
108 | statusImage: this.properties.loadingImage,
109 | imgWidth: this.properties.loadingImageWidth,
110 | imgHeight: this.properties.loadingImageHeight
111 | })
112 | },
113 | showEmpty: function(){
114 | this.setData({
115 | status: "EMPTY",
116 | statusText: this.properties.emptyText,
117 | statusImage: this.properties.emptyImage,
118 | imgWidth: this.properties.emptyImageWidth,
119 | imgHeight: this.properties.emptyImageHeight
120 | })
121 | },
122 | showError: function(){
123 | this.setData({
124 | status: "ERROR",
125 | statusText: this.properties.errorText,
126 | statusImage: this.properties.errorImage,
127 | imgWidth: this.properties.errorImageWidth,
128 | imgHeight: this.properties.errorImageHeight
129 | })
130 | },
131 | showContent: function(){
132 | this.setData({
133 | status: "CONTENT"
134 | })
135 | },
136 | onClickListener: function(res) {
137 | this.triggerEvent('OnClickListener', { status: this.data.status }, {})
138 | }
139 | }
140 | })
141 |
--------------------------------------------------------------------------------
/components/statusLayout/statusLayout.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/components/statusLayout/statusLayout.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{statusText}}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/components/statusLayout/statusLayout.wxss:
--------------------------------------------------------------------------------
1 | /* components/statusLayout/statusLayout.wxss */
2 |
3 | .status-layout-root{
4 | width: 100%;
5 | height: 100%;
6 | font-family: PingFangSC-Light;
7 | display: flex;
8 | justify-content: center;
9 | align-items: center;
10 | }
11 |
12 | .status-main{
13 | text-align: center;
14 | font-size: 14px;
15 | color: #bfbfbf;
16 | letter-spacing: -0.01px;
17 | align-self: center;
18 | font-weight: bold;
19 | }
20 |
21 | .status-main image{
22 | margin-bottom: 10px;
23 | }
24 |
25 | .status-image{
26 | width: 137px;
27 | height: 142px;
28 | }
29 |
30 | .status-image-anim{
31 | animation: weuiLoading 0.6s steps(12, end) infinite;
32 | }
33 |
34 | @keyframes weuiLoading {
35 | 0% {
36 | transform: rotate3d(0, 0, 1, 0deg);
37 | }
38 |
39 | 100% {
40 | transform: rotate3d(0, 0, 1, 360deg);
41 | }
42 | }
--------------------------------------------------------------------------------
/img/empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzjian/wx-statuslayout/8f7923d3a5507950a088acad4ee06f9b31fab3e0/img/empty.png
--------------------------------------------------------------------------------
/img/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzjian/wx-statuslayout/8f7923d3a5507950a088acad4ee06f9b31fab3e0/img/error.png
--------------------------------------------------------------------------------
/img/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzjian/wx-statuslayout/8f7923d3a5507950a088acad4ee06f9b31fab3e0/img/loading.png
--------------------------------------------------------------------------------
/pages/index/index.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | //获取应用实例
3 | const app = getApp()
4 | var statusLayout
5 | Page({
6 | data: {
7 | datas: ['测试数据1', '测试数据2', '测试数据3', '测试数据4', '测试数据5'],
8 | system: {}
9 | },
10 | //事件处理函数
11 | onReady: function(){
12 | var that = this
13 | statusLayout = this.selectComponent("#statusLayout")
14 | wx.getSystemInfo({
15 | success: function(res) {
16 | console.log(res)
17 | that.setData({
18 | system: res
19 | })
20 | }
21 | })
22 | },
23 | onLoad: function () {
24 | },
25 | testStatusLayout: function(e) {
26 | console.log(e)
27 | statusLayout.showLoading()
28 | // statusLayout.setStatus("LOADING")
29 | setTimeout(function(){
30 | var num = Math.floor(Math.random() * 10 + 1); //1-10
31 |
32 | if (num <= 3) {
33 | statusLayout.showContent()
34 | // statusLayout.setStatus("CONTENT")
35 | } else if (num <= 7) {
36 | statusLayout.showError()
37 | // statusLayout.setStatus("ERROR")
38 | } else {
39 | statusLayout.showEmpty()
40 | // statusLayout.setStatus("EMPTY")
41 | }
42 | },1000)
43 | }
44 | })
45 |
--------------------------------------------------------------------------------
/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "测试",
3 | "usingComponents": {
4 | "statusLayout": "../../components/statusLayout/statusLayout"
5 | }
6 | }
--------------------------------------------------------------------------------
/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{item}}
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/preview/preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zzjian/wx-statuslayout/8f7923d3a5507950a088acad4ee06f9b31fab3e0/preview/preview.gif
--------------------------------------------------------------------------------
/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 | module.exports = {
18 | formatTime: formatTime
19 | }
20 |
--------------------------------------------------------------------------------