├── .gitignore
├── LICENSE
├── README.md
├── assets
├── wxu.png
└── wxu
│ ├── authorize.gif
│ ├── infiniteScroll.gif
│ ├── popup.gif
│ └── toast.gif
├── docs
├── README.md
└── wxu
│ ├── authorize.md
│ ├── infiniteScroll.md
│ ├── popup.md
│ └── toast.md
├── package.json
└── src
├── app.js
├── app.json
├── app.wxss
├── pages
├── authorize
│ ├── authorize.js
│ ├── authorize.json
│ ├── authorize.wxml
│ └── authorize.wxss
├── index
│ ├── img
│ │ ├── base64.js
│ │ ├── icon_footer.png
│ │ ├── icon_footer_link.png
│ │ ├── icon_intro.png
│ │ ├── icon_nav_feedback.png
│ │ ├── icon_nav_form.png
│ │ ├── icon_nav_nav.png
│ │ ├── icon_nav_search.png
│ │ ├── icon_nav_special.png
│ │ ├── icon_nav_widget.png
│ │ ├── icon_nav_z-index.png
│ │ ├── icon_tabbar.png
│ │ ├── logo.png
│ │ ├── pic_160.png
│ │ ├── pic_article.png
│ │ └── vcode.jpg
│ ├── index.js
│ ├── index.wxml
│ └── index.wxss
├── infiniteScroll
│ ├── infiniteScroll.js
│ ├── infiniteScroll.json
│ ├── infiniteScroll.wxml
│ └── infiniteScroll.wxss
├── popup
│ ├── popup.js
│ ├── popup.json
│ └── popup.wxml
└── toast
│ ├── toast.js
│ ├── toast.json
│ └── toast.wxml
└── wxu
├── authorize
└── authorize.js
├── component.js
├── infiniteScroll
├── infiniteScroll.js
├── infiniteScroll.wxml
└── infiniteScroll.wxss
├── popup
├── popup.js
├── popup.wxml
└── popup.wxss
├── toast
├── toast.js
├── toast.wxml
└── toast.wxss
├── wxu.js
└── wxu.wxss
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/*
3 | node_modules/
4 | src/project.config.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Zhang Yu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wxu for 小程序
2 |
3 | ## 概述
4 |
5 | [wxu](https://github.com/vincheung/wxu) 微信小程序 WeUI 的轻量级补充,及其他组件(Authorize)。
6 |
7 |
8 | ## 预览
9 | 用[微信web开发者工具](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html)打开 `src` 目录(请注意,是 `src` 目录,不是整个项目)。
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ## 使用
23 |
24 | - 组件的 wxml 结构请看 `src/wxu/` 下的组件。
25 | - 样式文件可直接引用 `src/wxu/wxu.wxss`。
26 |
27 |
28 | ## 文档
29 |
30 | * [Toast - 提示框](https://github.com/vincheung/wxu/blob/master/docs/wxu/toast.md)
31 | * [Popup - 弹出框](https://github.com/vincheung/wxu/blob/master/docs/wxu/popup.md)
32 | * [InfiniteScroll - 无限滚动](https://github.com/vincheung/wxu/blob/master/docs/wxu/infiniteScroll.md)
33 | * [Authorize - 授权流程](https://github.com/vincheung/wxu/blob/master/docs/wxu/authorize.md)
34 |
35 |
36 | ## License
37 |
38 | The MIT License.
39 |
40 |
41 | ## 贡献
42 |
43 | 如果你有好的意见或建议,欢迎给我提 issue。
44 |
--------------------------------------------------------------------------------
/assets/wxu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/assets/wxu.png
--------------------------------------------------------------------------------
/assets/wxu/authorize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/assets/wxu/authorize.gif
--------------------------------------------------------------------------------
/assets/wxu/infiniteScroll.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/assets/wxu/infiniteScroll.gif
--------------------------------------------------------------------------------
/assets/wxu/popup.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/assets/wxu/popup.gif
--------------------------------------------------------------------------------
/assets/wxu/toast.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/assets/wxu/toast.gif
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | - [Toast - 提示框](wxu/toast.md)
4 | - [Popup - 弹出框](wxu/popup.md)
5 | - [InfiniteScroll - 无限滚动](wxu/infiniteScroll.md)
6 | - [Authorize - 授权流程](wxu/authorize.md)
--------------------------------------------------------------------------------
/docs/wxu/authorize.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Authorize(options)
4 | 授权流程
5 |
6 | 参数 | 说明 | 类型 | 可选值 | 默认值
7 | --- | --- | --- | --- | ---
8 | scope | 需要获取权限的 scope | Array |
9 | success | 授权完成的回调函数 | Function
10 |
11 |
12 | ## 说明
13 | Authorize 方法在 onShow 生命周期函数中执行。
14 |
15 |
16 | **Example**
17 |
18 | ```js
19 | // 请注意无 AppID 关联下,此页面功能是受限的
20 | import { Authorize } from '../../wxu/wxu'
21 |
22 | Page({
23 | onShow() {
24 | Authorize({
25 | scope: ['scope.userInfo', 'scope.userLocation'],
26 | success: () => {
27 | this.init()
28 | }
29 | })
30 | },
31 | init() {
32 | this.setData({
33 | success: '授权完成,执行 init 函数。'
34 | })
35 | }
36 | })
37 | ```
--------------------------------------------------------------------------------
/docs/wxu/infiniteScroll.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # InfiniteScroll(options)
4 | 无限滚动指令
5 |
6 | 参数 | 说明 | 类型 | 可选值 | 默认值
7 | --- | --- | --- | --- | ---
8 | name | 注册事件函数名 | String |
9 | msg | 触发时文本内容 | String | | 加载中...
10 | doneMsg | 结束时文本内容 | String | | 已无更多
11 | spinnerType | icon | String | fading-circle, snake | fading-circle
12 | className | 文本内容的自定义类名 | String
13 |
14 |
15 | ## 注册的事件函数中的api
16 | 完成此次加载:done()
17 |
18 | InfiniteScroll 结束:done(true)
19 |
20 |
21 | ## 说明
22 | 注意小程序上拉触底事件的处理函数 onReachBottom 执行条件需元素内容到达底部。
23 |
24 | 注册事件函数需传入 done 方法。
25 |
26 | 若希望 InfiniteScroll 组件在内容不足时总显示在窗口底部,请参考例子中的 Sticky footers 布局。
27 |
28 |
29 | **Example**
30 |
31 | ```html
32 |
33 |
34 |
35 |
36 | InfiniteScroll
37 | 无限滚动指令。
38 |
39 |
40 | {{ item }}
41 |
42 |
43 |
44 |
48 |
49 | ```
50 |
51 | ```js
52 | import { InfiniteScroll } from '../../wxu/wxu'
53 |
54 | Page({
55 | data: {
56 | list: []
57 | },
58 | onLoad() {
59 | InfiniteScroll({
60 | name: 'getData',
61 | msg: '玩命加载中...',
62 | doneMsg: '我是有底线的',
63 | spinnerType: 'snake'
64 | })
65 | this.loadMore()
66 | },
67 | getData(done) {
68 | let list = this.data.list
69 | let last = list[list.length - 1] || 0
70 | setTimeout(() => {
71 | for (let i = 1; i <= 10; i++) {
72 | list.push(last + i)
73 | }
74 | this.setData({
75 | list: list
76 | })
77 | if (list[list.length - 1] < 20) {
78 | done()
79 | } else {
80 | done(true)
81 | }
82 | }, 1000)
83 | },
84 | onReachBottom() {
85 | this.loadMore()
86 | }
87 | })
88 | ```
--------------------------------------------------------------------------------
/docs/wxu/popup.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Popup(options)
4 | 弹出框,可自定义内容
5 |
6 | 参数 | 说明 | 类型 | 可选值 | 默认值
7 | --- | --- | --- | --- | ---
8 | type | Popup 的类型 | String | default, button | default
9 | msg | 文本内容 | String
10 | className | Popup 的自定义类名,若有将覆盖默认样式 | String
11 | duration(default) | 持续时间(毫秒),若为 -1
则不会自动关闭 | Number | | 1500
12 | buttonType(button) | 按钮的样式类型 | String | primary, default, warn
13 | plain(button) | 按钮是否镂空,背景色透明 | Boolean | | false
14 | success | 关闭后的回调函数 | Function
15 |
16 | > 执行 Popup 方法会返回一个 Popup 实例,每个实例都有 close 方法,用于手动关闭 Popup
17 | ```js
18 | let instance = Popup({
19 | duration: 10000,
20 | msg: '不负代码不负卿',
21 | success: () => console.log('PopupTop完成')
22 | })
23 | setTimeout(() => {
24 | instance.close()
25 | }, 3000)
26 | ```
27 |
28 |
29 | **Example**
30 |
31 | ```html
32 |
33 |
34 |
35 |
36 |
37 | Popup
38 | 弹出框,可自定义内容。
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ```
48 |
49 | ```js
50 | import { Popup } from '../../wxu/wxu'
51 |
52 | Page({
53 | Popup() {
54 | Popup({
55 | msg: '不负代码不负卿',
56 | success: () => console.log('PopupTop完成')
57 | })
58 | },
59 | PopupButton() {
60 | Popup({
61 | type: 'button',
62 | msg: '关闭',
63 | buttonType: 'primary',
64 | success: () => console.log('PopupButton完成')
65 | })
66 | }
67 | })
68 | ```
--------------------------------------------------------------------------------
/docs/wxu/toast.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Toast(options)
4 | 提示窗,支持文字与 icon 自由组合
5 |
6 | 参数 | 说明 | 类型 | 可选值 | 默认值
7 | --- | --- | --- | --- | ---
8 | msg | 文本内容 | String
9 | position | Toast 的位置 | String | top, bottom, middle | middle
10 | duration | 持续时间(毫秒),若为 -1
则不会自动关闭 | Number | | 1500
11 | className | Toast 的自定义类名 | String
12 | icon | 小程序原生 icon 组件 | String | success, success_no_circle, info, warn,
waiting, cancel, download, search, clear
13 | colol | icon 的颜色 | String | | white
14 | success | 关闭后的回调函数 | Function
15 |
16 | > 执行 Toast 方法会返回一个 Toast 实例,每个实例都有 close 方法,用于手动关闭 Toast
17 | ```js
18 | let instance = Toast({
19 | duration: 10000,
20 | msg: '不负代码不负卿',
21 | success: () => console.log('showToast完成')
22 | })
23 | setTimeout(() => {
24 | instance.close()
25 | }, 3000)
26 | ```
27 |
28 |
29 | **Example**
30 |
31 | ```html
32 |
33 |
34 |
35 |
36 |
37 | Toast
38 | 弹出式提示,支持文字与 icon 自由组合。
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | ```
49 |
50 | ```js
51 | import { Toast } from '../../wxu/wxu'
52 |
53 | Page({
54 | showToast() {
55 | Toast({
56 | msg: '不负代码不负卿',
57 | success: () => console.log('showToast完成')
58 | })
59 | },
60 | showIcon() {
61 | Toast({
62 | icon: 'search',
63 | success: () => console.log('showIcon完成')
64 | })
65 | },
66 | showToastIcon() {
67 | Toast({
68 | msg: '操作成功',
69 | icon: 'success_no_circle',
70 | success: () => console.log('showToastIcon完成')
71 | })
72 | }
73 | })
74 | ```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wxu",
3 | "version": "1.0.0",
4 | "description": "微信小程序 WeUI 的轻量级补充。",
5 | "main": "src/app.js",
6 | "directories": {},
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+ssh://git@github.com/vincheung/wxu.git"
13 | },
14 | "keywords": ["wx-component", "wxapp"],
15 | "author": "vincheung",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/vincheung/wxu/issues"
19 | },
20 | "homepage": "https://github.com/vincheung/wxu#readme"
21 | }
22 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | App({})
--------------------------------------------------------------------------------
/src/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":[
3 | "pages/index/index",
4 | "pages/toast/toast",
5 | "pages/popup/popup",
6 | "pages/infiniteScroll/infiniteScroll",
7 | "pages/authorize/authorize"
8 | ],
9 | "window": {
10 | "navigationBarTextStyle": "black",
11 | "navigationBarTitleText": "wxu for 小程序",
12 | "navigationBarBackgroundColor": "#f8f8f8",
13 | "backgroundColor": "#f8f8f8"
14 | },
15 | "debug": false
16 | }
17 |
--------------------------------------------------------------------------------
/src/app.wxss:
--------------------------------------------------------------------------------
1 | @import 'wxu/wxu.wxss';
2 |
3 | page {
4 | font-size: 16px;
5 | font-family: -apple-system-font, Helvetica Neue, Helvetica, sans-serif;
6 | }
7 |
8 | .page__hd {
9 | padding: 40px;
10 | }
11 |
12 | .page__bd {
13 | padding-bottom: 40px;
14 | }
15 |
16 | .page__title {
17 | text-align: left;
18 | font-size: 20px;
19 | font-weight: 400;
20 | }
21 |
22 | .page__desc {
23 | margin-top: 5px;
24 | color: #888888;
25 | text-align: left;
26 | font-size: 14px;
27 | }
28 |
29 | .weui-btn-area {
30 | margin: 1.17647059em 15px .3em;
31 | }
32 |
33 | .weui-btn {
34 | margin-top: 15px;
35 | }
36 |
37 | .weui-btn:first-child {
38 | margin-top: 0;
39 | }
--------------------------------------------------------------------------------
/src/pages/authorize/authorize.js:
--------------------------------------------------------------------------------
1 | // 请注意无 AppID 关联下,此页面功能是受限的
2 | import { Authorize } from '../../wxu/wxu'
3 |
4 | Page({
5 | onShow() {
6 | Authorize({
7 | scope: ['scope.userInfo', 'scope.userLocation'],
8 | success: () => {
9 | this.init()
10 | }
11 | })
12 | },
13 | init() {
14 | this.setData({
15 | success: '授权完成,执行 init 函数。'
16 | })
17 | }
18 | })
--------------------------------------------------------------------------------
/src/pages/authorize/authorize.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "Authorize"
3 | }
--------------------------------------------------------------------------------
/src/pages/authorize/authorize.wxml:
--------------------------------------------------------------------------------
1 | {{ success ? success : ''}}
--------------------------------------------------------------------------------
/src/pages/authorize/authorize.wxss:
--------------------------------------------------------------------------------
1 | .center {
2 | position: absolute;
3 | top: 50%;
4 | left: 50%;
5 | transform: translate(-50%, -50%);
6 | width: 100%;
7 | text-align: center;
8 | }
--------------------------------------------------------------------------------
/src/pages/index/img/base64.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | icon20: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAMAAABgZ9sFAAAAVFBMVEXx8fHMzMzr6+vn5+fv7+/t7e3d3d2+vr7W1tbHx8eysrKdnZ3p6enk5OTR0dG7u7u3t7ejo6PY2Njh4eHf39/T09PExMSvr6+goKCqqqqnp6e4uLgcLY/OAAAAnklEQVRIx+3RSRLDIAxE0QYhAbGZPNu5/z0zrXHiqiz5W72FqhqtVuuXAl3iOV7iPV/iSsAqZa9BS7YOmMXnNNX4TWGxRMn3R6SxRNgy0bzXOW8EBO8SAClsPdB3psqlvG+Lw7ONXg/pTld52BjgSSkA3PV2OOemjIDcZQWgVvONw60q7sIpR38EnHPSMDQ4MjDjLPozhAkGrVbr/z0ANjAF4AcbXmYAAAAASUVORK5CYII=",
3 | icon60: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAMAAAAOusbgAAAAeFBMVEUAwAD///+U5ZTc9twOww7G8MYwzDCH4YcfyR9x23Hw+/DY9dhm2WZG0kbT9NP0/PTL8sux7LFe115T1VM+zz7i+OIXxhes6qxr2mvA8MCe6J6M4oz6/frr+us5zjn2/fa67rqB4IF13XWn6ad83nxa1loqyirn+eccHxx4AAAC/klEQVRo3u2W2ZKiQBBF8wpCNSCyLwri7v//4bRIFVXoTBBB+DAReV5sG6lTXDITiGEYhmEYhmEYhmEYhmEY5v9i5fsZGRx9PyGDne8f6K9cfd+mKXe1yNG/0CcqYE86AkBMBh66f20deBc7wA/1WFiTwvSEpBMA2JJOBsSLxe/4QEEaJRrASP8EVF8Q74GbmevKg0saa0B8QbwBdjRyADYxIhqxAZ++IKYtciPXLQVG+imw+oo4Bu56rjEJ4GYsvPmKOAB+xlz7L5aevqUXuePWVhvWJ4eWiwUQ67mK51qPj4dFDMlRLBZTqF3SDvmr4BwtkECu5gHWPkmDfQh02WLxXuvbvC8ku8F57GsI5e0CmUwLz1kq3kD17R1In5816rGvQ5VMk5FEtIiWislTffuDpl/k/PzscdQsv8r9qWq4LRWX6tQYtTxvI3XyrwdyQxChXioOngH3dLgOFjk0all56XRi/wDFQrGQU3Os5t0wJu1GNtNKHdPqYaGYQuRDfbfDf26AGLYSyGS3ZAK4S8XuoAlxGSdYMKwqZKM9XJMtyqXi7HX/CiAZS6d8bSVUz5J36mEMFDTlAFQzxOT1dzLRljjB6+++ejFqka+mXIe6F59mw22OuOw1F4T6lg/9VjL1rLDoI9Xzl1MSYDNHnPQnt3D1EE7PrXjye/3pVpr1Z45hMUdcACc5NVQI0bOdS1WA0wuz73e7/5TNqBPhQXPEFGJNV2zNqWI7QKBd2Gn6AiBko02zuAOXeWIXjV0jNqdKegaE/kJQ6Bfs4aju04lMLkA2T5wBSYPKDGF3RKhFYEa6A1L1LG2yacmsaZ6YPOSAMKNsO+N5dNTfkc5Aqe26uxHpx7ZirvgCwJpWq/lmX1hA7LyabQ34tt5RiJKXSwQ+0KU0V5xg+hZrd4Bn1n4EID+WkQdgLfRNtvil9SPfwy+WQ7PFBWQz6dGWZBLkeJFXZGCfLUjCgGgqXo5TuSu3cugdcTv/HjqnBTEMwzAMwzAMwzAMwzAMw/zf/AFbXiOA6frlMAAAAABJRU5ErkJggg=="
4 | };
--------------------------------------------------------------------------------
/src/pages/index/img/icon_footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_footer.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_footer_link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_footer_link.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_intro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_intro.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_feedback.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_form.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_form.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_nav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_nav.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_search.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_special.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_special.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_widget.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_nav_z-index.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_nav_z-index.png
--------------------------------------------------------------------------------
/src/pages/index/img/icon_tabbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/icon_tabbar.png
--------------------------------------------------------------------------------
/src/pages/index/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/logo.png
--------------------------------------------------------------------------------
/src/pages/index/img/pic_160.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/pic_160.png
--------------------------------------------------------------------------------
/src/pages/index/img/pic_article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/pic_article.png
--------------------------------------------------------------------------------
/src/pages/index/img/vcode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karl-cheung/wxu/3fa317d16d955fb634713eed4685f3f8d09afb40/src/pages/index/img/vcode.jpg
--------------------------------------------------------------------------------
/src/pages/index/index.js:
--------------------------------------------------------------------------------
1 | Page({
2 | data: {
3 | list: [
4 | {
5 | name: 'Toast',
6 | open: true,
7 | url: '/pages/toast/toast'
8 | },
9 | {
10 | name: 'Popup',
11 | open: true,
12 | url: '/pages/popup/popup'
13 | },
14 | {
15 | name: 'Infinite Scroll',
16 | open: true,
17 | url: '/pages/infiniteScroll/infiniteScroll'
18 | },
19 | {
20 | name: 'Authorize',
21 | open: true,
22 | url: '/pages/authorize/authorize'
23 | }
24 | ]
25 | },
26 | skip: function (ev) {
27 | let index = ev.currentTarget.dataset.index
28 | let list = this.data.list
29 | if (list[index].open) {
30 | wx.navigateTo({
31 | url: list[index].url
32 | })
33 | }
34 | }
35 | })
36 |
--------------------------------------------------------------------------------
/src/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | wxu
4 | 微信小程序 WeUI 的轻量级补充,及其他组件(Authorize)。
5 |
6 |
7 |
8 | {{ item.name }}
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | page {
2 | background-color: #F8F8F8;
3 | }
4 |
5 | .main {
6 | padding: 0 15px 40px;
7 | }
8 | .main .item {
9 | margin: 10px 0;
10 | background-color: #FFFFFF;
11 | border-radius: 2px;
12 | overflow: hidden;
13 | padding: 20px;
14 | text-align: center;
15 | }
16 | .main .item:first-child {
17 | margin-top: 0;
18 | }
19 |
--------------------------------------------------------------------------------
/src/pages/infiniteScroll/infiniteScroll.js:
--------------------------------------------------------------------------------
1 | import { InfiniteScroll } from '../../wxu/wxu'
2 |
3 | Page({
4 | data: {
5 | list: []
6 | },
7 | onLoad() {
8 | InfiniteScroll({
9 | name: 'getData',
10 | msg: '玩命加载中...',
11 | doneMsg: '我是有底线的',
12 | spinnerType: 'snake'
13 | })
14 | this.loadMore()
15 | },
16 | getData(done) {
17 | let list = this.data.list
18 | let last = list[list.length - 1] || 0
19 | setTimeout(() => {
20 | for (let i = 1; i <= 10; i++) {
21 | list.push(last + i)
22 | }
23 | this.setData({
24 | list: list
25 | })
26 | if (list[list.length - 1] < 20) {
27 | done()
28 | } else {
29 | done(true)
30 | }
31 | }, 1000)
32 | },
33 | onReachBottom() {
34 | this.loadMore()
35 | }
36 | })
--------------------------------------------------------------------------------
/src/pages/infiniteScroll/infiniteScroll.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "Iinfinite Scroll"
3 | }
--------------------------------------------------------------------------------
/src/pages/infiniteScroll/infiniteScroll.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | InfiniteScroll
6 | 无限滚动指令。
7 |
8 |
9 | {{ item }}
10 |
11 |
12 |
13 |
17 |
--------------------------------------------------------------------------------
/src/pages/infiniteScroll/infiniteScroll.wxss:
--------------------------------------------------------------------------------
1 | .page {
2 | position: absolute;
3 | width: 100%;
4 | height: 100%;
5 | }
6 |
7 | .main {
8 | width: 100%;
9 | min-height: 100%;
10 | }
11 |
12 | .main .sticky {
13 | padding-bottom: 100rpx;
14 | }
15 |
16 | .footer {
17 | position: relative;
18 | margin-top: -100rpx;
19 | }
20 |
21 | .infinite-scroll-item {
22 | height: 100rpx;
23 | line-height: 100rpx;
24 | border-bottom: solid 1rpx #eee;
25 | text-align: center;
26 | }
27 |
28 | .infinite-scroll-item:first-of-type {
29 | border-top: solid 1rpx #eee;
30 | }
--------------------------------------------------------------------------------
/src/pages/popup/popup.js:
--------------------------------------------------------------------------------
1 | import { Popup } from '../../wxu/wxu'
2 |
3 | Page({
4 | Popup() {
5 | Popup({
6 | msg: '不负代码不负卿',
7 | success: () => console.log('PopupTop完成')
8 | })
9 | },
10 | PopupButton() {
11 | Popup({
12 | type: 'button',
13 | msg: '关闭',
14 | buttonType: 'primary',
15 | success: () => console.log('PopupButton完成')
16 | })
17 | }
18 | })
--------------------------------------------------------------------------------
/src/pages/popup/popup.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "Popup"
3 | }
--------------------------------------------------------------------------------
/src/pages/popup/popup.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Popup
7 | 弹出框,可自定义内容。
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/pages/toast/toast.js:
--------------------------------------------------------------------------------
1 | import { Toast } from '../../wxu/wxu'
2 |
3 | Page({
4 | showToast() {
5 | Toast({
6 | msg: '不负代码不负卿',
7 | success: () => console.log('showToast完成')
8 | })
9 | },
10 | showIcon() {
11 | Toast({
12 | icon: 'search',
13 | success: () => console.log('showIcon完成')
14 | })
15 | },
16 | showToastIcon() {
17 | Toast({
18 | msg: '操作成功',
19 | icon: 'success_no_circle',
20 | success: () => console.log('showToastIcon完成')
21 | })
22 | }
23 | })
--------------------------------------------------------------------------------
/src/pages/toast/toast.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "Toast"
3 | }
--------------------------------------------------------------------------------
/src/pages/toast/toast.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Toast
7 | 提示窗,支持文字与 icon 自由组合。
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/wxu/authorize/authorize.js:
--------------------------------------------------------------------------------
1 | import Component from '../component'
2 |
3 | const setAuthorize = (scope, data, cb) => {
4 | if (scope.length === 0) {
5 | wx.getSetting({
6 | success(res) {
7 | if (!res.authSetting) {
8 | return
9 | }
10 | const authSetting = res.authSetting
11 | for (let item of data) {
12 | let bol = false
13 | for (let key in authSetting) {
14 | if (!authSetting[key]) {
15 | wx.openSetting()
16 | return
17 | }
18 | if (key === item) {
19 | bol = true
20 | }
21 | }
22 | if (!bol) {
23 | wx.openSetting()
24 | return
25 | }
26 | }
27 | cb()
28 | }
29 | })
30 | return
31 | }
32 | wx.authorize({
33 | scope: scope[0],
34 | complete() {
35 | setAuthorize(scope.slice(1), data, cb)
36 | }
37 | })
38 | }
39 |
40 | const authorize = (params = {}) => {
41 | const data = Object.assign({}, params)
42 | const component = new Component({
43 | scope: `wxu.authorize`,
44 | data: data,
45 | methods: {
46 | resolve(cb) {
47 | if (!data.scope) {
48 | return
49 | }
50 | setAuthorize(data.scope, data.scope, () => {
51 | typeof cb === `function` && cb()
52 | })
53 | }
54 | }
55 | })
56 | component.resolve(data.success)
57 | }
58 |
59 | export default authorize
--------------------------------------------------------------------------------
/src/wxu/component.js:
--------------------------------------------------------------------------------
1 | class Component {
2 | constructor(params = {}) {
3 | Object.assign(this, { params })
4 | this.init()
5 | }
6 |
7 | init() {
8 | this.page = getCurrentPages()[getCurrentPages().length - 1]
9 | this.setData = this.page.setData.bind(this.page)
10 | this.params.data && this.initData()
11 | this.params.methods && this.initMethods()
12 | }
13 |
14 | isEmptyObject(obj) {
15 | for (let key in obj) {
16 | return false
17 | }
18 | return true
19 | }
20 |
21 | initData() {
22 | const scope = this.params.scope
23 | const data = this.params.data
24 | this._data = {}
25 | if (!this.isEmptyObject(data)) {
26 | for (let key in data) {
27 | if (data.hasOwnProperty(key)) {
28 | if (typeof data[key] === `function`) {
29 | data[key] = data[key].bind(this)
30 | } else {
31 | this._data[key] = data[key]
32 | }
33 | }
34 | }
35 | }
36 | this.page.setData({
37 | [`${scope}`]: this._data
38 | })
39 | }
40 |
41 | initMethods() {
42 | const scope = this.params.scope
43 | const methods = this.params.methods
44 | if (!this.isEmptyObject(methods)) {
45 | for (let key in methods) {
46 | if (methods.hasOwnProperty(key) && typeof methods[key] === `function`) {
47 | this[key] = methods[key] = methods[key].bind(this)
48 | this.page[`${scope}.${key}`] = methods[key]
49 | this.setData({
50 | [`${scope}.${key}`]: `${scope}.${key}`
51 | })
52 | }
53 | }
54 | }
55 | }
56 |
57 | setShow(duration = 300) {
58 | this.setData({
59 | [`${this.params.scope}.wxuShow`]: true
60 | })
61 | setTimeout(() => {
62 | let animation = wx.createAnimation({
63 | duration: duration,
64 | timingFunction: 'linear',
65 | })
66 | animation.opacity(1).step()
67 | this.setData({
68 | [`${this.params.scope}.animation`]: animation.export(),
69 | })
70 | }, duration)
71 | }
72 |
73 | setHide(duration = 300) {
74 | let animation = wx.createAnimation({
75 | duration: duration,
76 | timingFunction: 'linear',
77 | })
78 | animation.opacity(0).step()
79 | this.setData({
80 | [`${this.params.scope}.animation`]: animation.export(),
81 | })
82 | setTimeout(() => {
83 | this.setData({
84 | [`${this.params.scope}.wxuShow`]: false
85 | })
86 | }, duration)
87 | }
88 | }
89 |
90 | export default Component
--------------------------------------------------------------------------------
/src/wxu/infiniteScroll/infiniteScroll.js:
--------------------------------------------------------------------------------
1 | import Component from '../component'
2 |
3 | function infiniteScroll(params = {}) {
4 | const DEFAULT = {
5 | name: '',
6 | msg: '加载中...',
7 | doneMsg: '已无更多',
8 | spinnerType: 'fading-circle',
9 | className: ''
10 | }
11 | const data = Object.assign({}, DEFAULT, params)
12 | const component = new Component({
13 | scope: `wxu.infiniteScroll`,
14 | data: data,
15 | methods: {
16 | done(params) {
17 | if (!params) {
18 | this.setData({
19 | [`${this.params.scope}.infiniteScrollShow`]: false
20 | })
21 | } else {
22 | this.setData({
23 | [`${this.params.scope}.doneEnd`]: true,
24 | [`${this.params.scope}.spinnerType`]: false,
25 | [`${this.params.scope}.msg`]: data.doneMsg
26 | })
27 | }
28 | },
29 | loadMore(...params) {
30 | if (!this.page[data.name] || this.page.data.wxu.infiniteScroll.doneEnd) {
31 | return
32 | }
33 | this.setData({
34 | [`${this.params.scope}.infiniteScrollShow`]: true
35 | })
36 | this.page[data.name](this.done, ...params)
37 | },
38 | setLoadMore() {
39 | this.page.loadMore = this.loadMore
40 | }
41 | }
42 | })
43 | component.setLoadMore()
44 | }
45 |
46 | export default infiniteScroll
--------------------------------------------------------------------------------
/src/wxu/infiniteScroll/infiniteScroll.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/src/wxu/infiniteScroll/infiniteScroll.wxss:
--------------------------------------------------------------------------------
1 | .infinite-scroll-button {
2 | height: 100rpx;
3 | line-height: 100rpx;
4 | font-size: 24rpx;
5 | border: none !important;
6 | }
7 |
8 | button[loading].infinite-scroll-snake::before {
9 | content:" ";
10 | display: inline-block;
11 | height: 26rpx;
12 | width: 26rpx;
13 | border-radius: 100%;
14 | border: 4rpx solid #666;
15 | border-bottom-color: transparent;
16 | vertical-align: middle;
17 | animation: rotate 0.75s linear infinite;
18 | background-size: 0;
19 | }
20 |
21 | @keyframes rotate {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/wxu/popup/popup.js:
--------------------------------------------------------------------------------
1 | import Component from '../component'
2 |
3 | function popup(params = {}) {
4 | const PERPETUAL = -1
5 | const DURATION = 1500
6 | const DEFAULT = {
7 | type: 'default',
8 | msg: '',
9 | className: '',
10 | duration: DURATION,
11 | buttonType: '',
12 | plain: ''
13 | }
14 | const data = Object.assign({}, DEFAULT, params)
15 | if (!data.msg) {
16 | return
17 | }
18 | const component = new Component({
19 | scope: `wxu.popup`,
20 | data: data,
21 | methods: {
22 | show(duration = 300) {
23 | let animation = wx.createAnimation({
24 | duration: duration,
25 | timingFunction: 'ease',
26 | })
27 | this.setData({
28 | [`${this.params.scope}.wxuShow`]: true,
29 | [`${this.params.scope}.animationPopup`]: animation.translateY('-100%').step().export()
30 | })
31 | setTimeout(() => {
32 | this.setData({
33 | [`${this.params.scope}.animationPopup`]: animation.translateY(0).step().export()
34 | })
35 | }, duration)
36 | },
37 | hide(cb, duration = 300) {
38 | if (data.duration !== PERPETUAL) {
39 | this.timer = setTimeout(() => {
40 | let animation = wx.createAnimation({
41 | duration: duration,
42 | timingFunction: 'ease',
43 | })
44 | this.setData({
45 | [`${this.params.scope}.animationPopup`]: animation.translateY('-100%').step().export(),
46 | })
47 | setTimeout(() => {
48 | this.setData({
49 | [`${this.params.scope}.wxuShow`]: false
50 | })
51 | typeof cb === `function` && cb()
52 | }, duration)
53 | }, data.duration)
54 | }
55 | },
56 | showButton(duration = 300) {
57 | this.page.hideButton = this.hideButton
58 | let animation = wx.createAnimation({
59 | duration: duration,
60 | timingFunction: 'linear',
61 | })
62 | this.setData({
63 | [`${this.params.scope}.wxuPopupButtonShow`]: true,
64 | [`${this.params.scope}.animationPopupButton`]: animation.translateX('100%').step().export()
65 | })
66 | setTimeout(() => {
67 | animation.translateX(0).step()
68 | this.setData({
69 | [`${this.params.scope}.animationPopupButton`]: animation.export(),
70 | })
71 | }, duration)
72 | },
73 | hideButton(event, duration = 300) {
74 | let animation = wx.createAnimation()
75 | animation.translateX('100%').step()
76 | this.setData({
77 | [`${this.params.scope}.animationPopupButton`]: animation.export()
78 | })
79 | this.timer = setTimeout(() => {
80 | this.setData({
81 | [`${this.params.scope}.wxuPopupButtonShow`]: false
82 | })
83 | typeof data.success === `function` && data.success()
84 | }, duration)
85 | },
86 | close() {
87 | clearTimeout(this.timer)
88 | if (data.type === 'default') {
89 | this.setHide()
90 | typeof data.success === `function` && data.success()
91 | } else if (data.type === 'button') {
92 | this.hideButton()
93 | }
94 | }
95 | }
96 | })
97 | if (data.type === 'default') {
98 | component.show() || component.hide(data.success)
99 | } else if (data.type === 'button') {
100 | component.showButton()
101 | }
102 | return component
103 | }
104 |
105 | export default popup
--------------------------------------------------------------------------------
/src/wxu/popup/popup.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/wxu/popup/popup.wxss:
--------------------------------------------------------------------------------
1 | .wxu-popup-default {
2 | position: fixed;
3 | top: 0;
4 | left: 0;
5 | width: 100%;
6 | }
7 |
8 | .wxu-popup-text {
9 | width: 100%;
10 | height: 100rpx;
11 | line-height: 100rpx;
12 | text-align: center;
13 | color: white;
14 | background: rgba(0, 0, 0, 0.7);
15 | }
16 |
17 | .wxu-popup-button {
18 | position: absolute;
19 | width: 90%;
20 | top: 50%;
21 | left: 5%;
22 | transform: translateY(-50%);
23 | }
--------------------------------------------------------------------------------
/src/wxu/toast/toast.js:
--------------------------------------------------------------------------------
1 | import Component from '../component'
2 |
3 | function toast(params = {}) {
4 | const PERPETUAL = -1
5 | const DURATION = 1500
6 | const DEFAULT = {
7 | msg: '',
8 | position: '',
9 | duration: DURATION,
10 | className: '',
11 | icon: '',
12 | colol: ''
13 | }
14 | if (params.icon) {
15 | const icon = ['success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel', 'download', 'search', 'clear']
16 | let bol = false
17 | for (let item of icon) {
18 | if (params.icon === item) {
19 | bol = true
20 | }
21 | }
22 | params.icon = bol ? params.icon : ''
23 | }
24 | const data = Object.assign({}, DEFAULT, params)
25 | if (!data.msg && !data.icon) {
26 | return
27 | }
28 | const component = new Component({
29 | scope: `wxu.toast`,
30 | data: data,
31 | methods: {
32 | show() {
33 | this.setShow()
34 | },
35 | hide(cb) {
36 | if (data.duration !== PERPETUAL) {
37 | this.timer = setTimeout(() => {
38 | this.setHide()
39 | typeof cb === `function` && cb()
40 | }, data.duration)
41 | }
42 | },
43 | close() {
44 | clearTimeout(this.timer)
45 | this.setHide()
46 | typeof data.success === `function` && data.success()
47 | }
48 | }
49 | })
50 | if (data.msg || data.icon) {
51 | component.show() || component.hide(data.success)
52 | }
53 | return component
54 | }
55 |
56 | export default toast
--------------------------------------------------------------------------------
/src/wxu/toast/toast.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ msg }}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/wxu/toast/toast.wxss:
--------------------------------------------------------------------------------
1 | .wxu-toast {
2 | position: fixed;
3 | top: 50%;
4 | left: 50%;
5 | z-index: 9999;
6 | transform: translate(-50%, -50%);
7 | text-align: center;
8 | border-radius: 10rpx;
9 | box-sizing: border-box;
10 | background: rgba(0, 0, 0, 0.7);
11 | color: #fff;
12 | opacity: 0;
13 | }
14 |
15 | .wxu-toast-flex {
16 | display: flex;
17 | align-items: center;
18 | justify-content: center;
19 | flex-direction: column;
20 | width: 240rpx;
21 | min-height: 240rpx;
22 | }
23 |
24 | .wxu-toast-top {
25 | top: 25%;
26 | }
27 |
28 | .wxu-toast-bottom {
29 | top: 75%;
30 | }
31 |
32 | .wxu-toast-text {
33 | line-height: 40rpx;
34 | padding: 20rpx;
35 | font-size: 28rpx;
36 | }
37 |
38 | .wxu-toast-text-icon {
39 | padding-bottom: 0;
40 | }
--------------------------------------------------------------------------------
/src/wxu/wxu.js:
--------------------------------------------------------------------------------
1 | import Toast from 'toast/toast'
2 | import Popup from 'popup/popup'
3 | import InfiniteScroll from 'infiniteScroll/infiniteScroll'
4 | import Authorize from 'authorize/authorize'
5 |
6 | export {
7 | Toast,
8 | Popup,
9 | InfiniteScroll,
10 | Authorize
11 | }
--------------------------------------------------------------------------------
/src/wxu/wxu.wxss:
--------------------------------------------------------------------------------
1 | @import 'toast/toast.wxss';
2 | @import 'popup/popup.wxss';
3 | @import 'infiniteScroll/infiniteScroll.wxss';
4 |
5 | .wxu-mask, .wxu-mask-transparent, .wxu-mask-white {
6 | position: fixed;
7 | z-index: 9999;
8 | top: 0;
9 | right: 0;
10 | left: 0;
11 | bottom: 0;
12 | }
13 |
14 | .wxu-mask {
15 | background: rgba(0, 0, 0, 0.6);
16 | }
17 |
18 | .wxu-mask-white {
19 | background: white;
20 | }
--------------------------------------------------------------------------------