stellar-ui-v2 1.40.16 → 1.40.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,9 +10,9 @@
10
10
 
11
11
  ## ✨ 特性
12
12
 
13
- - 🎯 多平台覆盖,支持 微信小程序、支付宝小程序、H5.
14
- - 🚀 40+ 个高质量组件,覆盖移动端主流场景.
15
- - 📖 提供丰富的文档和组件示例.
13
+ - 🎯 多平台覆盖,支持 微信小程序、支付宝小程序、H5.
14
+ - 🚀 40+ 个高质量组件,覆盖移动端主流场景.
15
+ - 📖 提供丰富的文档和组件示例.
16
16
  - 🎨 支持修改 CSS 变量实现主题定制.
17
17
 
18
18
  ## 📱 预览
@@ -75,11 +75,11 @@ npm i stellar-ui-v2 -S
75
75
 
76
76
  ## 周边生态
77
77
 
78
- | 项目 | 描述 |
79
- | --- | --- |
80
- |[StellarUI-Plus](https://github.com/wuhanshuzhiyun/stellar-ui-plus) | 一个基于vue3构建,打造的uni-app组件库 |
81
- |[ste-vue-inset-loader](https://github.com/wuhanshuzhiyun/ste-vue-inset-loader) |常用于小程序需要全局引入组件的场景的包 |
82
- |[ste-helper](https://github.com/wuhanshuzhiyun/stellar-ui-plus/tree/main/plugins/ste-helper) |旨在帮助开发者更加有效率的使用 StellarUI-Plus来开发项目的vscode插件 |
78
+ | 项目 | 描述 |
79
+ | --- | --- |
80
+ |[StellarUI-Plus](https://github.com/wuhanshuzhiyun/stellar-ui-plus) | 一个基于vue3构建,打造的uni-app组件库 |
81
+ |[ste-vue-inset-loader](https://github.com/wuhanshuzhiyun/ste-vue-inset-loader) |常用于小程序需要全局引入组件的场景的包 |
82
+ |[ste-helper](https://github.com/wuhanshuzhiyun/stellar-ui-plus/tree/main/plugins/ste-helper) |旨在帮助开发者更加有效率的使用 StellarUI-Plus来开发项目的vscode插件 |
83
83
  |[ste-cli](https://github.com/wuhanshuzhiyun/ste-cli) |stellar配套的脚手架 |
84
84
 
85
85
  ## 核心团队
@@ -0,0 +1,90 @@
1
+ # AppShare 分享
2
+ - APP分享组件
3
+ - 仅支持APP端
4
+
5
+ ---$
6
+
7
+ ### 代码演示
8
+ #### 基础用法
9
+ ```html
10
+ <template>
11
+ <ste-app-share :open="open" @close="open = false" :data="data" :poster="poster" :miniProgram="miniProgram"></ste-app-share>
12
+ </template>
13
+ <script>
14
+ let num = 0;
15
+ export default {
16
+ data() {
17
+ return {
18
+ open: false,
19
+ poster: {
20
+ qrcode: 'https://image.whzb.com/chain/StellarUI/头像/邻里购.png',
21
+ background: '#ffffff',
22
+ title: '推荐一个宝贝给你,快来看看吧~',
23
+ message: '请及时购买,价格具有时效性',
24
+ },
25
+ data: {
26
+ price: '100.00',
27
+ image: 'https://image.whzb.com/chain/image/1c/1cd2/1cd27514a2516b146e317fa3b538f4f4/6976279890175-1.jpg',
28
+ name: '中百福嘉白干子 200g/份',
29
+ desc: '豆香浓郁|家常百搭',
30
+ },
31
+ miniProgram: {
32
+ id: 'gh_c9b7b9786694',
33
+ path: 'pages/tabbar/tabbar',
34
+ type: 0,
35
+ webUrl: 'https://image.whzb.com/chain/StellarUI/头像/邻里购.png',
36
+ },
37
+ };
38
+ },
39
+ methods: {
40
+ headOpen() {
41
+ if (num % 2 === 0) {
42
+ this.data.image = 'https://image.whzb.com/chain/image/1c/1cd2/1cd27514a2516b146e317fa3b538f4f4/6976279890175-1.jpg';
43
+ } else {
44
+ this.data.image = 'https://image.whzb.com/chain/StellarUI/image/test.jpg';
45
+ }
46
+ num++;
47
+ this.open = true;
48
+ },
49
+ },
50
+ };
51
+ </script>
52
+ ```
53
+
54
+ ---$
55
+ ### API
56
+
57
+ | 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
58
+ | ----- | ----- | --- | ------- | ------| --------|
59
+ | `open` | 打开分享 | `boolean` | `false` | - | - |
60
+ | `viewPoster` | 是否显示海报 | `boolean` | `true` | - | - |
61
+ | `poster` | 海报参数 | `Poster` | `{ background: '#ffffff', title: '推荐一个宝贝给你,快来看看吧~', message: '请及时购买,价格具有时效性', qrcode: '' }` | - | - |
62
+ | `miniProgram` | 小程序参数 | `MiniProgram` | `{ id: '', path: '', type: 0, webUrl: '' }` | - | - |
63
+ | `data` | 分享数据 | `Data` | `{ price: '', image: '', name: '', desc: '' }` | - | - |
64
+
65
+ #### Poster 海报参数
66
+ | 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
67
+ | ----- | ----- | --- | ------- | ------| --------|
68
+ | `background`| 背景色 | `string`| `#ffffff` | - | - |
69
+ | `title` | 顶部标题 | `string`| `推荐一个宝贝给你,快来看看吧~` | - | - |
70
+ | `message` | 底部提示 | `string`| `请及时购买,价格具有时效性` | - | - |
71
+ | `qrcode` | 二维码 | `string`| - | - | - |
72
+
73
+ #### MiniProgram 小程序参数
74
+ | 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
75
+ | ----- | ----- | --- | ------- | ------| --------|
76
+ | `id` | 微信小程序原始id | `string`| - | - | - |
77
+ | `path` | 点击链接进入的页面 | `string`| - | - | - |
78
+ | `type` | 微信小程序版本类型,可取值: 0-正式版; 1-测试版; 2-体验版。 默认值为0 | `string`| `0` | - | - |
79
+ | `webUrl`| 兼容低版本的网页链接 | `string`| - | - | - |
80
+
81
+ #### Data 分享数据
82
+ | 属性名 | 说明 | 类型 | 默认值 | 可选值 | 支持版本 |
83
+ | ----- | ----- | --- | ------- | ------| --------|
84
+ | `price` | 价格 | `string`| - | - | - |
85
+ | `image` | 图片链接 | `string`| - | - | - |
86
+ | `name` | 商品名称 | `string`| - | - | - |
87
+ | `desc` | 商品描述 | `string`| - | - | - |
88
+
89
+ ---$
90
+ {{xuyajun}}
@@ -0,0 +1,5 @@
1
+ {
2
+ "group": "业务组件",
3
+ "title": "AppShare 分享",
4
+ "icon": "https://image.whzb.com/chain/StellarUI/%E7%BB%84%E4%BB%B6%E5%9B%BE%E6%A0%87/countTo.png"
5
+ }
@@ -0,0 +1,85 @@
1
+ async function getImage(src) {
2
+ const image = await uni.getImageInfo({ src: src });
3
+ if (Array.isArray(image)) {
4
+ const [e, img] = image;
5
+ if (e) throw e;
6
+ return img;
7
+ } else if (image.path) {
8
+ return image;
9
+ }
10
+ throw new Error('获取图片失败');
11
+ }
12
+
13
+ /**
14
+ * @param {UniApp.CanvasContext} ctx
15
+ * @param {{background:string;title:string;message:string;qrcode:string}} poster
16
+ * @param {{page: string;image: string;name: string;desc: string;price:string}} data
17
+ */
18
+ export function drawPoster(ctx, poster, data) {
19
+ return new Promise(async (resolve, reject) => {
20
+ const { width, height } = ctx;
21
+ // 清空
22
+ ctx.clearRect(0, 0, width, height);
23
+ // 绘制白色背景
24
+ ctx.setFillStyle(poster.background || '#ffffff');
25
+ ctx.fillRect(0, 0, width, height);
26
+ // 居中绘制标题
27
+ if (poster.title) {
28
+ ctx.setFontSize(14);
29
+ ctx.setFillStyle('#333333');
30
+ ctx.setTextAlign('center');
31
+ ctx.fillText(poster.title, width / 2, 30);
32
+ }
33
+ // 绘制宽高一致的图片
34
+ if (data.image) {
35
+ try {
36
+ const image = await getImage(data.image);
37
+ ctx.drawImage(image.path, 0, 40, width, width);
38
+ } catch (e) {
39
+ console.error(e);
40
+ }
41
+ }
42
+ // 绘制加粗文本name
43
+ if (data.name) {
44
+ ctx.setFontSize(16);
45
+ ctx.setFillStyle('#333333');
46
+ ctx.setTextAlign('left');
47
+ ctx.fillText(data.name, 10, width + 80);
48
+ }
49
+ // 绘制message
50
+ if (data.desc) {
51
+ ctx.setFontSize(14);
52
+ ctx.setFillStyle('#666666');
53
+ ctx.setTextAlign('left');
54
+ ctx.fillText(data.desc, 10, width + 100);
55
+ }
56
+ // 绘制价格
57
+ if (data.price) {
58
+ ctx.setFontSize(20);
59
+ ctx.setFillStyle('#ff0000');
60
+ ctx.setTextAlign('left');
61
+ ctx.fillText(`¥${data.price}`, 10, width + 130);
62
+ }
63
+
64
+ // 绘制文字
65
+ if (poster.message) {
66
+ ctx.setFontSize(12);
67
+ ctx.setFillStyle('#666666');
68
+ ctx.setTextAlign('left');
69
+ ctx.fillText(poster.message, 10, height - 25);
70
+ }
71
+ // 绘制qrcode
72
+ if (poster.qrcode) {
73
+ try {
74
+ const qrcode = await getImage(poster.qrcode);
75
+ ctx.drawImage(qrcode.path, width - 80, width + 80, 70, 70);
76
+ } catch (e) {
77
+ console.error(e);
78
+ }
79
+ }
80
+ // 绘制完成
81
+ ctx.draw(false, () => {
82
+ resolve();
83
+ });
84
+ });
85
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @param {'WXSceneSession' | 'WXSceneTimeline' | 'WXSceneFavorite'} scene
3
+ * @param {{id: string;path: string;type: number;webUrl: string}} miniProgram
4
+ * @param {{page: string;image: string;name: string;desc: string;price:string}} data
5
+ */
6
+ export const share = (scene, miniProgram, data) => {
7
+ return new Promise((resolve, reject) => {
8
+ uni.downloadFile({
9
+ url: data.image,
10
+ success: (res) => {
11
+ console.log('imageUrl===', res.tempFilePath);
12
+ const options = {
13
+ provider: 'weixin',
14
+ scene,
15
+ type: 5,
16
+ miniProgram: Object.assign({ type: 0, webUrl: res.tempFilePath }, miniProgram),
17
+ imageUrl: res.tempFilePath,
18
+ title: data.name,
19
+ summary: `${data.name} #${data.desc}`,
20
+ };
21
+ console.log('options====', options);
22
+ uni.share({
23
+ ...options,
24
+ success: (res) => {
25
+ console.log('分享成功', res);
26
+ resolve(res);
27
+ },
28
+ fail: (err) => {
29
+ console.log('分享失败', err);
30
+ reject(err);
31
+ },
32
+ });
33
+ },
34
+ fail: (err) => {
35
+ console.log('下载失败', err);
36
+ reject(err);
37
+ },
38
+ });
39
+ });
40
+ };
@@ -0,0 +1,270 @@
1
+ <template>
2
+ <!-- 分享弹窗 -->
3
+ <view class="ste-share-root" :class="{ open: dataOpen }">
4
+ <view class="content-box" :style="{ opacity: viewPoster ? 1 : 0 }">
5
+ <view class="loading" v-if="loading"></view>
6
+ <canvas id="content-poster" canvas-id="content-poster" />
7
+ </view>
8
+ <view class="footer-box">
9
+ <view class="footer-head">
10
+ <view class="footer-head-item"></view>
11
+ <view>分享到</view>
12
+ <view class="footer-head-item" @click="close">×</view>
13
+ </view>
14
+ <scroll-view class="footer-scroll-view" scroll-x="true">
15
+ <view class="footer-share-list">
16
+ <view class="footer-item" @click="handShare('WXSceneSession')">
17
+ <image class="footer-icon" src="../../static/weixin.png" mode="widthFix"></image>
18
+ <text>微信好友</text>
19
+ </view>
20
+ <view class="footer-item" @click="handShare('WXSceneTimeline')">
21
+ <image class="footer-icon" src="../../static/wxpyq.png" mode="widthFix"></image>
22
+ <text>朋友圈</text>
23
+ </view>
24
+ <view class="footer-item" @click="handShare('WXSceneFavorite')">
25
+ <image class="footer-icon" src="../../static/shoucang.png" mode="widthFix"></image>
26
+ <text>微信收藏</text>
27
+ </view>
28
+ <view class="footer-item" @click="downloadPoster" v-if="viewPoster">
29
+ <image class="footer-icon" src="../../static/haibao.png" mode="widthFix"></image>
30
+ <text>生成海报</text>
31
+ </view>
32
+ </view>
33
+ </scroll-view>
34
+ </view>
35
+ </view>
36
+ </template>
37
+
38
+ <script>
39
+ import { copyFileToPublicDir, drawPoster } from './draw';
40
+ import { share } from './share';
41
+
42
+ export default {
43
+ name: 'ste-app-share',
44
+ group: '业务组件',
45
+ title: 'AppShare 分享',
46
+ props: {
47
+ open: {
48
+ type: Boolean,
49
+ default: false,
50
+ },
51
+ /** 显示海报 */
52
+ viewPoster: {
53
+ type: Boolean,
54
+ default: true,
55
+ },
56
+ /** 海报参数 */
57
+ poster: {
58
+ type: Object,
59
+ default: () => ({ background: '#ffffff', title: '推荐一个宝贝给你,快来看看吧~', message: '请及时购买,价格具有时效性', qrcode: '' }),
60
+ },
61
+ /** 小程序参数 */
62
+ miniProgram: {
63
+ type: Object,
64
+ default: () => ({ id: '', path: '', type: 0, webUrl: '' }),
65
+ },
66
+ /** 分享数据 */
67
+ data: {
68
+ type: Object,
69
+ default: () => ({ price: '', image: '', name: '', desc: '' }),
70
+ },
71
+ },
72
+ data() {
73
+ return {
74
+ dataOpen: false,
75
+ loading: false,
76
+ ctx: null,
77
+ canvas: null,
78
+ };
79
+ },
80
+ watch: {
81
+ open: {
82
+ handler(val) {
83
+ this.dataOpen = val;
84
+ if (val) {
85
+ this.draw();
86
+ }
87
+ },
88
+ immediate: true,
89
+ },
90
+ },
91
+ mounted() {},
92
+ methods: {
93
+ close() {
94
+ this.dataOpen = false;
95
+ this.$emit('close', false);
96
+ },
97
+ handShare(scene) {
98
+ // #ifndef APP
99
+ uni.showToast({ title: '暂不支持', icon: 'none', duration: 2000 });
100
+ // #endif
101
+ // #ifdef APP
102
+ share(scene, this.miniProgram, this.data);
103
+ // #endif
104
+ },
105
+ draw() {
106
+ if (!this.viewPoster) return;
107
+ this.loading = true;
108
+ if (!this.ctx) {
109
+ this.ctx = uni.createCanvasContext('content-poster', this);
110
+ const query = uni.createSelectorQuery().in(this);
111
+ this.canvas = query
112
+ .select('#content-poster')
113
+ .boundingClientRect((canvas) => {
114
+ this.ctx.width = canvas.width;
115
+ this.ctx.height = canvas.height;
116
+
117
+ drawPoster(this.ctx, this.poster, this.data).finally(() => {
118
+ this.loading = false;
119
+ });
120
+ })
121
+ .exec();
122
+ } else {
123
+ drawPoster(this.ctx, this.poster, this.data).finally(() => {
124
+ this.loading = false;
125
+ });
126
+ }
127
+ },
128
+ downloadPoster() {
129
+ uni.canvasToTempFilePath({
130
+ canvasId: 'content-poster',
131
+ success: ({ tempFilePath }) => {
132
+ uni.saveImageToPhotosAlbum({
133
+ filePath: tempFilePath,
134
+ success: () => {
135
+ uni.showToast({ title: '保存成功', icon: 'success', duration: 2000 });
136
+ },
137
+ fail: (err) => {
138
+ uni.showToast({ title: '保存失败', icon: 'none', duration: 2000 });
139
+ },
140
+ });
141
+ },
142
+ });
143
+ },
144
+ },
145
+ };
146
+ </script>
147
+
148
+ <style lang="scss">
149
+ .ste-share-root {
150
+ position: fixed;
151
+ top: 0;
152
+ left: 0;
153
+ width: 100%;
154
+ height: 100%;
155
+ z-index: 9999;
156
+ background-color: rgba(0, 0, 0, 0.5);
157
+ opacity: 0;
158
+ pointer-events: none;
159
+ transition: all 0.3s;
160
+ &.open {
161
+ opacity: 1;
162
+ pointer-events: auto;
163
+ }
164
+ .content-box {
165
+ position: absolute;
166
+ width: 660rpx;
167
+ height: 960rpx;
168
+ top: 90rpx;
169
+ left: 50%;
170
+ transform: translateX(-50%);
171
+ z-index: 9;
172
+ border-radius: 12px;
173
+ overflow: hidden;
174
+ #content-poster {
175
+ width: 100%;
176
+ height: 100%;
177
+ }
178
+ .loading {
179
+ position: absolute;
180
+ width: 100%;
181
+ height: 100%;
182
+ z-index: 10;
183
+ background-color: #fff;
184
+ &::after {
185
+ content: '加载中...';
186
+ position: absolute;
187
+ width: 100%;
188
+ top: calc(50% + 20px);
189
+ font-size: 12px;
190
+ color: #999;
191
+ text-align: center;
192
+ line-height: 40px;
193
+ }
194
+ &::before {
195
+ content: '';
196
+ position: absolute;
197
+ width: 40px;
198
+ height: 40px;
199
+ top: calc(50%);
200
+ left: calc(50%);
201
+ border-radius: 50%;
202
+ border: 4px solid #f3f3f3;
203
+ border-top-color: #999;
204
+ animation: loading 1s infinite linear;
205
+ }
206
+ }
207
+ }
208
+ .footer-box {
209
+ width: 100%;
210
+ background-color: #fff;
211
+ position: absolute;
212
+ bottom: 0;
213
+ z-index: 10;
214
+ border-radius: 15px 15px 0 0;
215
+ overflow: hidden;
216
+ .footer-head {
217
+ width: 100%;
218
+ height: 44px;
219
+ display: flex;
220
+ justify-content: space-between;
221
+ align-items: center;
222
+ .footer-head-item {
223
+ font-size: 20px;
224
+ width: 44px;
225
+ height: 100%;
226
+ display: flex;
227
+ align-items: center;
228
+ justify-content: center;
229
+ }
230
+ }
231
+ .footer-scroll-view {
232
+ width: 100%;
233
+ height: 75px;
234
+ }
235
+ .footer-share-list {
236
+ white-space: nowrap;
237
+ padding: 0 15px 15px 15px;
238
+ display: flex;
239
+ align-items: flex-start;
240
+
241
+ .footer-item {
242
+ width: 60px;
243
+ height: 60px;
244
+ display: inline-flex;
245
+ flex-direction: column;
246
+ align-items: center;
247
+ justify-content: center;
248
+ font-size: 12px;
249
+ line-height: 30px;
250
+ & + .footer-item {
251
+ margin-left: 10px;
252
+ }
253
+ .footer-icon {
254
+ width: 30px;
255
+ height: 30px;
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
261
+
262
+ @keyframes loading {
263
+ 0% {
264
+ transform: translate(-50%, -50%) rotate(0deg);
265
+ }
266
+ 100% {
267
+ transform: translate(-50%, -50%) rotate(360deg);
268
+ }
269
+ }
270
+ </style>
@@ -1,6 +1,7 @@
1
1
  # AppUpdate App更新
2
2
 
3
- 此组件用于APP更新功能
3
+ - 此组件用于APP更新功能
4
+ - 仅支持APP端
4
5
 
5
6
  ---$
6
7
 
@@ -9,8 +10,8 @@
9
10
  - 属性`clientId`用于设置APP的应用编码
10
11
  - 属性`clientSecret`用于设置APP的应用密钥
11
12
  - 函数`start`用于开始检查更新
12
- - 回调事`cancel`取消更新
13
- - 回调事`complete`取消,成功更新都会执行
13
+ - 回调事件`cancel`取消更新
14
+ - 回调事件`complete`取消,成功更新都会执行
14
15
 
15
16
  ```html
16
17
  <script>
@@ -111,12 +111,12 @@ methods: {
111
111
 
112
112
  #### IndexList Props
113
113
 
114
- | 属性名 | 说明 |类型 |默认值 |可选值 | 支持版本 |
115
- | --- |--- | --- | --- | --- | --- |
116
- | `active` | 当前激活的索引下标,支持sync双向绑定,默认值0 | `Number` | `0` | - | - |
117
- | `height` | 高度,默认值100% | `String`/`Number` | `"100%"` | - | - |
118
- | `sticky` | `title`是否粘性布局,自定义`title`插槽时不生效 | `Boolean` | `true` | - | - |
119
- | `inactiveColor` | 右边锚点状态非激活时的颜色 | `String` | `#666666` | - | - |
114
+ | 属性名 | 说明 |类型 |默认值 |可选值 | 支持版本 |
115
+ | --- |--- | --- | --- | --- | --- |
116
+ | `active` | 当前激活的索引下标,支持sync双向绑定,默认值0 | `Number` | `0` | - | - |
117
+ | `height` | 高度,默认值100% | `String`/`Number` | `"100%"` | - | - |
118
+ | `sticky` | `title`是否粘性布局,自定义`title`插槽时不生效 | `Boolean` | `true` | - | - |
119
+ | `inactiveColor` | 右边锚点状态非激活时的颜色 | `String` | `#666666` | - | - |
120
120
  | `activeColor` | 右边锚点状态激活时的颜色 | `String` | `#0090FF` | - | - |
121
121
 
122
122
  #### IndexList Events