├── README.md
├── demos
├── demo.png
└── screenshots.jpg
├── package.json
└── pin-prompt
├── assets
├── .DS_Store
├── dots.png
└── step-2.png
├── pin-prompt.js
├── pin-prompt.json
├── pin-prompt.wxml
├── pin-prompt.wxss
└── utils.js
/README.md:
--------------------------------------------------------------------------------
1 | # pin-prompt “添加到我的小程序”提示框
2 |
3 | 微信小程序中,提示用户点击右上角按钮,**添加到我的小程序**。
4 |
5 | * 长条状无干扰方式展示
6 |
7 | * 卡片状带详细引导步骤展示
8 |
9 | * 支持自定义导航栏
10 |
11 | * 支持横竖屏
12 |
13 | * 支持自动提示
14 |
15 |
16 |
17 | ### 扫码体验
18 | 
19 |
20 | ### 示例
21 | 
22 |
23 | ### 安装
24 |
25 | #### 方式一:npm
26 |
27 | ```
28 | npm i --save wx-pin-prompt
29 | ```
30 |
31 | 然后,在微信开发者工具中执行 **「构建 npm 」**
32 |
33 | #### 方式二:直接下载源码
34 |
35 | 直接下载源码,添加到你的项目中
36 |
37 |
38 |
39 | ### 使用
40 |
41 | 在页面 json 文件 `usingComponents` 中添加组件
42 | ``` json
43 | "pin-prompt": "/miniprogram_npm/wx-pin-prompt/pin-prompt"
44 | ```
45 |
46 | 在 wxml 文件中
47 |
48 | ```html
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | ```
58 |
59 |
60 |
61 | > ⚠️注意:通过 npm 安装,可能会遇到在开发者工具报错 “渲染层网络层错误” 。可忽略。在真机上可以正常运行。
62 |
63 |
64 |
65 |
66 |
67 | ### 参数
68 |
69 | | 属性 | 默认值 | 说明 |
70 | | ---------- | -------------------------------- | --------------------------------------------------------- |
71 | | text | 点击「添加小程序」,方便下次访问 | 提示语 |
72 | | type | bar | 【提示框类型】bar:长条型,点击会展示 card 型;card:卡片型(含详细引导步骤) |
73 | | background | \#fff (白色) | 提示框背景色 |
74 | | customNavbar | false | 页面是否使用自定义的导航栏,用于自动定位提示框 |
75 | | auto | false | 如果为 true,则自动在第一次打开时提示,之后不在展示 |
76 | | delay | 0 | 延迟展示的时间(秒)。默认不延迟 |
77 | | duration | 5 | 展示时长(秒)。之后自动隐藏。0 代表不自动隐藏 |
78 | | logo | 无 | 用于详细引导步骤中,展示自家小程序 logo |
79 | | name | 无 | 用于详细引导步骤中,展示自家小程序名称 |
80 | | show | false | 展示提示框 |
81 | | showWhenNotAdded | false | 当未添加时展示 |
82 | | showDetail | false | 展示详细步骤提示框 |
83 |
84 |
--------------------------------------------------------------------------------
/demos/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liudding/wx-pin-prompt/48cc43fe254ff27e551794be0508a40f12a77b27/demos/demo.png
--------------------------------------------------------------------------------
/demos/screenshots.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liudding/wx-pin-prompt/48cc43fe254ff27e551794be0508a40f12a77b27/demos/screenshots.jpg
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wx-pin-prompt",
3 | "version": "1.4.6",
4 | "description": "微信小程序 「添加到我的小程序」提示",
5 | "files": [
6 | "pin-prompt"
7 | ],
8 | "miniprogram": "pin-prompt",
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/liudding/wx-pin-prompt.git"
15 | },
16 | "keywords": [
17 | "小程序",
18 | "mini-program",
19 | "miniprogram",
20 | "wechat",
21 | "component",
22 | "pin-prompt"
23 | ],
24 | "author": "liuding",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/liudding/wx-pin-prompt/issues"
28 | },
29 | "homepage": "https://github.com/liudding/wx-pin-prompt"
30 | }
--------------------------------------------------------------------------------
/pin-prompt/assets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liudding/wx-pin-prompt/48cc43fe254ff27e551794be0508a40f12a77b27/pin-prompt/assets/.DS_Store
--------------------------------------------------------------------------------
/pin-prompt/assets/dots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liudding/wx-pin-prompt/48cc43fe254ff27e551794be0508a40f12a77b27/pin-prompt/assets/dots.png
--------------------------------------------------------------------------------
/pin-prompt/assets/step-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liudding/wx-pin-prompt/48cc43fe254ff27e551794be0508a40f12a77b27/pin-prompt/assets/step-2.png
--------------------------------------------------------------------------------
/pin-prompt/pin-prompt.js:
--------------------------------------------------------------------------------
1 | const STORAGE_KEY = 'PIN_PROMPT_DATE';
2 |
3 | import { checkIsAdded } from './utils'
4 |
5 | Component({
6 | properties: {
7 | text: {
8 | type: String,
9 | value: '点击「添加小程序」,方便下次访问'
10 | },
11 |
12 | /**
13 | * 展示类型
14 | */
15 | type: {
16 | type: String,
17 | value: 'bar' // bar, card
18 | },
19 |
20 | show: {
21 | type: Boolean,
22 | value: false,
23 | observer: function (val) {
24 | val && this.show();
25 | !val && this.close()
26 | }
27 | },
28 |
29 | showWhenNotAdded: {
30 | type: Boolean,
31 | value: false,
32 | },
33 |
34 | showDetail: {
35 | type: Boolean,
36 | value: false,
37 | observer: function (val) {
38 | val && this.showDetail();
39 | }
40 | },
41 |
42 | auto: {
43 | type: Boolean,
44 | value: false,
45 | },
46 |
47 | background: {
48 | type: String,
49 | value: '#fff'
50 | },
51 |
52 | color: {
53 | type: String,
54 | value: '#000'
55 | },
56 |
57 | /**
58 | * 页面使用了自定义导航栏
59 | */
60 | customNavbar: {
61 | type: Boolean,
62 | value: false,
63 | },
64 |
65 | logo: {
66 | type: String,
67 | },
68 | name: {
69 | type: String
70 | },
71 |
72 | /**
73 | * 延迟展示
74 | */
75 | delay: {
76 | type: Number,
77 | value: 0 // seconds
78 | },
79 |
80 | /**
81 | * 展示时长
82 | */
83 | duration: {
84 | type: Number,
85 | value: 5 // seconds
86 | },
87 |
88 | backdrop: {
89 | type: Boolean,
90 | value: false
91 | }
92 | },
93 |
94 | data: {
95 | showHint: false,
96 | showBackdrop: false,
97 |
98 | position: {
99 | top: 0,
100 | right: 0
101 | },
102 |
103 | timer: null
104 | },
105 |
106 | lifetimes: {
107 | attached: async function () {
108 | await this._attached();
109 | },
110 | },
111 |
112 | pageLifetimes: {
113 | resize: function (size) {
114 | // 页面尺寸变化
115 | this._updatePosition()
116 | }
117 | },
118 |
119 | attached: function () {
120 | this._attached();
121 | },
122 |
123 | methods: {
124 | onTapBackdrop() {
125 | this.close()
126 | },
127 |
128 | onTapClose() {
129 | this.close()
130 | },
131 |
132 | show() {
133 | this.setData({
134 | show: true,
135 | showHint: true,
136 | showBackdrop: this.data.backdrop || this.data.type === 'card'
137 | });
138 |
139 | if (this.data.type === 'bar' && this.data.duration > 0) {
140 | this.data.timer = setTimeout(() => {
141 | if (this.data.type === 'bar') {
142 | this.close();
143 | }
144 | }, this.data.duration * 1000)
145 | }
146 |
147 | this.triggerEvent('show')
148 | },
149 |
150 | close() {
151 | this.setData({
152 | show: false,
153 | showHint: false,
154 | showBackdrop: false
155 | });
156 |
157 | wx.setStorageSync(STORAGE_KEY, Date.now())
158 |
159 | this.triggerEvent('close')
160 | },
161 |
162 | showDetail: function () {
163 | this.data.timer && clearTimeout(this.data.timer)
164 |
165 | this.setData({
166 | show: true,
167 | showHint: true,
168 | showBackdrop: true,
169 | type: 'card'
170 | });
171 |
172 | this.triggerEvent('showDetail')
173 | },
174 |
175 | async shouldShow() {
176 | if (this.data.showWhenNotAdded) {
177 | const isAdded = await checkIsAdded()
178 | if (isAdded !== null) {
179 | return !isAdded
180 | }
181 | }
182 |
183 | if (this.data.auto) {
184 | const alreadyShown = wx.getStorageSync(STORAGE_KEY)
185 |
186 | return !alreadyShown;
187 | }
188 |
189 | return this.data.show;
190 | },
191 |
192 | async _attached() {
193 | this._updatePosition()
194 |
195 | if (await this.shouldShow()) {
196 | setTimeout(() => {
197 | this.show();
198 | }, this.data.delay * 1000)
199 | }
200 | },
201 |
202 | _updatePosition() {
203 | const isSupport = !!wx.getMenuButtonBoundingClientRect
204 | const rect = isSupport ? wx.getMenuButtonBoundingClientRect() : {}
205 |
206 | wx.getSystemInfo({
207 | success: (res) => {
208 | this.setData({
209 | position: {
210 | top: this.data.customNavbar ? rect.bottom : 0,
211 | right: res.screenWidth - rect.left - rect.width * 3 / 4
212 | }
213 | })
214 | }
215 | })
216 |
217 | }
218 | }
219 | })
--------------------------------------------------------------------------------
/pin-prompt/pin-prompt.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/pin-prompt/pin-prompt.wxml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | {{text}}
7 |
8 |
9 |
10 |
11 |
12 |
13 | 1
14 |
15 | 点击右上角
16 |
17 |
18 |
19 |
20 |
21 | 2
22 |
23 | 选择「添加到我的小程序」
24 |
26 |
27 |
28 |
29 | 3
30 |
31 | 微信首页下拉,快速进入小程序
32 |
33 | 我的小程序
34 |
35 |
36 | {{name}}
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 我知道了
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/pin-prompt/pin-prompt.wxss:
--------------------------------------------------------------------------------
1 | .container {
2 | position: fixed;
3 | top: 0px;
4 | right: 0;
5 | z-index: 10001;
6 |
7 | width: 600rpx;
8 |
9 | display: flex;
10 | flex-direction: column;
11 | justify-content: flex-end;
12 | align-items: flex-end;
13 | }
14 |
15 |
16 | .arrow {
17 | width: 0;
18 | height: 0;
19 | margin-right: 30px;
20 | border-width: 10px;
21 | border-style: solid;
22 | border-color: transparent transparent #fff transparent;
23 | }
24 |
25 | .body {
26 | min-height: 40px;
27 | }
28 |
29 | .bar {
30 | background: #fff;
31 | padding: 4px 8px;
32 | border-radius: 8px;
33 | }
34 |
35 | .bar .text {
36 | color: rgb(0, 0, 0);
37 | font-size: 12px;
38 | font-weight: 400;
39 | }
40 |
41 | .card {
42 | background-color: #fff;
43 | box-shadow: 0 10rpx 20rpx -10rpx #fff;
44 | border-radius: 16px;
45 | min-width: 200rpx;
46 | padding: 24px;
47 | display: flex;
48 | flex-direction: column;
49 | box-sizing: border-box;
50 | }
51 |
52 | .card .step {
53 | width: 100%;
54 | display: flex;
55 | flex-direction: row;
56 | justify-items: start;
57 | align-items: flex-start;
58 | padding: 8px 0;
59 | font-size: 14px;
60 | }
61 |
62 | .card .label {
63 | background: rgb(241, 130, 130);
64 | width: 20px;
65 | min-width: 20px;
66 | height: 20px;
67 | min-height: 20px;
68 | border-radius: 100%;
69 | text-align: center;
70 | line-height: 20px;
71 | font-size: 12px;
72 | margin-right: 8px;
73 | }
74 |
75 | .card .step-1__desc {
76 | display: flex;
77 | }
78 |
79 | .card .image {
80 | margin-top: 4px;
81 | border-radius: 8px;
82 | }
83 |
84 | .quick-entry {
85 | margin-top: 4px;
86 | position: relative;
87 | height: 70px;
88 | background: rgb(68, 65, 88);
89 | border-radius: 8px;
90 | color: white;
91 | padding: 8px 16px;
92 | }
93 |
94 | .quick-entry .quick-entry-title {
95 | color: gray;
96 | font-size: 10px;
97 | }
98 |
99 | .quick-entry .mini-app {
100 | width: 45px;
101 | display: flex;
102 | flex-direction: column;
103 | align-items: center;
104 | }
105 |
106 | .quick-entry .mini-app .logo {
107 | width: 30px;
108 | height: 30px;
109 | margin-top: 8px;
110 | border-radius: 100%;
111 | }
112 |
113 | .quick-entry .mini-app .name {
114 | margin-top: 4px;
115 | text-align: center;
116 | color: white;
117 | font-size: 8px;
118 | }
119 |
120 | .tail {
121 | width: 100%;
122 | text-align: center;
123 | padding: 8px 0;
124 |
125 | display: flex;
126 | flex-direction: column;
127 | align-items: center;
128 | }
129 |
130 | .got-it {
131 | width: 80px;
132 | background: transparent;
133 | border-radius: 1000px;
134 | border: 1px solid white;
135 | color: white;
136 | }
137 |
138 | .backdrop {
139 | position: fixed;
140 | top: 0;
141 | right: 0;
142 | bottom: 0;
143 | left: 0;
144 | z-index: 10000;
145 | background: rgba(0, 0, 0, 0.5);
146 | }
--------------------------------------------------------------------------------
/pin-prompt/utils.js:
--------------------------------------------------------------------------------
1 |
2 | export async function checkIsAdded() {
3 | return new Promise((resolve, reject) => {
4 | if (!wx.checkIsAddedToMyMiniProgram) {
5 | resolve(null)
6 | }
7 | wx.checkIsAddedToMyMiniProgram({
8 | success: (res) => {
9 | resolve(res.added)
10 | },
11 | fail: (err) => {
12 | reject(err)
13 | }
14 | })
15 | })
16 | }
--------------------------------------------------------------------------------