提交 aa085f50 编写于 作者: DCloud_JSON's avatar DCloud_JSON

使用2.0版。当显示分享窗口时,监听返回操作(如:物理返回,全面屏手机侧滑)关闭分享窗口,而不是关闭当前页面。

上级 3a6dd066
......@@ -142,6 +142,7 @@ uni-starter服务端使用[uni-config-center](https://ext.dcloud.net.cn/plugin?i
列举不需要强制登陆即可访问的页面完整路径(支持正则)
#### 配置示例
配置文件:`项目根目录/uni-starter.config.js`
```js
"router": {
"needLogin" : [
......@@ -303,7 +304,7 @@ uni-starter集成了这个功能,你只需直接在`项目根目录/uni-starte
- 而路由跳转方法不仅有`uni.navigateTo`还有`uni.redirectTo`,`uni.reLaunch`,`uni.switchTab`
- 另外我们还希望控制直接跳转至哪种登陆类型
所以在uni-starter框架中我们这样定义:
> uni-starter/common/appInit.js 的第228-280行
uni-starter/common/appInit.js 的第228-280行
```js
const {"router": {needLogin,login} } = uniStarterConfig //需要登录的页面
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
......
## 1.1.18(2021-10-14)
使用2.0版`uni-share`。当显示分享窗口时,监听返回操作(如:物理返回,全面屏手机侧滑)关闭分享窗口,而不是关闭当前页面。
## 1.1.17(2021-10-12)
- 更新文档
- 修复list页面where条件中缺少&符,导致的错误
......
......@@ -214,6 +214,9 @@
"key": ""
}
}
},
"router": {
"base": ""
}
},
"_spaceID": "",
......
{
"id": "uni-starter",
"displayName": "uni-starter",
"version": "1.1.17",
"version": "1.1.18",
"description": "云端一体应用快速开发基本项目模版",
"keywords": [
"login",
......
......@@ -50,14 +50,22 @@
</template>
<script>
import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
import UniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
const uniShare = new UniShare()
const db = uniCloud.database();
const readNewsLog = db.collection('read-news-log')
import {
mapGetters
} from 'vuex';
export default {
export default {
onBackPress({from}) {
if(from=='backbutton'){
this.$nextTick(function(){
uniShare.hide()
})
return uniShare.isShow;
}
},
data() {
return {
// 当前显示 _id
......@@ -196,8 +204,8 @@
title,
excerpt,
avatar
}) );
uniShare({
}) );
uniShare.show({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: this.uniStarterConfig.h5.url + `/#/pages/list/detail?id=${_id}&title=${title}`,
......@@ -264,7 +272,7 @@
],
cancelText: this.$t('common').cancelShare,
}, e => { //callback
// console.log(e);
console.log(e);
})
},
}
......
......@@ -19,8 +19,17 @@
</view>
</template>
<script>
import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
import UniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
const uniShare = new UniShare()
export default {
onBackPress({from}) {
if(from=='backbutton'){
this.$nextTick(function(){
uniShare.hide()
})
return uniShare.isShow;
}
},
onLoad() {
// #ifdef APP-PLUS
this.version = plus.runtime.version
......@@ -30,7 +39,7 @@
uniStarterConfig() {
console.log(getApp());
return getApp().globalData.config
}
}
},
data() {
return {
......@@ -53,7 +62,7 @@
slogan,
logo
} = this.about
uniShare({
uniShare.show({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: download,
......@@ -149,10 +158,10 @@
border-radius: 15px;
}
.tip {
.tip {
text-align: center;
font-size: 24rpx;
margin-top: 10px;
margin-top: 10px;
padding: 10rpx;
}
......@@ -191,4 +200,4 @@
color: #999999;
font-size: 26rpx;
}
</style>
</style>
......@@ -37,10 +37,18 @@
} from 'vuex';
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version';
import uniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
import UniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
const uniShare = new UniShare()
const db = uniCloud.database();
export default {
onBackPress({from}) {
if(from=='backbutton'){
this.$nextTick(function(){
uniShare.hide()
})
return uniShare.isShow;
}
},
data() {
return {
gridList: [{
......@@ -264,7 +272,7 @@
slogan
} = this.appConfig.about
// #ifdef APP-PLUS
uniShare({
uniShare.show({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: this.appConfig.h5.url +
......
......@@ -13,7 +13,7 @@ exports.main = async (event, context) => {
uniID = uniID.createInstance({
context
})
console.log('event : ' + JSON.stringify(event))
console.log('event : ' + JSON.stringify(event))
/*
1.event为客户端 uniCloud.callFunction填写的data的值,这里介绍一下其中的属性
action:表示要执行的任务名称、比如:登陆login、退出登陆 logout等
......
## 2.0.0(2021-10-14)
支持监听返回操作(如:物理返回,全面屏手机侧滑)关闭分享弹窗
## 1.0.6(2021-08-25)
兼容vue3
## 1.0.5(2021-08-05)
......
var nvMask,nvImageMenu;
export default {
show({list,cancelText},callback){
console.log(789789879);
if(!list){
list = [{
"img":"/static/sharemenu/wechatfriend.png",
"text":"图标文字"
}]
}
//以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
var screenWidth = plus.screen.resolutionWidth
//以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
//图标下的按钮文字距离图标5像素,文字大小12像素
//底部取消按钮高度固定为44px
//TODO 未处理横屏和pad,这些情况6个图标应该一排即可
var margin = 20,
iconWidth = 60,
icontextSpace = 5,
textHeight = 12
var left1 = margin / 360 * screenWidth
var iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次
margin = 15
iconWidth = 40
left1 = margin / 360 * screenWidth
iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
}
var left2 = left1 + iconWidth + iconSpace
var left3 = left1 + (iconWidth + iconSpace) * 2
var left4 = left1 + (iconWidth + iconSpace) * 3
var top1 = left1
var top2 = top1 + iconWidth + icontextSpace + textHeight + left1
const TOP = {top1,top2}, LEFT = {left1,left2,left3,left4};
nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层
top: '0px',
left: '0px',
height: '100%',
width: '100%',
backgroundColor: 'rgba(0,0,0,0.2)'
});
nvMask.addEventListener("click", function() { //处理遮罩层点击
nvMask.hide();
nvImageMenu.hide();
})
nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
bottom: '0px',
left: '0px',
height: (iconWidth + textHeight + 2 * margin)*Math.ceil(list.length/4) +44+'px',//'264px',
width: '100%',
backgroundColor: 'rgb(255,255,255)'
});
let myList = []
list.forEach((item,i)=>{
myList.push({
tag: 'img',
src: item.img,
position: {
top: TOP['top'+( parseInt(i/4) +1)],
left: LEFT['left'+(1+i%4)],
width: iconWidth,
height: iconWidth
}
})
myList.push({
tag: 'font',
text: item.text,
textStyles: {
size: textHeight
},
position: {
top: TOP['top'+(parseInt(i/4)+1)] + iconWidth + icontextSpace,
left: LEFT['left'+(1+i%4)],
width: iconWidth,
height: textHeight
}
})
})
//绘制底部图标菜单的内容
nvImageMenu.draw([
{
tag: 'rect',//菜单顶部的分割灰线
color: '#e7e7e7',
position: {
top: '0px',
height: '1px'
}
},
{
tag: 'font',
text: cancelText,//底部取消按钮的文字
textStyles: {
size: '14px'
},
position: {
bottom: '0px',
height: '44px'
}
},
{
tag: 'rect',//底部取消按钮的顶部边线
color: '#e7e7e7',
position: {
bottom: '45px',
height: '1px'
}
},
...myList
])
var nvMask, nvImageMenu;
class NvImageMenu {
constructor(arg) {
this.isShow = false
}
show({
list,
cancelText
}, callback) {
if (!list) {
list = [{
"img": "/static/sharemenu/wechatfriend.png",
"text": "图标文字"
}]
}
//以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
var screenWidth = plus.screen.resolutionWidth
//以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
//图标下的按钮文字距离图标5像素,文字大小12像素
//底部取消按钮高度固定为44px
//TODO 未处理横屏和pad,这些情况6个图标应该一排即可
var margin = 20,
iconWidth = 60,
icontextSpace = 5,
textHeight = 12
var left1 = margin / 360 * screenWidth
var iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次
margin = 15
iconWidth = 40
left1 = margin / 360 * screenWidth
iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
}
var left2 = left1 + iconWidth + iconSpace
var left3 = left1 + (iconWidth + iconSpace) * 2
var left4 = left1 + (iconWidth + iconSpace) * 3
var top1 = left1
var top2 = top1 + iconWidth + icontextSpace + textHeight + left1
const TOP = {
top1,
top2
},
LEFT = {
left1,
left2,
left3,
left4
};
nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层
top: '0px',
left: '0px',
height: '100%',
width: '100%',
backgroundColor: 'rgba(0,0,0,0.2)'
});
nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
bottom: '0px',
left: '0px',
height: (iconWidth + textHeight + 2 * margin) * Math.ceil(list.length / 4) + 44 +
'px', //'264px',
width: '100%',
backgroundColor: 'rgb(255,255,255)'
});
nvMask.addEventListener("click", () => { //处理遮罩层点击
// console.log('处理遮罩层点击');
this.hide()
callback({
event: "clickMask"
})
})
let myList = []
list.forEach((item, i) => {
myList.push({
tag: 'img',
src: item.img,
position: {
top: TOP['top' + (parseInt(i / 4) + 1)],
left: LEFT['left' + (1 + i % 4)],
width: iconWidth,
height: iconWidth
}
})
myList.push({
tag: 'font',
text: item.text,
textStyles: {
size: textHeight
},
position: {
top: TOP['top' + (parseInt(i / 4) + 1)] + iconWidth + icontextSpace,
left: LEFT['left' + (1 + i % 4)],
width: iconWidth,
height: textHeight
}
})
})
//绘制底部图标菜单的内容
nvImageMenu.draw([{
tag: 'rect', //菜单顶部的分割灰线
color: '#e7e7e7',
position: {
top: '0px',
height: '1px'
}
},
{
tag: 'font',
text: cancelText, //底部取消按钮的文字
textStyles: {
size: '14px'
},
position: {
bottom: '0px',
height: '44px'
}
},
{
tag: 'rect', //底部取消按钮的顶部边线
color: '#e7e7e7',
position: {
bottom: '45px',
height: '1px'
}
},
...myList
])
nvMask.show()
nvImageMenu.show() //5+应支持从底部向上弹出的动画
nvImageMenu.addEventListener("click",e=>{ //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑
// console.log("click menu"+JSON.stringify(e));
if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮
nvMask.hide();
nvImageMenu.hide();
} else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {
//屏幕左右边缘5像素及菜单顶部5像素不处理点击
} else { //点击了图标按钮
var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0
var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1
var iCol = -1
if (e.clientX < (left2 - (iconSpace / 2))) {
iCol = 0
} else if (e.clientX < (left3 - (iconSpace / 2))) {
iCol = 1
} else if (e.clientX < (left4 - (iconSpace / 2))) {
iCol = 2
} else {
iCol = 3
}
if (iRow == 0) {
iClickIndex = iCol
} else {
iClickIndex = iCol + 4
}
// console.log("点击按钮的序号: " + iClickIndex);
// if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
// }
callback(iClickIndex)
this.hide()
}
})
/* nvImageMenu.addEventListener("touchstart", function(e) {
if (e.screenY > (plus.screen.resolutionHeight - 44)) {
//TODO 这里可以处理按下背景变灰的效果
}
})
nvImageMenu.addEventListener("touchmove", function(e) {
//TODO 这里可以处理按下背景变灰的效果
if (e.screenY > plus.screen.resolutionHeight - 44) {}
})
nvImageMenu.addEventListener("touchend", function(e) {
//TODO 这里可以处理释放背景恢复的效果
})
*/
},
hide(){
nvMask.hide()
nvImageMenu.hide()
}
}
\ No newline at end of file
nvImageMenu.show()
// 开始动画
/*
plus.nativeObj.View.startAnimation({
type: 'slide-in-bottom',
duration: 300
}, nvImageMenu, {}, function() {
console.log('plus.nativeObj.View.startAnimation动画结束');
// 关闭原生动画
plus.nativeObj.View.clearAnimation();
nvImageMenu.show()
});
*/
this.isShow = true
nvImageMenu.addEventListener("click", e => { //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑
// console.log("click menu"+JSON.stringify(e));
if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮
// callback({event:"clickCancelButton"})
this.hide()
} else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {
//屏幕左右边缘5像素及菜单顶部5像素不处理点击
} else { //点击了图标按钮
var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0
var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1
var iCol = -1
if (e.clientX < (left2 - (iconSpace / 2))) {
iCol = 0
} else if (e.clientX < (left3 - (iconSpace / 2))) {
iCol = 1
} else if (e.clientX < (left4 - (iconSpace / 2))) {
iCol = 2
} else {
iCol = 3
}
if (iRow == 0) {
iClickIndex = iCol
} else {
iClickIndex = iCol + 4
}
// console.log("点击按钮的序号: " + iClickIndex);
// if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
// }
callback({
event: "clickMenu",
index: iClickIndex
})
}
})
/* nvImageMenu.addEventListener("touchstart", function(e) {
if (e.screenY > (plus.screen.resolutionHeight - 44)) {
//TODO 这里可以处理按下背景变灰的效果
}
})
nvImageMenu.addEventListener("touchmove", function(e) {
//TODO 这里可以处理按下背景变灰的效果
if (e.screenY > plus.screen.resolutionHeight - 44) {}
})
nvImageMenu.addEventListener("touchend", function(e) {
//TODO 这里可以处理释放背景恢复的效果
})
*/
}
hide() {
nvMask.hide()
nvImageMenu.hide()
this.isShow = false
}
}
export default NvImageMenu
import uniImageMenu from './uni-image-menu.js';
export default async (param,callback) => {
var menus = []
plus.share.getServices(services => { //只显示有服务的项目
services = services.filter(item=>item.nativeClient)
// console.log("servicesList",services);
let servicesList = services.map(e => e.id)
param.menus.forEach(item => {
if (servicesList.includes(item.share.provider) || typeof(item.share) == 'string') {
menus.push(item)
}
})
// console.log(menus);
uniImageMenu.show({list:menus,cancelText:param.cancelText}, e => {
if (typeof(menus[e]['share']) == 'string') {
switch (menus[e]['share']){
case "copyurl":
copyurl()
break;
case "shareSystem":
shareSystem()
break;
default:
console.error('未知事件名称:'+menus[e]['share']);
break;
import UniImageMenu from './uni-image-menu.js';
class UniShare extends UniImageMenu{
constructor(arg) {
super()
this.isShow = super.isShow
}
async show(param, callback){
var menus = []
plus.share.getServices(services => { //只显示有服务的项目
services = services.filter(item => item.nativeClient)
let servicesList = services.map(e => e.id)
param.menus.forEach(item => {
if (servicesList.includes(item.share.provider) || typeof(item.share) == 'string') {
menus.push(item)
}
} else {
console.log(123456,{
...param.content,
...menus[e].share,
});
uni.share({
...param.content,
...menus[e].share,
success: function(res) {
console.log("success:" + JSON.stringify(res));
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
uni.showModal({
content: JSON.stringify(err),
showCancel: false,
confirmText:"知道了"
});
},
complete(e) {
uniImageMenu.hide()
callback(e)
})
super.show({
list: menus,
cancelText: param.cancelText
}, e => {
callback(e)
if(e.event == 'clickMenu'){
if (typeof(menus[e.index]['share']) == 'string') {
this[menus[e.index]['share']](param)
} else {
uni.share({
...param.content,
...menus[e.index].share,
success: res=> {
console.log("success:" + JSON.stringify(res));
super.hide()
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
uni.showModal({
content: JSON.stringify(err),
showCancel: false,
confirmText: "知道了"
});
}
})
}
})
}
}
})
}, err => {
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
}, err => {
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
function copyurl() {
}
hide(){
super.hide()
}
copyurl(param) {
console.log('copyurl',param);
uni.setClipboardData({
data: param.content.href,
success: function () {
success: ()=>{
console.log('success');
uni.hideToast()//关闭自带的toast
uni.hideToast() //关闭自带的toast
uni.showToast({
title: '复制成功',
icon: 'none'
});
super.hide();
},
fail: (err) => {
uni.showModal({
......@@ -77,20 +73,26 @@ export default async (param,callback) => {
showCancel: false
});
}
});
}
// 使用系统分享发送分享消息
function shareSystem() {
plus.share.sendWithSystem({
type: 'text',
});
}
// 使用系统分享发送分享消息
shareSystem(param) {
console.log('shareSystem',param);
plus.share.sendWithSystem({
type: 'text',
content: param.content.title + param.content.summary || '',
href: param.content.href,
}, function(e) {
href: param.content.href,
}, (e)=> {
console.log('分享成功');
callback(e)
}, function(e) {
console.log('分享失败:' + JSON.stringify(e));
callback(e)
});
}
}
\ No newline at end of file
super.hide()
}, (err)=> {
console.log('分享失败:' + JSON.stringify(err));
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
});
}
}
export default UniShare
\ No newline at end of file
{
"id": "uni-share",
"displayName": "uni-share",
"version": "1.0.6",
"version": "2.0.0",
"description": "底部弹出宫格图标式的分享菜单,可覆盖原生组件。",
"keywords": [
"分享菜单"
......
......@@ -9,7 +9,7 @@
export default {
methods: {
uniShare() {
uniShare({
uniShare.show({
content: { //公共的分享参数配置 类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: 'https://uniapp.dcloud.io/',
......
......@@ -193,6 +193,9 @@
"key" : ""
}
}
},
"router" : {
"base" : ""
}
},
"_spaceID" : "76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册