default
This commit is contained in:
parent
1013829393
commit
6604902a2b
|
|
@ -0,0 +1,138 @@
|
|||
<script>
|
||||
import {
|
||||
mapMutations
|
||||
} from 'vuex'
|
||||
import {
|
||||
version
|
||||
} from './package.json'
|
||||
// #ifdef APP
|
||||
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
// #ifdef H5
|
||||
console.log(
|
||||
`%c hello uniapp %c v${version} `,
|
||||
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
|
||||
'background:#007aff ;padding: 1px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;'
|
||||
)
|
||||
// #endif
|
||||
// 线上示例使用
|
||||
// console.log('%c uni-app官方团队诚邀优秀前 端工程师加盟,一起打造更卓越的uni-app & uniCloud,欢迎投递简历到 hr2013@dcloud.io', 'color: red');
|
||||
console.log('App Launch');
|
||||
// #ifdef APP-PLUS
|
||||
// App平台检测升级,服务端代码是通过uniCloud的云函数实现的,详情可参考:https://ext.dcloud.net.cn/plugin?id=4542
|
||||
if (plus.runtime.appid !== 'HBuilder') { // 真机运行不需要检查更新,真机运行时appid固定为'HBuilder',这是调试基座的appid
|
||||
checkUpdate()
|
||||
}
|
||||
|
||||
// 一键登录预登陆,可以显著提高登录速度
|
||||
uni.preLogin({
|
||||
provider: 'univerify',
|
||||
success: (res) => {
|
||||
// 成功
|
||||
this.setUniverifyErrorMsg();
|
||||
console.log("preLogin success: ", res);
|
||||
},
|
||||
fail: (res) => {
|
||||
this.setUniverifyLogin(false);
|
||||
this.setUniverifyErrorMsg(res.errMsg);
|
||||
// 失败
|
||||
console.log("preLogin fail res: ", res);
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
},
|
||||
globalData: {
|
||||
test: ''
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setUniverifyErrorMsg', 'setUniverifyLogin'])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/uni_modules/uni-scss/index.scss';
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
|
||||
@import './common/uni.css';
|
||||
@import '@/static/customicons.css';
|
||||
/* H5 兼容 pc 所需 */
|
||||
/* #ifdef H5 */
|
||||
@media screen and (min-width: 768px) {
|
||||
body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
/* 顶栏通栏样式 */
|
||||
/* .uni-top-window {
|
||||
left: 0;
|
||||
right: 0;
|
||||
} */
|
||||
|
||||
uni-page-body {
|
||||
background-color: #F5F5F5 !important;
|
||||
min-height: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.uni-top-window uni-tabbar .uni-tabbar {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.uni-app--showleftwindow .hideOnPc {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* 以下样式用于 hello uni-app 演示所需 */
|
||||
page {
|
||||
background-color: #efeff4;
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
/* line-height: 1.8; */
|
||||
}
|
||||
|
||||
.fix-pc-padding {
|
||||
padding: 0 50px;
|
||||
}
|
||||
|
||||
.uni-header-logo {
|
||||
padding: 30rpx;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.uni-header-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.uni-hello-text {
|
||||
color: #7A7E83;
|
||||
}
|
||||
|
||||
.uni-hello-addfile {
|
||||
text-align: center;
|
||||
line-height: 300rpx;
|
||||
background: #FFF;
|
||||
padding: 50rpx;
|
||||
margin-top: 10px;
|
||||
font-size: 38rpx;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
/* #endif*/
|
||||
</style>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 DCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
131
README.md
131
README.md
|
|
@ -1,2 +1,129 @@
|
|||
# uniapp-course
|
||||
|
||||
# hello-uniapp
|
||||
|
||||
`uni-app`框架示例,一套代码,同时发行到iOS、Android、H5、小程序等多个平台,请使用手机在下方扫码快速体验`uni-app`的强大功能。[官方文档](https://uniapp.dcloud.net.cn/)
|
||||
|
||||
## 快速上手
|
||||
hello-uniapp 示例工程可以通过两种方式创建, 一种是 HBuilderX, 配套 IDE,集成开发;另一种是 CLI 创建;推荐前者。
|
||||
### 通过 HBuilderX 可视化界面创建(推荐)
|
||||
|
||||
可视化的方式比较简单,HBuilderX内置相关环境,开箱即用,无需配置nodejs。
|
||||
|
||||
开始之前,开发者需先下载安装如下工具:
|
||||
|
||||
- HBuilderX:[官方IDE下载地址](https://www.dcloud.io/hbuilderx.html)
|
||||
|
||||
HBuilderX是通用的前端开发工具,但为`uni-app`做了特别强化,请下载App开发版。
|
||||
|
||||
由于截图在 github 不便浏览,参见官方文档 [HBuilderX 可视化界面创建](https://uniapp.dcloud.net.cn/quickstart?id=_1-%e9%80%9a%e8%bf%87-hbuilderx-%e5%8f%af%e8%a7%86%e5%8c%96%e7%95%8c%e9%9d%a2)
|
||||
|
||||
### 通过 vue-cli 创建
|
||||
|
||||
```
|
||||
npm install -g @vue/cli
|
||||
```
|
||||
|
||||
#### 创建uni-app
|
||||
|
||||
**使用正式版**(对应HBuilderX最新正式版)
|
||||
|
||||
```
|
||||
vue create -p dcloudio/uni-preset-vue my-project
|
||||
```
|
||||
|
||||
**使用alpha版**(对应HBuilderX最新alpha版)
|
||||
|
||||
```
|
||||
vue create -p dcloudio/uni-preset-vue#alpha my-alpha-project
|
||||
```
|
||||
|
||||
此时,会提示选择项目模板,选择 `hello uni-app` 项目模板,如下所示:
|
||||
|
||||
<div>
|
||||
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/h5-cli-01.png" width="300">
|
||||
</div>
|
||||
|
||||
创建好后,进入项目目录
|
||||
```
|
||||
cd my-project
|
||||
```
|
||||
|
||||
执行该命令运行到 h5 端
|
||||
```
|
||||
npm run dev:h5
|
||||
```
|
||||
|
||||
欢迎提 issues,推荐到[官方社区](https://ask.dcloud.net.cn/explore/)提问。
|
||||
|
||||
## 扫码体验
|
||||
|
||||
<div class="quick">
|
||||
<p>一套代码编到10个平台,这不是梦想。眼见为实,扫描10个二维码,亲自体验最全面的跨平台效果!</p>
|
||||
<div style="display: flex;">
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://web-assets.dcloud.net.cn/unidoc/zh/uni-android.png" width="160" />
|
||||
</div>
|
||||
<b>Android版</b>
|
||||
</a>
|
||||
<a href="https://itunes.apple.com/cn/app/hello-uni-app/id1417078253?mt=8" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://web-assets.dcloud.net.cn/unidoc/zh/uni-h5.png" width="160" />
|
||||
</div>
|
||||
<b>iOS版</b>
|
||||
</a>
|
||||
<a href="https://hellouniapp.dcloud.net.cn/" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/uni-h5-hosting-qr.png" width="160" />
|
||||
</div>
|
||||
<b>H5版</b>
|
||||
</a>
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box"><img src="//img.cdn.aliyun.dcloud.net.cn/guide/uniapp/gh_33446d7f7a26_430.jpg" width="160" /></div>
|
||||
<b>微信小程序版</b>
|
||||
</a>
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box"><img src="https://web-assets.dcloud.net.cn/unidoc/zh/alipay1.png" width="160" /></div>
|
||||
<b>支付宝小程序版</b>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex-img-group-view" style="margin-top: 20px;">
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box"><img src="https://web-assets.dcloud.net.cn/unidoc/zh/baidu-uniapp.png" width="160" /></div>
|
||||
<b>百度小程序版</b>
|
||||
</a>
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/mp-toutiao.png" width="160" />
|
||||
</div>
|
||||
<b>字节跳动小程序版</b>
|
||||
</a>
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/hello-uni-qq.png" width="160" />
|
||||
</div>
|
||||
<b>QQ小程序版</b>
|
||||
</a>
|
||||
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/hello-uni-qa-union.png" width="160" />
|
||||
</div>
|
||||
<b>快应用</b>
|
||||
</a>
|
||||
<a href="https://so.mp.360.cn/mp.html?appid=qh4j181qqtru354st6" target="_blank" class="clear-style barcode-view">
|
||||
<div class="barcode-img-box">
|
||||
<img src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/hello-uni-mp-360-qr.png" width="160" />
|
||||
</div>
|
||||
<b>360小程序</b>
|
||||
</a>
|
||||
</div>
|
||||
<p>
|
||||
<em>注:某些平台不能提交简单demo,故补充了一些其他功能;hello uni-app示例代码可从[github](https://github.com/dcloudio/hello-uniapp)获取</em></br>
|
||||
<em>快应用仅支持 vivo 、oppo、华为</em></br>
|
||||
<em>360小程序仅 windows平台支持,需要在360浏览器中打开</em></br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
`uni-app`官网文档详见[https://uniapp.dcloud.io](https://uniapp.dcloud.io)
|
||||
|
||||
更多uni-app的模板、示例详见[插件市场](https://ext.dcloud.net.cn/)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
## 3.4.9(2025-06-25)
|
||||
- 适配 鸿蒙元服务
|
||||
- 更新 uni-swipe-action
|
||||
- 新增 crypto 示例和测试例
|
||||
- 新增 css 变量示例和测试例
|
||||
- 新增 web-view点击位置偏移测试例
|
||||
## 3.4.8(2025-04-10)
|
||||
- 调整 renderjs示例的平台兼容性
|
||||
## 3.4.7(2025-01-08)
|
||||
- 新增 uni-calendar显示
|
||||
- 更新 uniui 组件
|
||||
- 更新uni-id至3.3.33版本
|
||||
- 替换示例中失效图片资源地址
|
||||
## 3.4.6(2023-06-30)
|
||||
- 更新 video组件引用的视频链接
|
||||
## 3.4.4(2022-07-25)
|
||||
- 新增 同步 uni-ui@1.4.20
|
||||
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
|
||||
- uni-section 新增组件
|
||||
## 3.4.3(2022-07-14)
|
||||
- 修复 HBuilderX 拉取 hello uni-app 项目直接运行提示无服务空间关联的bug
|
||||
## 3.4.2(2022-07-06)
|
||||
- 新增 同步 uni-ui@1.4.18
|
||||
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
|
||||
- uni-forms 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
|
||||
- uni-forms 新增 更多表单示例
|
||||
- uni-forms 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
|
||||
- uni-forms 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
|
||||
- uni-forms 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
|
||||
- uni-forms 新增 子表单的 setRules 方法,配合自定义校验函数使用
|
||||
- uni-forms 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
|
||||
- uni-forms 修复 由 1.4.0 引发的 label 插槽不生效的bug
|
||||
- uni-forms 修复 子组件找不到 setValue 报错的bug
|
||||
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中报错的bug
|
||||
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
|
||||
- uni-forms 修复 表单校验顺序无序问题
|
||||
- uni-forms 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
|
||||
- uni-forms 优化 动态表单校验方式,废弃拼接name的方式
|
||||
- uni-breadcrumb 修复 微信小程序 separator 不显示问题
|
||||
- uni-data-checkbox 优化 在 uni-forms 中的依赖注入方式
|
||||
- uni-data-picker 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
|
||||
- uni-data-picker 优化 显示样式
|
||||
- uni-data-select 优化 显示样式
|
||||
- uni-datetime-picker 修复 日历顶部年月及底部确认未国际化 bug
|
||||
- uni-datetime-picker 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
|
||||
- uni-easyinput 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
|
||||
- uni-easyinput 新增 clear 事件,点击右侧叉号图标触发
|
||||
- uni-easyinput 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
|
||||
- uni-easyinput 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
|
||||
- uni-easyinput 优化 clearable 显示策略
|
||||
- uni-file-picker 修复 在uni-forms下样式不生效的bug
|
||||
- uni-nav-bar 修复 组件示例中插槽用法无法显示内容的bug
|
||||
- uni-swipe-action 修复 vue3 下使用组件不能正常运行的Bug
|
||||
- uni-swipe-action 修复 h5端点击click触发两次的Bug
|
||||
- uni-table 修复 微信小程序存在无使用组件的问题
|
||||
## 3.4.1(2022-06-30)
|
||||
- 新增 支持 ios 安全区
|
||||
## 3.3.8(2022-05-08)
|
||||
- 新增 同步 uni-ui@1.4.15
|
||||
- uni-data-picker 修复 字节小程序 本地数据无法选择下一级的Bug
|
||||
- uni-data-select 新增 记住上次的选项(仅 collection 存在时有效)
|
||||
- uni-search-bar 修复 vue3 input 事件不生效的bug
|
||||
- uni-search-bar 修复 多余代码导致的bug
|
||||
- uni-tooltip 更新 text 属性变更为 content
|
||||
- uni-tooltip 更新 移除 width 属性
|
||||
- uni-tooltip 修复 组件根 text 嵌套组件 warning
|
||||
## 3.3.7(2022-04-06)
|
||||
- 新增 更新扩展组件 uni-nav-bar、uni-list 的展示页面
|
||||
## 3.3.6(2022-03-31)
|
||||
- 更新 uni-ui 组件及示例
|
||||
## 3.3.5(2022-03-30)
|
||||
- 修复 插槽兼容 vue3, slot -> v-slot
|
||||
- 新增 更新 uni-ui
|
||||
## 3.3.4(2022-02-25)
|
||||
- 修复 编译到 App 平台的控制台报错
|
||||
## 3.3.3(2022-02-23)
|
||||
- 修复 模板城市选择 vue3 报错的bug
|
||||
- 修复 删除 map.nvue 中多余的 enableOverlooking 变量
|
||||
- 修复 swipe-dot.nvue 中条件编译媒体查询
|
||||
## 3.3.2(2022-01-26)
|
||||
- 修复 默认运行到 vue2
|
||||
## 3.3.1(2022-01-26)
|
||||
- 新增 同步 uni-ui@1.4.11
|
||||
- uni-collapse 修复 微信小程序resize后组件收起的bug
|
||||
- uni-countdown 修复 在微信小程序中样式不生效的bug
|
||||
- uni-countdown 新增 update 方法 ,在动态更新时间后,刷新组件
|
||||
- uni-load-more 新增 showText属性 ,是否显示文本
|
||||
- uni-load-more 修复 nvue 平台下不显示文本的bug
|
||||
- uni-load-more 修复 微信小程序平台样式选择器报警告的问题
|
||||
- uni-nav-bar 修复 在vue下,标题不垂直居中的bug
|
||||
- uni-nav-bar 修复 height 属性类型错误
|
||||
- uni-nav-bar 新增 height 属性,可修改组件高度
|
||||
- uni-nav-bar 新增 dark 属性可可开启暗黑模式
|
||||
- uni-nav-bar 优化 标题字数过多显示省略号
|
||||
- uni-nav-bar 优化 插槽,插入内容可完全覆盖
|
||||
- uni-popup 修复 isMaskClick 失效的bug
|
||||
- uni-popup 新增 cancelText \ confirmText 属性 ,可自定义文本
|
||||
- uni-popup 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
|
||||
- uni-popup 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
|
||||
## 3.3.0(2022-01-04)
|
||||
- 修复 开发时在 vue3 下由 pc 端切换到手机端,不能返回上一级页面的 bug
|
||||
- 优化 去掉 pc 端 topwindow 右上角用于演示的 url 导航
|
||||
## 3.2.12(2021-12-20)
|
||||
- 新增 适配京东小程序
|
||||
## 3.2.11(2021-12-07)
|
||||
- 修复 uni-ui 在 hello-uniapp 中丢失图标、ui 受到公共样式影响等问题
|
||||
- 修复 微信登录取值报错的问题
|
||||
## 3.2.10(2021-11-30)
|
||||
- 修复 map 组件示例不显示的 bug
|
||||
## 3.2.9(2021-11-19)
|
||||
- 新增 uni-ui 以 uni_modules 方式引入,方便开发者从 hello-uniapp 中 copy 组件及示例
|
||||
- 优化 uni-ui 示例页面,完善组件示例
|
||||
## 3.2.8(2021-11-10)
|
||||
- 新增 适配飞书平台(lark)
|
||||
## 3.2.7(2021-10-26)
|
||||
- 修复 uni-popup 示例的 button 文字在 iPhone 5 上换行的 bug
|
||||
- 修复 uni-table 示例,页面顶部距离不对的 bug
|
||||
- 修复 GlobalData示例,在vue3是无效的 bug
|
||||
- 优化 删除无用的 project.swan.json 文件
|
||||
## 3.2.6(2021-10-08)
|
||||
- 由于体验问题,暂时撤销 uni-ui 以 uni_modules 方式引入的修改
|
||||
|
||||
## 3.2.4(2021-09-07)
|
||||
- 修复 vue3 在 H5 编译报错的 bug
|
||||
- 新增 同步 uni-ui
|
||||
- 新增 uni-ui 组件支持国际化 i18n
|
||||
- uni-data-checkbox 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
|
||||
- uni-datetime-picker 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
|
||||
- uni-datetime-picker 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
|
||||
- uni-datetime-picker 优化 调整字号大小,美化日历界面
|
||||
- uni-datetime-picker 修复 因国际化导致的 placeholder 失效的 bug
|
||||
- uni-file-picker 修复 return-type="object" 时且存在v-model时,无法删除文件的Bug
|
||||
- uni-file-picker 新增 参数中返回 fileID 字段
|
||||
- uni-file-picker 修复 腾讯云传入fileID 不能回显的bug
|
||||
- uni-file-picker 修复 选择图片后,不能放大的问题
|
||||
- uni-link 修复 在 nvue 下不显示的 bug
|
||||
- uni-list 修复 在vue3中to属性在发行应用的时候报错的bug
|
||||
- uni-search-bar 修复 value 属性与 modelValue 属性不兼容的Bug
|
||||
- uni-swipe-action 优化 close-all 方法
|
||||
- uni-collapse 优化 show-arrow 属性默认为true
|
||||
- uni-collapse 新增 show-arrow 属性,控制是否显示右侧箭头
|
||||
- uni-data-checkbox 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
|
||||
- uni-easyinput 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
|
||||
- uni-file-picker 修复 由于 0.2.11 版本引起的不能回显图片的Bug
|
||||
- uni-file-picker 新增 clearFiles(index) 方法,可以手动删除指定文件
|
||||
- uni-file-picker 修复 v-model 值设为 null 报错的Bug
|
||||
- uni-swipe-action 新增 close-all 方法,关闭所有已打开的组件
|
||||
- uni-swipe-action 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
|
||||
- uni-swipe-action 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
|
||||
- uni-swipe-action 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
|
||||
|
||||
|
||||
## 3.2.3(2021-08-27)
|
||||
- 优化 tabbar 页面移除 vuex 相关代码
|
||||
- 新增 适配 vue3 (app)
|
||||
## 3.2.2(2021-08-10)
|
||||
- 新增 适配快手小程序
|
||||
- 新增 同步 uni-ui
|
||||
- uni-datetime-picker 新增 return-type 属性支持返回 date 日期对象
|
||||
- uni-file-picker 修复 fileExtname属性不指定值报错的Bug
|
||||
- uni-file-picker 修复 在某种场景下图片不回显的Bug
|
||||
- uni-link 支持自定义插槽
|
||||
- uni-calendar 修复 弹出层被 tabbar 遮盖 bug
|
||||
- uni-dateformat 调整 默认时间不再是当前时间,而是显示'-'字符
|
||||
- uni-datetime-picker 新增 适配 vue3
|
||||
- uni-datetime-picker 新增 支持作为 uni-forms 子组件相关功能
|
||||
- uni-datetime-picker 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
|
||||
- uni-datetime-picker 修复 type 属性动态赋值无效的 bug
|
||||
- uni-datetime-picker 修复 ‘确认’按钮被 tabbar 遮盖 bug
|
||||
- uni-datetime-picker 修复 组件未赋值时范围选左、右日历相同的 bug
|
||||
- uni-datetime-picker 修复 范围选未正确显示当前值的 bug
|
||||
- uni-datetime-picker 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
|
||||
- uni-file-picker 修复 auto-upload 属性失效的Bug
|
||||
## 3.2.1(2021-07-31)
|
||||
- 新增 同步 uni-ui@1.3.8
|
||||
## 3.2.0(2021-07-30)
|
||||
- 新增 同时兼容 vue2 & vue3
|
||||
## 3.1.20(2021-07-30)
|
||||
- 新增 同时兼容 vue2 & vue3
|
||||
## 3.1.17(2021-05-26)
|
||||
- 修复 3.1.16 依赖 sass 的问题
|
||||
- 条件编译 nuve 不支持 css 属性
|
||||
## 3.1.16(2021-05-26)
|
||||
- 修复 uni-data-checkbox 不关联服务空间的情况下组件报错的 Bug
|
||||
## 3.1.12(2021-05-07)
|
||||
- hello-uniapp 发布插件市场
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
export default {
|
||||
"list": [{
|
||||
"letter": "A",
|
||||
"data": [
|
||||
"阿克苏机场",
|
||||
"阿拉山口机场",
|
||||
"阿勒泰机场",
|
||||
"阿里昆莎机场",
|
||||
"安庆天柱山机场",
|
||||
"澳门国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "B",
|
||||
"data": [
|
||||
"保山机场",
|
||||
"包头机场",
|
||||
"北海福成机场",
|
||||
"北京南苑机场",
|
||||
"北京首都国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "C",
|
||||
"data": [
|
||||
"长白山机场",
|
||||
"长春龙嘉国际机场",
|
||||
"常德桃花源机场",
|
||||
"昌都邦达机场",
|
||||
"长沙黄花国际机场",
|
||||
"长治王村机场",
|
||||
"常州奔牛机场",
|
||||
"成都双流国际机场",
|
||||
"赤峰机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "D",
|
||||
"data": [
|
||||
"大理机场",
|
||||
"大连周水子国际机场",
|
||||
"大庆萨尔图机场",
|
||||
"大同东王庄机场",
|
||||
"达州河市机场",
|
||||
"丹东浪头机场",
|
||||
"德宏芒市机场",
|
||||
"迪庆香格里拉机场",
|
||||
"东营机场",
|
||||
"敦煌机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "E",
|
||||
"data": [
|
||||
"鄂尔多斯机场",
|
||||
"恩施许家坪机场",
|
||||
"二连浩特赛乌苏国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "F",
|
||||
"data": [
|
||||
"阜阳西关机场",
|
||||
"福州长乐国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "G",
|
||||
"data": [
|
||||
"赣州黄金机场",
|
||||
"格尔木机场",
|
||||
"固原六盘山机场",
|
||||
"广元盘龙机场",
|
||||
"广州白云国际机场",
|
||||
"桂林两江国际机场",
|
||||
"贵阳龙洞堡国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "H",
|
||||
"data": [
|
||||
"哈尔滨太平国际机场",
|
||||
"哈密机场",
|
||||
"海口美兰国际机场",
|
||||
"海拉尔东山国际机场",
|
||||
"邯郸机场",
|
||||
"汉中机场",
|
||||
"杭州萧山国际机场",
|
||||
"合肥骆岗国际机场",
|
||||
"和田机场",
|
||||
"黑河机场",
|
||||
"呼和浩特白塔国际机场",
|
||||
"淮安涟水机场",
|
||||
"黄山屯溪国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "I",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "J",
|
||||
"data": [
|
||||
"济南遥墙国际机场",
|
||||
"济宁曲阜机场",
|
||||
"鸡西兴凯湖机场",
|
||||
"佳木斯东郊机场",
|
||||
"嘉峪关机场",
|
||||
"锦州小岭子机场",
|
||||
"景德镇机场",
|
||||
"井冈山机场",
|
||||
"九江庐山机场",
|
||||
"九寨黄龙机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "K",
|
||||
"data": [
|
||||
"喀什机场",
|
||||
"克拉玛依机场",
|
||||
"库车龟兹机场",
|
||||
"库尔勒机场",
|
||||
"昆明巫家坝国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "L",
|
||||
"data": [
|
||||
"拉萨贡嘎机场",
|
||||
"兰州中川机场",
|
||||
"丽江三义机场",
|
||||
"黎平机场",
|
||||
"连云港白塔埠机场",
|
||||
"临沧机场",
|
||||
"临沂机场",
|
||||
"林芝米林机场",
|
||||
"柳州白莲机场",
|
||||
"龙岩冠豸山机场",
|
||||
"泸州蓝田机场",
|
||||
"洛阳北郊机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "M",
|
||||
"data": [
|
||||
"满洲里西郊机场",
|
||||
"绵阳南郊机场",
|
||||
"漠河古莲机场",
|
||||
"牡丹江海浪机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "N",
|
||||
"data": [
|
||||
"南昌昌北国际机场",
|
||||
"南充高坪机场",
|
||||
"南京禄口国际机场",
|
||||
"南宁吴圩机场",
|
||||
"南通兴东机场",
|
||||
"南阳姜营机场",
|
||||
"宁波栎社国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "O",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "P",
|
||||
"data": [
|
||||
"普洱思茅机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "Q",
|
||||
"data": [
|
||||
"齐齐哈尔三家子机场",
|
||||
"秦皇岛山海关机场",
|
||||
"青岛流亭国际机场",
|
||||
"衢州机场",
|
||||
"泉州晋江机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "R",
|
||||
"data": [
|
||||
"日喀则和平机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "S",
|
||||
"data": [
|
||||
"三亚凤凰国际机场",
|
||||
"汕头外砂机场",
|
||||
"上海虹桥国际机场",
|
||||
"上海浦东国际机场",
|
||||
"深圳宝安国际机场",
|
||||
"沈阳桃仙国际机场",
|
||||
"石家庄正定国际机场",
|
||||
"苏南硕放国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "T",
|
||||
"data": [
|
||||
"塔城机场",
|
||||
"太原武宿国际机场",
|
||||
"台州路桥机场 (黄岩机场)",
|
||||
"唐山三女河机场",
|
||||
"腾冲驼峰机场",
|
||||
"天津滨海国际机场",
|
||||
"通辽机场",
|
||||
"铜仁凤凰机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "U",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "V",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "W",
|
||||
"data": [
|
||||
"万州五桥机场",
|
||||
"潍坊机场",
|
||||
"威海大水泊机场",
|
||||
"文山普者黑机场",
|
||||
"温州永强国际机场",
|
||||
"乌海机场",
|
||||
"武汉天河国际机场",
|
||||
"乌兰浩特机场",
|
||||
"乌鲁木齐地窝堡国际机场",
|
||||
"武夷山机场",
|
||||
"梧州长洲岛机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "X",
|
||||
"data": [
|
||||
"西安咸阳国际机场",
|
||||
"西昌青山机场",
|
||||
"锡林浩特机场",
|
||||
"西宁曹家堡机场",
|
||||
"西双版纳嘎洒机场",
|
||||
"厦门高崎国际机场",
|
||||
"香港国际机场",
|
||||
"襄阳刘集机场",
|
||||
"兴义机场",
|
||||
"徐州观音机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "Y",
|
||||
"data": [
|
||||
"延安二十里堡机场",
|
||||
"盐城机场",
|
||||
"延吉朝阳川机场",
|
||||
"烟台莱山国际机场",
|
||||
"宜宾菜坝机场",
|
||||
"宜昌三峡机场",
|
||||
"伊春林都机场",
|
||||
"伊宁机场",
|
||||
"义乌机场",
|
||||
"银川河东机场",
|
||||
"永州零陵机场",
|
||||
"榆林榆阳机场",
|
||||
"玉树巴塘机场",
|
||||
"运城张孝机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "Z",
|
||||
"data": [
|
||||
"湛江机场",
|
||||
"昭通机场",
|
||||
"郑州新郑国际机场",
|
||||
"芷江机场",
|
||||
"重庆江北国际机场",
|
||||
"中卫香山机场",
|
||||
"舟山朱家尖机场",
|
||||
"珠海三灶机场"
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
数据验证(表单验证)
|
||||
来自 grace.hcoder.net
|
||||
作者 hcoder 深海
|
||||
*/
|
||||
export default {
|
||||
error:'',
|
||||
check : function (data, rule){
|
||||
for(var i = 0; i < rule.length; i++){
|
||||
if (!rule[i].checkType){return true;}
|
||||
if (!rule[i].name) {return true;}
|
||||
if (!rule[i].errorMsg) {return true;}
|
||||
if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;}
|
||||
switch (rule[i].checkType){
|
||||
case 'string':
|
||||
var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
|
||||
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
case 'int':
|
||||
var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
|
||||
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
break;
|
||||
case 'between':
|
||||
if (!this.isNumber(data[rule[i].name])){
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
var minMax = rule[i].checkRule.split(',');
|
||||
minMax[0] = Number(minMax[0]);
|
||||
minMax[1] = Number(minMax[1]);
|
||||
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'betweenD':
|
||||
var reg = /^-?[1-9][0-9]?$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
var minMax = rule[i].checkRule.split(',');
|
||||
minMax[0] = Number(minMax[0]);
|
||||
minMax[1] = Number(minMax[1]);
|
||||
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'betweenF':
|
||||
var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
|
||||
if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;}
|
||||
var minMax = rule[i].checkRule.split(',');
|
||||
minMax[0] = Number(minMax[0]);
|
||||
minMax[1] = Number(minMax[1]);
|
||||
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'same':
|
||||
if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
case 'notsame':
|
||||
if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'email':
|
||||
var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'phoneno':
|
||||
var reg = /^1[0-9]{10,10}$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'zipcode':
|
||||
var reg = /^[0-9]{6}$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'reg':
|
||||
var reg = new RegExp(rule[i].checkRule);
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'in':
|
||||
if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){
|
||||
this.error = rule[i].errorMsg; return false;
|
||||
}
|
||||
break;
|
||||
case 'notnull':
|
||||
if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
isNumber : function (checkVal){
|
||||
var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
|
||||
return reg.test(checkVal);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* HTML5 Parser By Sam Blowes
|
||||
*
|
||||
* Designed for HTML5 documents
|
||||
*
|
||||
* Original code by John Resig (ejohn.org)
|
||||
* http://ejohn.org/blog/pure-javascript-html-parser/
|
||||
* Original code by Erik Arvidsson, Mozilla Public License
|
||||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* License
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* This code is triple licensed using Apache Software License 2.0,
|
||||
* Mozilla Public License or GNU Public License
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////////////
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////////////
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Simple HTML Parser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Erik Arvidsson.
|
||||
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////////////
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Usage
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* // Use like so:
|
||||
* HTMLParser(htmlString, {
|
||||
* start: function(tag, attrs, unary) {},
|
||||
* end: function(tag) {},
|
||||
* chars: function(text) {},
|
||||
* comment: function(text) {}
|
||||
* });
|
||||
*
|
||||
* // or to get an XML string:
|
||||
* HTMLtoXML(htmlString);
|
||||
*
|
||||
* // or to get an XML DOM Document
|
||||
* HTMLtoDOM(htmlString);
|
||||
*
|
||||
* // or to inject into an existing document/DOM node
|
||||
* HTMLtoDOM(htmlString, document);
|
||||
* HTMLtoDOM(htmlString, document.body);
|
||||
*
|
||||
*/
|
||||
// Regular Expressions for parsing tags and attributes
|
||||
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
|
||||
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
|
||||
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
|
||||
|
||||
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
|
||||
// fixed by xxx 将 ins 标签从块级名单中移除
|
||||
|
||||
var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
|
||||
|
||||
var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
|
||||
// (and which close themselves)
|
||||
|
||||
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
|
||||
|
||||
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
|
||||
|
||||
var special = makeMap('script,style');
|
||||
function HTMLParser(html, handler) {
|
||||
var index;
|
||||
var chars;
|
||||
var match;
|
||||
var stack = [];
|
||||
var last = html;
|
||||
|
||||
stack.last = function () {
|
||||
return this[this.length - 1];
|
||||
};
|
||||
|
||||
while (html) {
|
||||
chars = true; // Make sure we're not in a script or style element
|
||||
|
||||
if (!stack.last() || !special[stack.last()]) {
|
||||
// Comment
|
||||
if (html.indexOf('<!--') == 0) {
|
||||
index = html.indexOf('-->');
|
||||
|
||||
if (index >= 0) {
|
||||
if (handler.comment) {
|
||||
handler.comment(html.substring(4, index));
|
||||
}
|
||||
|
||||
html = html.substring(index + 3);
|
||||
chars = false;
|
||||
} // end tag
|
||||
|
||||
} else if (html.indexOf('</') == 0) {
|
||||
match = html.match(endTag);
|
||||
|
||||
if (match) {
|
||||
html = html.substring(match[0].length);
|
||||
match[0].replace(endTag, parseEndTag);
|
||||
chars = false;
|
||||
} // start tag
|
||||
|
||||
} else if (html.indexOf('<') == 0) {
|
||||
match = html.match(startTag);
|
||||
|
||||
if (match) {
|
||||
html = html.substring(match[0].length);
|
||||
match[0].replace(startTag, parseStartTag);
|
||||
chars = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (chars) {
|
||||
index = html.indexOf('<');
|
||||
var text = index < 0 ? html : html.substring(0, index);
|
||||
html = index < 0 ? '' : html.substring(index);
|
||||
|
||||
if (handler.chars) {
|
||||
handler.chars(text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
|
||||
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
|
||||
|
||||
if (handler.chars) {
|
||||
handler.chars(text);
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
parseEndTag('', stack.last());
|
||||
}
|
||||
|
||||
if (html == last) {
|
||||
throw 'Parse Error: ' + html;
|
||||
}
|
||||
|
||||
last = html;
|
||||
} // Clean up any remaining tags
|
||||
|
||||
|
||||
parseEndTag();
|
||||
|
||||
function parseStartTag(tag, tagName, rest, unary) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
if (block[tagName]) {
|
||||
while (stack.last() && inline[stack.last()]) {
|
||||
parseEndTag('', stack.last());
|
||||
}
|
||||
}
|
||||
|
||||
if (closeSelf[tagName] && stack.last() == tagName) {
|
||||
parseEndTag('', tagName);
|
||||
}
|
||||
|
||||
unary = empty[tagName] || !!unary;
|
||||
|
||||
if (!unary) {
|
||||
stack.push(tagName);
|
||||
}
|
||||
|
||||
if (handler.start) {
|
||||
var attrs = [];
|
||||
rest.replace(attr, function (match, name) {
|
||||
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
|
||||
attrs.push({
|
||||
name: name,
|
||||
value: value,
|
||||
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
if (handler.start) {
|
||||
handler.start(tagName, attrs, unary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseEndTag(tag, tagName) {
|
||||
// If no tag name is provided, clean shop
|
||||
if (!tagName) {
|
||||
var pos = 0;
|
||||
} // Find the closest opened tag of the same type
|
||||
else {
|
||||
for (var pos = stack.length - 1; pos >= 0; pos--) {
|
||||
if (stack[pos] == tagName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= 0) {
|
||||
// Close all the open elements, up the stack
|
||||
for (var i = stack.length - 1; i >= pos; i--) {
|
||||
if (handler.end) {
|
||||
handler.end(stack[i]);
|
||||
}
|
||||
} // Remove the open elements from the stack
|
||||
|
||||
|
||||
stack.length = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeMap(str) {
|
||||
var obj = {};
|
||||
var items = str.split(',');
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
obj[items[i]] = true;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function removeDOCTYPE(html) {
|
||||
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
|
||||
}
|
||||
|
||||
function parseAttrs(attrs) {
|
||||
return attrs.reduce(function (pre, attr) {
|
||||
var value = attr.value;
|
||||
var name = attr.name;
|
||||
|
||||
if (pre[name]) {
|
||||
pre[name] = pre[name] + " " + value;
|
||||
} else {
|
||||
pre[name] = value;
|
||||
}
|
||||
|
||||
return pre;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function parseHtml(html) {
|
||||
html = removeDOCTYPE(html);
|
||||
var stacks = [];
|
||||
var results = {
|
||||
node: 'root',
|
||||
children: []
|
||||
};
|
||||
HTMLParser(html, {
|
||||
start: function start(tag, attrs, unary) {
|
||||
var node = {
|
||||
name: tag
|
||||
};
|
||||
|
||||
if (attrs.length !== 0) {
|
||||
node.attrs = parseAttrs(attrs);
|
||||
}
|
||||
|
||||
if (unary) {
|
||||
var parent = stacks[0] || results;
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
} else {
|
||||
stacks.unshift(node);
|
||||
}
|
||||
},
|
||||
end: function end(tag) {
|
||||
var node = stacks.shift();
|
||||
if (node.name !== tag) console.error('invalid state: mismatch end tag');
|
||||
|
||||
if (stacks.length === 0) {
|
||||
results.children.push(node);
|
||||
} else {
|
||||
var parent = stacks[0];
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
}
|
||||
},
|
||||
chars: function chars(text) {
|
||||
var node = {
|
||||
type: 'text',
|
||||
text: text
|
||||
};
|
||||
|
||||
if (stacks.length === 0) {
|
||||
results.children.push(node);
|
||||
} else {
|
||||
var parent = stacks[0];
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
}
|
||||
},
|
||||
comment: function comment(text) {
|
||||
var node = {
|
||||
node: 'comment',
|
||||
text: text
|
||||
};
|
||||
var parent = stacks[0];
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
}
|
||||
});
|
||||
return results.children;
|
||||
}
|
||||
|
||||
export default parseHtml;
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
/// null = 未请求,1 = 已允许,0 = 拒绝|受限, 2 = 系统未开启
|
||||
|
||||
var isIOS
|
||||
|
||||
function album() {
|
||||
var result = 0;
|
||||
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
|
||||
var authStatus = PHPhotoLibrary.authorizationStatus();
|
||||
if (authStatus === 0) {
|
||||
result = null;
|
||||
} else if (authStatus == 3) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
plus.ios.deleteObject(PHPhotoLibrary);
|
||||
return result;
|
||||
}
|
||||
|
||||
function camera() {
|
||||
var result = 0;
|
||||
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
|
||||
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
|
||||
if (authStatus === 0) {
|
||||
result = null;
|
||||
} else if (authStatus == 3) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
plus.ios.deleteObject(AVCaptureDevice);
|
||||
return result;
|
||||
}
|
||||
|
||||
function location() {
|
||||
var result = 0;
|
||||
var cllocationManger = plus.ios.import("CLLocationManager");
|
||||
var enable = cllocationManger.locationServicesEnabled();
|
||||
var status = cllocationManger.authorizationStatus();
|
||||
if (!enable) {
|
||||
result = 2;
|
||||
} else if (status === 0) {
|
||||
result = null;
|
||||
} else if (status === 3 || status === 4) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
plus.ios.deleteObject(cllocationManger);
|
||||
return result;
|
||||
}
|
||||
|
||||
function push() {
|
||||
var result = 0;
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var app = UIApplication.sharedApplication();
|
||||
var enabledTypes = 0;
|
||||
if (app.currentUserNotificationSettings) {
|
||||
var settings = app.currentUserNotificationSettings();
|
||||
enabledTypes = settings.plusGetAttribute("types");
|
||||
if (enabledTypes == 0) {
|
||||
result = 0;
|
||||
console.log("推送权限没有开启");
|
||||
} else {
|
||||
result = 1;
|
||||
console.log("已经开启推送功能!")
|
||||
}
|
||||
plus.ios.deleteObject(settings);
|
||||
} else {
|
||||
enabledTypes = app.enabledRemoteNotificationTypes();
|
||||
if (enabledTypes == 0) {
|
||||
result = 3;
|
||||
console.log("推送权限没有开启!");
|
||||
} else {
|
||||
result = 4;
|
||||
console.log("已经开启推送功能!")
|
||||
}
|
||||
}
|
||||
plus.ios.deleteObject(app);
|
||||
plus.ios.deleteObject(UIApplication);
|
||||
return result;
|
||||
}
|
||||
|
||||
function contact() {
|
||||
var result = 0;
|
||||
var CNContactStore = plus.ios.import("CNContactStore");
|
||||
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
|
||||
if (cnAuthStatus === 0) {
|
||||
result = null;
|
||||
} else if (cnAuthStatus == 3) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
plus.ios.deleteObject(CNContactStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
function record() {
|
||||
var result = null;
|
||||
var avaudiosession = plus.ios.import("AVAudioSession");
|
||||
var avaudio = avaudiosession.sharedInstance();
|
||||
var status = avaudio.recordPermission();
|
||||
console.log("permissionStatus:" + status);
|
||||
if (status === 1970168948) {
|
||||
result = null;
|
||||
} else if (status === 1735552628) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
plus.ios.deleteObject(avaudiosession);
|
||||
return result;
|
||||
}
|
||||
|
||||
function calendar() {
|
||||
var result = null;
|
||||
var EKEventStore = plus.ios.import("EKEventStore");
|
||||
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
|
||||
if (ekAuthStatus == 3) {
|
||||
result = 1;
|
||||
console.log("日历权限已经开启");
|
||||
} else {
|
||||
console.log("日历权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(EKEventStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
function memo() {
|
||||
var result = null;
|
||||
var EKEventStore = plus.ios.import("EKEventStore");
|
||||
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
|
||||
if (ekAuthStatus == 3) {
|
||||
result = 1;
|
||||
console.log("备忘录权限已经开启");
|
||||
} else {
|
||||
console.log("备忘录权限没有开启");
|
||||
}
|
||||
plus.ios.deleteObject(EKEventStore);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function requestIOS(permissionID) {
|
||||
return new Promise((resolve, reject) => {
|
||||
switch (permissionID) {
|
||||
case "push":
|
||||
resolve(push());
|
||||
break;
|
||||
case "location":
|
||||
resolve(location());
|
||||
break;
|
||||
case "record":
|
||||
resolve(record());
|
||||
break;
|
||||
case "camera":
|
||||
resolve(camera());
|
||||
break;
|
||||
case "album":
|
||||
resolve(album());
|
||||
break;
|
||||
case "contact":
|
||||
resolve(contact());
|
||||
break;
|
||||
case "calendar":
|
||||
resolve(calendar());
|
||||
break;
|
||||
case "memo":
|
||||
resolve(memo());
|
||||
break;
|
||||
default:
|
||||
resolve(0);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function requestAndroid(permissionID) {
|
||||
return new Promise((resolve, reject) => {
|
||||
plus.android.requestPermissions(
|
||||
[permissionID],
|
||||
function(resultObj) {
|
||||
var result = 0;
|
||||
for (var i = 0; i < resultObj.granted.length; i++) {
|
||||
var grantedPermission = resultObj.granted[i];
|
||||
console.log('已获取的权限:' + grantedPermission);
|
||||
result = 1
|
||||
}
|
||||
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
|
||||
var deniedPresentPermission = resultObj.deniedPresent[i];
|
||||
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
|
||||
result = 0
|
||||
}
|
||||
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
|
||||
var deniedAlwaysPermission = resultObj.deniedAlways[i];
|
||||
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
|
||||
result = -1
|
||||
}
|
||||
resolve(result);
|
||||
},
|
||||
function(error) {
|
||||
console.log('result error: ' + error.message)
|
||||
resolve({
|
||||
code: error.code,
|
||||
message: error.message
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function gotoAppPermissionSetting() {
|
||||
if (permission.isIOS) {
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var application2 = UIApplication.sharedApplication();
|
||||
var NSURL2 = plus.ios.import("NSURL");
|
||||
var setting2 = NSURL2.URLWithString("app-settings:");
|
||||
application2.openURL(setting2);
|
||||
plus.ios.deleteObject(setting2);
|
||||
plus.ios.deleteObject(NSURL2);
|
||||
plus.ios.deleteObject(application2);
|
||||
} else {
|
||||
var Intent = plus.android.importClass("android.content.Intent");
|
||||
var Settings = plus.android.importClass("android.provider.Settings");
|
||||
var Uri = plus.android.importClass("android.net.Uri");
|
||||
var mainActivity = plus.android.runtimeMainActivity();
|
||||
var intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
mainActivity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
const permission = {
|
||||
get isIOS(){
|
||||
return typeof isIOS === 'boolean' ? isIOS : (isIOS = uni.getSystemInfoSync().platform === 'ios')
|
||||
},
|
||||
requestIOS: requestIOS,
|
||||
requestAndroid: requestAndroid,
|
||||
gotoAppSetting: gotoAppPermissionSetting
|
||||
}
|
||||
|
||||
export default permission
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/* #ifndef APP-PLUS-NVUE */
|
||||
page {
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/* 解决头条小程序字体图标不显示问题,因为头条运行时自动插入了span标签,且有全局字体 */
|
||||
/* #ifdef MP-TOUTIAO */
|
||||
/* text :not(view) {
|
||||
font-family: uniicons;
|
||||
} */
|
||||
/* #endif */
|
||||
|
||||
.uni-icon {
|
||||
font-family: uniicons;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.uni-container {
|
||||
padding: 15px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.uni-header-logo {
|
||||
/* #ifdef H5 */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
padding: 15px 15px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.uni-header-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.uni-hello-text {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.hello-text {
|
||||
color: #7A7E83;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.hello-link {
|
||||
color: #7A7E83;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.uni-panel {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.uni-panel-h {
|
||||
/* #ifdef H5 */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
background-color: #ffffff;
|
||||
flex-direction: row !important;
|
||||
/* justify-content: space-between !important; */
|
||||
align-items: center !important;
|
||||
padding: 12px;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
/*
|
||||
.uni-panel-h:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
*/
|
||||
.uni-panel-h-on {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.uni-panel-text {
|
||||
flex: 1;
|
||||
color: #000000;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.uni-panel-icon {
|
||||
margin-left: 15px;
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
transform: rotate(0deg);
|
||||
transition-duration: 0s;
|
||||
transition-property: transform;
|
||||
}
|
||||
|
||||
.uni-panel-icon-on {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.uni-navigate-item {
|
||||
/* #ifdef H5 */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
border-top-style: solid;
|
||||
border-top-color: #f0f0f0;
|
||||
border-top-width: 1px;
|
||||
padding: 12px;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-navigate-item:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.uni-navigate-text {
|
||||
flex: 1;
|
||||
color: #000000;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.uni-navigate-icon {
|
||||
margin-left: 15px;
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,73 @@
|
|||
function formatTime(time) {
|
||||
if (typeof time !== 'number' || time < 0) {
|
||||
return time
|
||||
}
|
||||
|
||||
var hour = parseInt(time / 3600)
|
||||
time = time % 3600
|
||||
var minute = parseInt(time / 60)
|
||||
time = time % 60
|
||||
var second = time
|
||||
|
||||
return ([hour, minute, second]).map(function(n) {
|
||||
n = n.toString()
|
||||
return n[1] ? n : '0' + n
|
||||
}).join(':')
|
||||
}
|
||||
|
||||
function formatLocation(longitude, latitude) {
|
||||
if (typeof longitude === 'string' && typeof latitude === 'string') {
|
||||
longitude = parseFloat(longitude)
|
||||
latitude = parseFloat(latitude)
|
||||
}
|
||||
|
||||
longitude = longitude.toFixed(2)
|
||||
latitude = latitude.toFixed(2)
|
||||
|
||||
return {
|
||||
longitude: longitude.toString().split('.'),
|
||||
latitude: latitude.toString().split('.')
|
||||
}
|
||||
}
|
||||
var dateUtils = {
|
||||
UNITS: {
|
||||
'年': 31557600000,
|
||||
'月': 2629800000,
|
||||
'天': 86400000,
|
||||
'小时': 3600000,
|
||||
'分钟': 60000,
|
||||
'秒': 1000
|
||||
},
|
||||
humanize: function(milliseconds) {
|
||||
var humanize = '';
|
||||
for (var key in this.UNITS) {
|
||||
if (milliseconds >= this.UNITS[key]) {
|
||||
humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return humanize || '刚刚';
|
||||
},
|
||||
format: function(dateStr) {
|
||||
var date = this.parse(dateStr)
|
||||
var diff = Date.now() - date.getTime();
|
||||
if (diff < this.UNITS['天']) {
|
||||
return this.humanize(diff);
|
||||
}
|
||||
var _format = function(number) {
|
||||
return (number < 10 ? ('0' + number) : number);
|
||||
};
|
||||
return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
|
||||
_format(date.getHours()) + ':' + _format(date.getMinutes());
|
||||
},
|
||||
parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
|
||||
var a = str.split(/[^0-9]/);
|
||||
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
formatTime,
|
||||
formatLocation,
|
||||
dateUtils
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
import amap from '@/components/amap-wx/lib/amap-wx.js';
|
||||
// 地铁颜色图
|
||||
const line = {
|
||||
'1号线': '#C43B33',
|
||||
'2号线': '#016299',
|
||||
'4号线/大兴线': '#008E9C',
|
||||
'5号线': '#A42380',
|
||||
'6号线': '#D09900',
|
||||
'7号线': '#F2C172',
|
||||
'8号线': '#009D6A',
|
||||
'9号线': '#8FC41E',
|
||||
'10号线': '#009DBE',
|
||||
'13号线': '#F9E701',
|
||||
'14号线东段': '#D4A7A2',
|
||||
'14号线西段': '#D4A7A2',
|
||||
'15号线': '#5D2D69',
|
||||
'八通线': '#C33A32',
|
||||
'昌平线': '#DE82B1',
|
||||
'亦庄线': '#E40177',
|
||||
'房山线': '#E66021',
|
||||
'机场线': '#A29BBC',
|
||||
}
|
||||
|
||||
// 150500:地铁站 ,150700:公交站 , 190700:地名地址
|
||||
const typecode = [{
|
||||
id: '150500',
|
||||
icon: 'icon-ditie'
|
||||
}, {
|
||||
id: '150700',
|
||||
icon: 'icon-gongjiao'
|
||||
}, {
|
||||
id: '190700',
|
||||
icon: 'icon-gonglu'
|
||||
}];
|
||||
|
||||
const util = {
|
||||
key:'b526b09b86cd2996e7732be8ab8c4430',
|
||||
/**
|
||||
* 初始化高德地图api
|
||||
*/
|
||||
mapInit() {
|
||||
return new amap.AMapWX({
|
||||
key: this.key
|
||||
});
|
||||
},
|
||||
// 服务状态吗
|
||||
typecode,
|
||||
/**
|
||||
* 获取地图颜色
|
||||
*/
|
||||
lineColor(name) {
|
||||
if (line[name]) {
|
||||
return line[name];
|
||||
} else {
|
||||
return '#ccc';
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 关键字颜色变化
|
||||
*/
|
||||
serachNmme(val, name) {
|
||||
let namestr = new RegExp(val);
|
||||
let nameresult =
|
||||
`<div style="font-size: 14px;color: #333;line-height: 1.5;">
|
||||
${name.replace(namestr, "<span style='color:#66ccff;'>" + val + '</span>')}
|
||||
</div>`
|
||||
.trim();
|
||||
|
||||
return nameresult;
|
||||
},
|
||||
/**
|
||||
* 地址转地铁线路
|
||||
*/
|
||||
addressToLine(address, type) {
|
||||
let addr = address.split(';');
|
||||
let dt = '';
|
||||
addr.forEach(elm => {
|
||||
let color = '#cccccc';
|
||||
if (type === typecode[0].id) {
|
||||
color = this.lineColor(elm)
|
||||
} else if (type === typecode[1].id) {
|
||||
color = '#4075cb'
|
||||
}
|
||||
let style = 'margin:5px 0;margin-right:5px;padding:0 5px;background:' + color +
|
||||
';font-size:12px;color:#fff;border-radius:3px;';
|
||||
dt += `<div style=\'${style}\'>${elm}</div>`;
|
||||
|
||||
});
|
||||
return `<div style="display:flex;flex-wrap: wrap;">${dt}</div>`;
|
||||
},
|
||||
/**
|
||||
* 数据处理
|
||||
*/
|
||||
dataHandle(item, val) {
|
||||
// 改变字体颜色
|
||||
if (val) {
|
||||
item.nameNodes = util.serachNmme(val, item.name);
|
||||
} else {
|
||||
item.nameNodes = `<div style="font-size: 14px;color: #333;line-height: 1.5;">${item.name}</div>`;
|
||||
|
||||
}
|
||||
// 地址解析 地铁
|
||||
if (
|
||||
item.typecode === util.typecode[0].id ||
|
||||
item.typecode === util.typecode[1].id
|
||||
) {
|
||||
item.addressNodes = util.addressToLine(item.address, item.typecode);
|
||||
if (item.typecode === util.typecode[0].id) {
|
||||
item.icon = util.typecode[0].icon;
|
||||
} else if (item.typecode === util.typecode[1].id) {
|
||||
item.icon = util.typecode[1].icon;
|
||||
}
|
||||
} else {
|
||||
item.addressNodes = `<span>${item.district}${
|
||||
item.address.length > 0 ? '·' + item.address : ''
|
||||
}</span>`.trim();
|
||||
item.icon = 'icon-weizhi';
|
||||
}
|
||||
|
||||
if (item.location && item.location.length === 0) {
|
||||
item.icon = 'icon-sousuo';
|
||||
}
|
||||
|
||||
return item;
|
||||
},
|
||||
/**
|
||||
* 存储历史数据
|
||||
* val [string | object]需要存储的内容
|
||||
*/
|
||||
setHistory(val) {
|
||||
let searchHistory = uni.getStorageSync('search:history');
|
||||
if (!searchHistory) searchHistory = [];
|
||||
let serachData = {};
|
||||
if (typeof(val) === 'string') {
|
||||
serachData = {
|
||||
adcode: [],
|
||||
address: [],
|
||||
city: [],
|
||||
district: [],
|
||||
id: [],
|
||||
location: [],
|
||||
name: val,
|
||||
typecode: []
|
||||
};
|
||||
} else {
|
||||
serachData = val
|
||||
}
|
||||
|
||||
// 判断数组是否存在,如果存在,那么将放到最前面
|
||||
for (var i = 0; i < searchHistory.length; i++) {
|
||||
if (searchHistory[i].name === serachData.name) {
|
||||
searchHistory.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
searchHistory.unshift(util.dataHandle(serachData));
|
||||
uni.setStorage({
|
||||
key: 'search:history',
|
||||
data: searchHistory,
|
||||
success: function() {
|
||||
// console.log('success');
|
||||
}
|
||||
});
|
||||
},
|
||||
getHistory() {
|
||||
|
||||
},
|
||||
removeHistory() {
|
||||
uni.removeStorage({
|
||||
key: 'search:history',
|
||||
success: function(res) {
|
||||
console.log('success');
|
||||
}
|
||||
});
|
||||
return []
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default util;
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<view class="uni-padding-wrap">
|
||||
<page-head :title="title"></page-head>
|
||||
<button class="button" @click="setTabBarBadge">{{ !hasSetTabBarBadge ? '设置tab徽标' : '移除tab徽标' }}</button>
|
||||
<!-- #ifndef MP-HARMONY -->
|
||||
<button class="button" @click="showTabBarRedDot">{{ !hasShownTabBarRedDot ? '显示红点' : '移除红点'}}</button>
|
||||
<button class="button" @click="customStyle">{{ !hasCustomedStyle ? '自定义Tab样式' : '移除自定义样式'}}</button>
|
||||
<button class="button" @click="customItem">{{ !hasCustomedItem ? '自定义Tab信息' : '移除自定义信息' }}</button>
|
||||
<!-- #endif -->
|
||||
<button class="button" @click="hideTabBar">{{ !hasHiddenTabBar ? '隐藏TabBar' : '显示TabBar' }}</button>
|
||||
<view class="btn-area">
|
||||
<button class="button" type="primary" @click="navigateBack">返回上一级</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'tababr',
|
||||
hasSetTabBarBadge: false,
|
||||
hasShownTabBarRedDot: false,
|
||||
hasCustomedStyle: false,
|
||||
hasCustomedItem: false,
|
||||
hasHiddenTabBar: false
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.hasSetTabBarBadge) {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
if (this.hasShownTabBarRedDot) {
|
||||
uni.hideTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
if (this.hasHiddenTabBar) {
|
||||
uni.showTabBar()
|
||||
}
|
||||
if (this.hasCustomedStyle) {
|
||||
uni.setTabBarStyle({
|
||||
color: '#7A7E83',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#F8F8F8',
|
||||
borderStyle: 'black'
|
||||
})
|
||||
}
|
||||
|
||||
if (this.hasCustomedItem) {
|
||||
let tabBarOptions = {
|
||||
index: 1,
|
||||
text: '接口',
|
||||
iconPath: '/static/api.png',
|
||||
selectedIconPath: '/static/apiHL.png'
|
||||
}
|
||||
uni.setTabBarItem(tabBarOptions)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navigateBack() {
|
||||
this.$emit('unmount')
|
||||
},
|
||||
setTabBarBadge() {
|
||||
if(this.hasShownTabBarRedDot){
|
||||
uni.hideTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
this.hasShownTabBarRedDot = !this.hasShownTabBarRedDot
|
||||
}
|
||||
if (!this.hasSetTabBarBadge) {
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: '1'
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
this.hasSetTabBarBadge = !this.hasSetTabBarBadge
|
||||
},
|
||||
showTabBarRedDot() {
|
||||
if(this.hasSetTabBarBadge) {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1
|
||||
})
|
||||
this.hasSetTabBarBadge = !this.hasSetTabBarBadge
|
||||
}
|
||||
if (!this.hasShownTabBarRedDot) {
|
||||
uni.showTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
} else {
|
||||
uni.hideTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
this.hasShownTabBarRedDot = !this.hasShownTabBarRedDot
|
||||
},
|
||||
hideTabBar() {
|
||||
if (!this.hasHiddenTabBar) {
|
||||
uni.hideTabBar()
|
||||
} else {
|
||||
uni.showTabBar()
|
||||
}
|
||||
this.hasHiddenTabBar = !this.hasHiddenTabBar
|
||||
},
|
||||
customStyle() {
|
||||
if (this.hasCustomedStyle) {
|
||||
uni.setTabBarStyle({
|
||||
color: '#7A7E83',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#F8F8F8',
|
||||
borderStyle: 'black'
|
||||
})
|
||||
} else {
|
||||
uni.setTabBarStyle({
|
||||
color: '#FFF',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#000000',
|
||||
borderStyle: 'black'
|
||||
})
|
||||
}
|
||||
this.hasCustomedStyle = !this.hasCustomedStyle
|
||||
},
|
||||
customItem() {
|
||||
let tabBarOptions = {
|
||||
index: 1,
|
||||
text: '接口',
|
||||
iconPath: '/static/api.png',
|
||||
selectedIconPath: '/static/apiHL.png'
|
||||
}
|
||||
if (this.hasCustomedItem) {
|
||||
uni.setTabBarItem(tabBarOptions)
|
||||
} else {
|
||||
tabBarOptions.text = 'API'
|
||||
uni.setTabBarItem(tabBarOptions)
|
||||
}
|
||||
this.hasCustomedItem = !this.hasCustomedItem
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.button {
|
||||
margin-top: 30rpx;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.btn-area {
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1 @@
|
|||
export default './lib/marked'
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,38 @@
|
|||
<template name="page-foot">
|
||||
<view class="page-share-title">
|
||||
<text>感谢{{name}}提供本示例,</text>
|
||||
<text class="submit" @click="submit">我也提交</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "page-foot",
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
uni.showModal({
|
||||
content:"hello uni-app开源地址为https://github.com/dcloudio/uni-app/tree/master/examples,请在这个开源项目上贡献你的代码",
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.page-share-title {
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #BEBEBE;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.submit {
|
||||
border-bottom: 1rpx solid #BEBEBE;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<template name="page-head">
|
||||
<view class="common-page-head">
|
||||
<view class="common-page-head-title">{{title}}</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "page-head",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<view class="product">
|
||||
<image class="product-image" :src="image ? image : 'https://via.placeholder.com/150x200'"></image>
|
||||
<view class="product-title">{{title}}</view>
|
||||
<view class="product-price">
|
||||
<text class="product-price-favour">¥{{originalPrice}}</text>
|
||||
<text class="product-price-original">¥{{favourPrice}}</text>
|
||||
<text class="product-tip">{{tip}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'product',
|
||||
props: ['image', 'title', 'originalPrice', 'favourPrice', 'tip']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.product {
|
||||
padding: 10rpx 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
height: 330rpx;
|
||||
width: 330rpx;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
width: 300rpx;
|
||||
font-size: 32rpx;
|
||||
word-break: break-all;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-price-original {
|
||||
color: #E80080;
|
||||
}
|
||||
|
||||
.product-price-favour {
|
||||
color: #888888;
|
||||
text-decoration: line-through;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.product-tip {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
background-color: #FF3333;
|
||||
color: #FFFFFF;
|
||||
padding: 0 10rpx;
|
||||
border-radius: 5rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
<template>
|
||||
<view class="view">
|
||||
<view class="list-cell view" hover-class="uni-list-cell-hover" @click="bindClick">
|
||||
<view class="media-list view" v-if="options.title">
|
||||
<view class="view" :class="{'media-image-right': options.article_type === 2, 'media-image-left': options.article_type === 1}">
|
||||
<text class="media-title" :class="{'media-title2': options.article_type === 1 || options.article_type === 2}">{{options.title}}</text>
|
||||
<view v-if="options.image_list || options.image_url" class="image-section view" :class="{'image-section-right': options.article_type === 2, 'image-section-left': options.article_type === 1}">
|
||||
<image class="image-list1" :class="{'image-list2': options.article_type === 1 || options.article_type === 2}"
|
||||
v-if="options.image_url" :src="options.image_url"></image>
|
||||
<image class="image-list3" v-if="options.image_list" :src="source.url" v-for="(source, i) in options.image_list"
|
||||
:key="i" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="media-foot view">
|
||||
<view class="media-info view">
|
||||
<text class="info-text">{{options.source}}</text>
|
||||
<text class="info-text">{{options.comment_count}}条评论</text>
|
||||
<text class="info-text">{{options.datetime}}</text>
|
||||
</view>
|
||||
<view class="max-close-view view" @click.stop="close">
|
||||
<view class="close-view view"><text class="close">×</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: function(e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close(e) {
|
||||
this.$emit('close');
|
||||
},
|
||||
bindClick() {
|
||||
this.$emit('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
width: 750rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.uni-list-cell-hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.media-list {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #c8c7cc;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.media-image-right {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.media-image-left {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.media-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.media-title {
|
||||
lines: 3;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 32rpx;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
.media-title2 {
|
||||
flex: 1;
|
||||
margin-top: 6rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.image-section {
|
||||
margin-top: 20rpx;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.image-section-right {
|
||||
margin-top: 0rpx;
|
||||
margin-left: 10rpx;
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.image-section-left {
|
||||
margin-top: 0rpx;
|
||||
margin-right: 10rpx;
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.image-list1 {
|
||||
width: 690rpx;
|
||||
height: 481rpx;
|
||||
}
|
||||
|
||||
.image-list2 {
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.image-list3 {
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.media-info {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
margin-right: 20rpx;
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.media-foot {
|
||||
margin-top: 20rpx;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.max-close-view {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-direction: row;
|
||||
height: 40rpx;
|
||||
width: 80rpx;
|
||||
}
|
||||
|
||||
.close-view {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #999999;
|
||||
border-radius: 10rpx;
|
||||
justify-content: center;
|
||||
height: 30rpx;
|
||||
width: 40rpx;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
|
||||
.close {
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<text style="text-decoration:underline" :href="href" @click="openURL" :inWhiteList="inWhiteList">{{text}}</text>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* @description u-link是一个外部网页超链接组件,在小程序内打开内部web-view组件或复制url,在app内打开外部浏览器,在h5端打开新网页
|
||||
* @property {String} href 点击后打开的外部网页url,小程序中必须以https://开头
|
||||
* @property {String} text 显示的文字
|
||||
* @property {Boolean} inWhiteList 是否在小程序白名单中,如果在的话,在小程序端会直接打开内置web-view,否则会只会复制url,提示在外部打开
|
||||
* @example * <u-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn" :inWhiteList="true"></u-link>
|
||||
*/
|
||||
export default {
|
||||
name: 'u-link',
|
||||
props: {
|
||||
href: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
inWhiteList: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openURL() {
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(this.href) //这里默认使用外部浏览器打开而不是内部web-view组件打开
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
window.open(this.href)
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
if (this.inWhiteList) { //如果在小程序的网址白名单中,会走内置webview打开,否则会复制网址提示在外部浏览器打开
|
||||
uni.navigateTo({
|
||||
url: '/pages/component/web-view/web-view?url=' + this.href
|
||||
});
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: this.href
|
||||
});
|
||||
uni.showModal({
|
||||
content: '本网址无法直接在小程序内打开。已自动复制网址,请在手机浏览器里粘贴该网址',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
|
||||
<title>点击显示小点</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
background-color: aqua;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: red;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
<script type="text/javascript" src="https://doc.dcloud.net.cn/uni.webview.1.5.6.js"></script>
|
||||
<script>
|
||||
document.addEventListener('click', function(e) {
|
||||
const {
|
||||
clientX,
|
||||
clientY
|
||||
} = e
|
||||
uni.postMessage({
|
||||
data: {
|
||||
action: 'click',
|
||||
clientX,
|
||||
clientY
|
||||
}
|
||||
});
|
||||
const dot = document.createElement('div');
|
||||
dot.className = 'dot';
|
||||
dot.style.left = `${clientX - 4}px`;
|
||||
dot.style.top = `${clientY - 4}px`;
|
||||
document.body.appendChild(dot);
|
||||
setTimeout(() => {
|
||||
dot.remove();
|
||||
}, 500); // 显示 500 毫秒后消失
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>本地网页</title>
|
||||
<style type="text/css">
|
||||
.btn {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
padding: 5px;
|
||||
background-color: #007aff;
|
||||
border: 0;
|
||||
color: #ffffff;
|
||||
height: 40px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.btn-red {
|
||||
background-color: #dd524d;
|
||||
}
|
||||
|
||||
.btn-yellow {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
|
||||
.desc {
|
||||
padding: 10px;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p class="desc">web-view 组件加载本地 html 示例,仅在 App 环境下生效。点击下列按钮,跳转至其它页面。</p>
|
||||
<div class="btn-list">
|
||||
<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
|
||||
<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
|
||||
<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
|
||||
<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
|
||||
<button class="btn" type="button" data-action="switchTab">switchTab</button>
|
||||
</div>
|
||||
<p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p>
|
||||
<div class="btn-list">
|
||||
<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
|
||||
</div>
|
||||
<!-- uni 的 SDK -->
|
||||
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('UniAppJSBridgeReady', function() {
|
||||
document.querySelector('.btn-list').addEventListener('click', function(evt) {
|
||||
var target = evt.target;
|
||||
if (target.tagName === 'BUTTON') {
|
||||
var action = target.getAttribute('data-action');
|
||||
switch (action) {
|
||||
case 'switchTab':
|
||||
uni.switchTab({
|
||||
url: '/pages/tabBar/API/API'
|
||||
});
|
||||
break;
|
||||
case 'reLaunch':
|
||||
uni.reLaunch({
|
||||
url: '/pages/tabBar/API/API'
|
||||
});
|
||||
break;
|
||||
case 'navigateBack':
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
break;
|
||||
default:
|
||||
uni[action]({
|
||||
url: '/pages/component/button/button'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
document.querySelector("#postMessage").addEventListener('click', function() {
|
||||
uni.postMessage({
|
||||
data: {
|
||||
action: 'message'
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<script src="/static/web/image-resize-3.0.1.min.js"></script>
|
||||
<script src="/static/web/quill-1.3.7.min.js"></script>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
module.exports = {
|
||||
testTimeout: 20000,
|
||||
reporters: [
|
||||
'default'
|
||||
],
|
||||
watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
|
||||
moduleFileExtensions: ['js', 'json'],
|
||||
rootDir: __dirname,
|
||||
testMatch: ["<rootDir>/pages/**/*test.[jt]s?(x)"],
|
||||
testPathIgnorePatterns: ['/node_modules/']
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import App from './App'
|
||||
import store from './store'
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
Vue.prototype.$adpid = "1111111111"
|
||||
Vue.prototype.$backgroundAudioData = {
|
||||
playing: false,
|
||||
playTime: 0,
|
||||
formatedPlayTime: '00:00:00'
|
||||
}
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
store,
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
} from 'vue'
|
||||
import * as Pinia from 'pinia';
|
||||
import Vuex from "vuex";
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(store)
|
||||
app.use(Pinia.createPinia());
|
||||
app.config.globalProperties.$adpid = "1111111111"
|
||||
app.config.globalProperties.$backgroundAudioData = {
|
||||
playing: false,
|
||||
playTime: 0,
|
||||
formatedPlayTime: '00:00:00'
|
||||
}
|
||||
return {
|
||||
app,
|
||||
Vuex, // 如果 nvue 使用 vuex 的各种map工具方法时,必须 return Vuex
|
||||
Pinia // 此处必须将 Pinia 返回
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
{
|
||||
"name" : "uniapp-demo-new",
|
||||
"appid" : "",
|
||||
"description" : "应用描述",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"nvueLaunchMode" : "fast",
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"modules" : {
|
||||
"OAuth" : {},
|
||||
"Payment" : {},
|
||||
"Push" : {},
|
||||
"Share" : {},
|
||||
"Speech" : {},
|
||||
"VideoPlayer" : {}
|
||||
},
|
||||
"distribute" : {
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
|
||||
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
|
||||
]
|
||||
},
|
||||
"ios" : {
|
||||
"UIBackgroundModes" : [ "audio" ],
|
||||
"urlschemewhitelist" : [ "baidumap", "iosamap" ]
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"speech" : {
|
||||
"ifly" : {}
|
||||
}
|
||||
},
|
||||
"orientation" : [ "portrait-primary" ]
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"quickapp" : {},
|
||||
"quickapp-native" : {
|
||||
"icon" : "/static/logo.png",
|
||||
"package" : "com.example.demo",
|
||||
"features" : [
|
||||
{
|
||||
"name" : "system.clipboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"quickapp-webview" : {
|
||||
"icon" : "/static/logo.png",
|
||||
"package" : "com.example.demo",
|
||||
"minPlatformVersion" : 1070,
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : 100
|
||||
},
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"permission" : {
|
||||
"scope.userLocation" : {
|
||||
"desc" : "演示定位能力"
|
||||
}
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
},
|
||||
"dynamicLib" : {
|
||||
"editorLib" : {
|
||||
"provider" : "swan-editor"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-jd" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"h5" : {
|
||||
"template" : "template.h5.html",
|
||||
"router" : {
|
||||
"mode" : "history",
|
||||
"base" : ""
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"maps" : {
|
||||
"qqmap" : {
|
||||
"key" : "TKUBZ-D24AF-GJ4JY-JDVM2-IBYKK-KEBCU"
|
||||
}
|
||||
}
|
||||
},
|
||||
"async" : {
|
||||
"timeout" : 20000
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"vueVersion" : "3",
|
||||
"mp-kuaishou" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-lark" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-qq" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"quickapp-webview-huawei" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"quickapp-webview-union" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"version" : "2",
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"id": "hello-uniapp",
|
||||
"name": "hello-uniapp",
|
||||
"displayName": "hello-uniapp 示例工程",
|
||||
"version": "3.4.9",
|
||||
"description": "uni-app 框架示例,一套代码,同时发行到iOS、Android、H5、小程序等多个平台,请使用手机扫码快速体验 uni-app 的强大功能",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": "https://github.com/dcloudio/hello-uniapp.git",
|
||||
"keywords": [
|
||||
"hello-uniapp",
|
||||
"uni-app",
|
||||
"uni-ui",
|
||||
"示例工程"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/dcloudio/hello-uniapp/issues"
|
||||
},
|
||||
"homepage": "https://github.com/dcloudio/hello-uniapp#readme",
|
||||
"dependencies": {},
|
||||
"dcloudext": {
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "",
|
||||
"type": "uniapp-template-project",
|
||||
"darkmode": "x",
|
||||
"i18n": "x",
|
||||
"widescreen": "x"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "√",
|
||||
"aliyun": "√",
|
||||
"alipay": "x"
|
||||
},
|
||||
"client": {
|
||||
"uni-app": {
|
||||
"vue": {
|
||||
"vue2": "√",
|
||||
"vue3": "√"
|
||||
},
|
||||
"web": {
|
||||
"safari": "√",
|
||||
"chrome": "√"
|
||||
},
|
||||
"app": {
|
||||
"vue": "√",
|
||||
"nvue": "√",
|
||||
"android": "√",
|
||||
"ios": "√",
|
||||
"harmony": "√"
|
||||
},
|
||||
"mp": {
|
||||
"weixin": "√",
|
||||
"alipay": "√",
|
||||
"toutiao": "√",
|
||||
"baidu": "√",
|
||||
"kuaishou": "√",
|
||||
"jd": "√",
|
||||
"harmony": "√",
|
||||
"qq": "√",
|
||||
"lark": "√"
|
||||
},
|
||||
"quickapp": {
|
||||
"huawei": "-",
|
||||
"union": "-"
|
||||
}
|
||||
},
|
||||
"uni-app-x": {
|
||||
"web": {
|
||||
"safari": "-",
|
||||
"chrome": "-"
|
||||
},
|
||||
"app": {
|
||||
"android": "-",
|
||||
"ios": "-",
|
||||
"harmony": "-"
|
||||
},
|
||||
"mp": {
|
||||
"weixin": "-"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"uni-app": {
|
||||
"scripts": {
|
||||
"mp-dingtalk": {
|
||||
"title": "钉钉小程序",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "mp-alipay"
|
||||
},
|
||||
"define": {
|
||||
"MP-DINGTALK": true
|
||||
}
|
||||
},
|
||||
"hello-uniapp-demo": {
|
||||
"title": "hello-uniapp 演示网站",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "h5"
|
||||
},
|
||||
"define": {
|
||||
"H5-DEMO": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0",
|
||||
"uni-app": "^4.03",
|
||||
"uni-app-x": ""
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button class="target" type="default" @tap="actionSheetTap">弹出action sheet</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'action-sheet',
|
||||
buttonRect: {}
|
||||
}
|
||||
},
|
||||
// #ifdef H5
|
||||
onReady() {
|
||||
this.getNodeInfo()
|
||||
window.addEventListener('resize', this.getNodeInfo)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.getNodeInfo)
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
actionSheetTap() {
|
||||
const that = this
|
||||
uni.showActionSheet({
|
||||
title: '标题',
|
||||
itemList: ['item1', 'item2', 'item3', 'item4'],
|
||||
popover: {
|
||||
// 104: navbar + topwindow 高度,暂时 fix createSelectorQuery 在 pc 上获取 top 不准确的 bug
|
||||
top: that.buttonRect.top + 104 + that.buttonRect.height,
|
||||
left: that.buttonRect.left + that.buttonRect.width / 2
|
||||
},
|
||||
success: (e) => {
|
||||
console.log(e.tapIndex);
|
||||
uni.showToast({
|
||||
title: "点击了第" + e.tapIndex + "个选项",
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// #ifdef H5
|
||||
getNodeInfo() {
|
||||
uni.createSelectorQuery().select('.target').boundingClientRect().exec((ret) => {
|
||||
const rect = ret[0]
|
||||
if (rect) {
|
||||
this.buttonRect = rect
|
||||
}
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">名称</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入联系人名称" name="name" :value="name" @input="nameChange"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">手机号</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入联系人手机号" name="phone" :value="phone" @input="phoneChange"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" class="btn-setstorage" @tap="add">添加联系人</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
import permision from "@/common/permission.js"
|
||||
// #endif
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'addPhoneContact',
|
||||
name: '',
|
||||
phone: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
nameChange: function(e) {
|
||||
this.name = e.detail.value
|
||||
},
|
||||
phoneChange: function(e) {
|
||||
this.phone = e.detail.value
|
||||
},
|
||||
async add() {
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
|
||||
uni.addPhoneContact({
|
||||
firstName: this.name,
|
||||
mobilePhoneNumber: this.phone,
|
||||
success: function() {
|
||||
uni.showModal({
|
||||
content: '已成功添加联系人!',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
fail: function() {
|
||||
uni.showModal({
|
||||
content: '添加联系人失败!',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
,
|
||||
async checkPermission() {
|
||||
let status = permision.isIOS ? await permision.requestIOS('contact') :
|
||||
await permision.requestAndroid('android.permission.WRITE_CONTACTS');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要联系人权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return status;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="animation-element-wrapper">
|
||||
<view class="animation-element" :animation="animationData"></view>
|
||||
</view>
|
||||
<scroll-view class="animation-buttons" scroll-y="true">
|
||||
<button class="animation-button" @tap="rotate">旋转</button>
|
||||
<button class="animation-button" @tap="scale">缩放</button>
|
||||
<button class="animation-button" @tap="translate">移动</button>
|
||||
<button class="animation-button" @tap="skew">倾斜</button>
|
||||
<button class="animation-button" @tap="rotateAndScale">旋转并缩放</button>
|
||||
<button class="animation-button" @tap="rotateThenScale">旋转后缩放</button>
|
||||
<button class="animation-button" @tap="all">同时展示全部</button>
|
||||
<button class="animation-button" @tap="allInQueue">顺序展示全部</button>
|
||||
<button class="animation-button animation-button-reset" @tap="reset">还原</button>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'createAnimation',
|
||||
animationData: ''
|
||||
}
|
||||
},
|
||||
onUnload(){
|
||||
this.animationData = ''
|
||||
},
|
||||
onLoad() {
|
||||
this.animation = uni.createAnimation()
|
||||
},
|
||||
methods: {
|
||||
rotate: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
scale: function () {
|
||||
this.animation.scale(Math.random() * 2).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
translate: function () {
|
||||
this.animation.translate(Math.random() * 100 - 50, Math.random() * 100 - 50).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
skew: function () {
|
||||
this.animation.skew(Math.random() * 90, Math.random() * 90).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
rotateAndScale: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360)
|
||||
.scale(Math.random() * 2)
|
||||
.step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
rotateThenScale: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360).step()
|
||||
.scale(Math.random() * 2).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
all: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360)
|
||||
.scale(Math.random() * 2)
|
||||
.translate(Math.random() * 100 - 50, Math.random() * 100 - 50)
|
||||
.skew(Math.random() * 90, Math.random() * 90)
|
||||
.step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
allInQueue: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360).step()
|
||||
.scale(Math.random() * 2).step()
|
||||
.translate(Math.random() * 100 - 50, Math.random() * 100 - 50).step()
|
||||
.skew(Math.random() * 90, Math.random() * 90).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
reset: function () {
|
||||
this.animation.rotate(0, 0)
|
||||
.scale(1)
|
||||
.translate(0, 0)
|
||||
.skew(0, 0)
|
||||
.step({
|
||||
duration: 0
|
||||
})
|
||||
this.animationData = this.animation.export()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.animation-element-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-top: 150rpx;
|
||||
padding-bottom: 150rpx;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.animation-element {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background-color: #1AAD19;
|
||||
}
|
||||
|
||||
.animation-buttons {
|
||||
padding:30rpx 0;
|
||||
width: 100%;
|
||||
/* height: 360rpx; */
|
||||
}
|
||||
|
||||
.animation-button {
|
||||
float: left;
|
||||
width: 44%;
|
||||
margin: 15rpx 3%;
|
||||
}
|
||||
|
||||
.animation-button-reset {
|
||||
width: 94%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-center">
|
||||
<text class="time-big">{{formatedPlayTime}}</text>
|
||||
</view>
|
||||
<view class="uni-common-mt">
|
||||
<slider class="slider" min="0" max="21" step="1" :value="playTime" @change="seek"></slider>
|
||||
</view>
|
||||
<view class="play-time">
|
||||
<text>00:00</text>
|
||||
<text>00:21</text>
|
||||
</view>
|
||||
<view class="uni-hello-text">注意:离开当前页面后背景音乐将保持播放,但退出uni-app将停止</view>
|
||||
<view class="page-body-buttons">
|
||||
<block v-if="playing">
|
||||
<view class="page-body-button" @tap="stop">
|
||||
<image src="/static/stop.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button" @tap="pause">
|
||||
<image src="/static/pause.png"></image>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="!playing">
|
||||
<view class="page-body-button"></view>
|
||||
<view class="page-body-button" @tap="play">
|
||||
<image src="/static/play.png"></image>
|
||||
</view>
|
||||
</block>
|
||||
<view class="page-body-button"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import * as util from '../../../common/util.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'backgroundAudio',
|
||||
bgAudioMannager: null,
|
||||
dataUrl: 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3',
|
||||
playing: false,
|
||||
playTime: 0,
|
||||
formatedPlayTime: '00:00:00'
|
||||
}
|
||||
},
|
||||
onLoad: function () {
|
||||
this.playing = this.$backgroundAudioData.playing;
|
||||
this.playTime = this.$backgroundAudioData.playTime;
|
||||
this.formatedPlayTime = this.$backgroundAudioData.formatedPlayTime;
|
||||
|
||||
let bgAudioMannager = uni.getBackgroundAudioManager();
|
||||
if(!bgAudioMannager.title){
|
||||
bgAudioMannager.title = '致爱丽丝';
|
||||
}
|
||||
if(!bgAudioMannager.singer) {
|
||||
bgAudioMannager.singer = '暂无';
|
||||
}
|
||||
if(!bgAudioMannager.coverImgUrl){
|
||||
bgAudioMannager.coverImgUrl = 'https://web-assets.dcloud.net.cn/unidoc/zh/Alice.jpeg';
|
||||
}
|
||||
|
||||
bgAudioMannager.onPlay(() => {
|
||||
console.log("开始播放");
|
||||
this.$backgroundAudioData.playing = this.playing = true;
|
||||
})
|
||||
bgAudioMannager.onPause(() => {
|
||||
console.log("暂停播放");
|
||||
this.$backgroundAudioData.playing = this.playing = false;
|
||||
})
|
||||
bgAudioMannager.onEnded(() => {
|
||||
this.playing = false;
|
||||
this.$backgroundAudioData.playing = false;
|
||||
this.$backgroundAudioData.playTime = this.playTime = 0;
|
||||
this.$backgroundAudioData.formatedPlayTime = this.formatedPlayTime = util.formatTime(0);
|
||||
})
|
||||
|
||||
bgAudioMannager.onTimeUpdate((e) => {
|
||||
if (Math.floor(bgAudioMannager.currentTime) > Math.floor(this.playTime)) {
|
||||
this.$backgroundAudioData.formatedPlayTime = this.formatedPlayTime = util.formatTime(Math.floor(bgAudioMannager.currentTime));
|
||||
}
|
||||
this.$backgroundAudioData.playTime = this.playTime = bgAudioMannager.currentTime;
|
||||
})
|
||||
|
||||
this.bgAudioMannager = bgAudioMannager;
|
||||
},
|
||||
methods: {
|
||||
play: function (res) {
|
||||
if (!this.bgAudioMannager.src) {
|
||||
this.bgAudioMannager.startTime = this.playTime;
|
||||
this.bgAudioMannager.src = this.dataUrl;
|
||||
} else {
|
||||
this.bgAudioMannager.seek(this.playTime);
|
||||
this.bgAudioMannager.play();
|
||||
}
|
||||
},
|
||||
seek: function (e) {
|
||||
this.bgAudioMannager.seek(e.detail.value);
|
||||
},
|
||||
pause: function () {
|
||||
this.bgAudioMannager.pause();
|
||||
},
|
||||
stop: function () {
|
||||
this.bgAudioMannager.stop();
|
||||
this.$backgroundAudioData.playing = this.playing = false;
|
||||
this.$backgroundAudioData.playTime = this.playTime = 0;
|
||||
this.$backgroundAudioData.formatedPlayTime = this.formatedPlayTime = util.formatTime(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
image {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.page-body-text {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.page-body-wrapper {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.page-body-info {
|
||||
padding-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.time-big {
|
||||
font-size: 60rpx;
|
||||
margin: 20rpx;
|
||||
}
|
||||
|
||||
.slider {
|
||||
width:630rpx;
|
||||
}
|
||||
|
||||
.play-time {
|
||||
font-size: 28rpx;
|
||||
width:100%;
|
||||
padding: 20rpx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-body-buttons {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-top: 100rpx;
|
||||
}
|
||||
|
||||
.page-body-button {
|
||||
width: 250rpx;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,723 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view>
|
||||
本蓝牙协议只支持低功耗蓝牙协议ble。如果想连接非ble蓝牙设备,请在社区搜索 Native.js 蓝牙。
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" :disabled="disabled[0]" @click="openBluetoothAdapter">
|
||||
初始化蓝牙模块
|
||||
</button>
|
||||
<view v-if="!adapterState.available">
|
||||
{{ '蓝牙适配器不可用,请初始化蓝牙模块' }}
|
||||
</view>
|
||||
<button
|
||||
type="primary"
|
||||
:loading="searchLoad"
|
||||
:disabled="disabled[1]"
|
||||
@click="startBluetoothDevicesDiscovery"
|
||||
>
|
||||
开始搜索蓝牙设备
|
||||
</button>
|
||||
<button
|
||||
type="primary"
|
||||
:disabled="disabled[2]"
|
||||
@click="stopBluetoothDevicesDiscovery(false)"
|
||||
>
|
||||
停止搜索蓝牙设备
|
||||
</button>
|
||||
<button
|
||||
type="primary"
|
||||
:loading="newDeviceLoad"
|
||||
:disabled="disabled[3]"
|
||||
@click="queryDevices"
|
||||
>
|
||||
选择设备
|
||||
</button>
|
||||
<view v-if="equipment.length > 0">
|
||||
{{
|
||||
(connected ? '已连接设备' : '已选择设备') +
|
||||
' : ' +
|
||||
equipment[0].name +
|
||||
' (' +
|
||||
equipment[0].deviceId +
|
||||
')'
|
||||
}}
|
||||
</view>
|
||||
<button type="primary" :disabled="disabled[4]" @click="createBLEConnection">
|
||||
连接蓝牙设备
|
||||
</button>
|
||||
<button type="primary" :disabled="disabled[5]" @click="getBLEDeviceServices">
|
||||
选择设备服务
|
||||
</button>
|
||||
<view v-if="servicesData.length > 0">已选服务uuid:{{ servicesData[0].uuid }}</view>
|
||||
<button type="primary" :disabled="disabled[6]" @click="getBLEDeviceCharacteristics">
|
||||
获取服务的特征值
|
||||
</button>
|
||||
<view v-if="characteristicsData.length > 0">
|
||||
<view class="uni-list_name">uuid:{{ characteristicsData[0].uuid }}</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 read 操作:{{ characteristicsData[0].properties.read }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 write 操作:{{ characteristicsData[0].properties.write }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 notify 操作:{{ characteristicsData[0].properties.notify }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 indicate 操作:{{ characteristicsData[0].properties.indicate }}
|
||||
</view>
|
||||
</view>
|
||||
<!-- <button type="primary" :disabled="disabled[7]" @click="readBLECharacteristicValue">
|
||||
读取特征值数据
|
||||
</button>
|
||||
<view v-if="valueChangeData.serviceId">
|
||||
<view class="list-name">
|
||||
特征值最新的值:{{ valueChangeData.value || '还没有最新值' }}
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- <button type="primary" :disabled="disabled[8]" @click="w">写入特征值数据</button> -->
|
||||
<button type="primary" :disabled="disabled[9]" @click="closeBLEConnection">
|
||||
断开蓝牙设备
|
||||
</button>
|
||||
<button type="primary" :disabled="disabled[10]" @click="closeBluetoothAdapter">
|
||||
关闭蓝牙模块
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 遮罩 -->
|
||||
<view v-if="maskShow" class="uni-mask" @touchmove.stop.prevent="moveHandle" @click="maskclose">
|
||||
<scroll-view class="uni-scroll_box" scroll-y @touchmove.stop.prevent="moveHandle" @click.stop="moveHandle">
|
||||
<view class="uni-title">
|
||||
已经发现{{ list.length }}{{ showMaskType === 'device' ? '台设备' : '个服务' }}:
|
||||
</view>
|
||||
<view
|
||||
class="uni-list-box"
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
@click="tapQuery(item)"
|
||||
>
|
||||
<view v-if="showMaskType === 'device'">
|
||||
<view class="uni-list_name">{{ item.name || item.localName }}</view>
|
||||
<view class="uni-list_item">信号强度:{{ item.RSSI }}dBm</view>
|
||||
<view class="uni-list_item">UUID:{{ item.deviceId }}</view>
|
||||
<!-- <view class="list-item" v-if="showMaskType === 'device'">
|
||||
Service数量:{{ item.advertisServiceUUIDs.length }}
|
||||
</view> -->
|
||||
</view>
|
||||
<view v-if="showMaskType === 'service'">
|
||||
<view class="uni-list_item" style="line-height:2.2;">
|
||||
UUID: {{ item.uuid }}
|
||||
<text v-if="showMaskType === 'service'">
|
||||
{{ item.isPrimary ? '(主服务)' : '' }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="showMaskType === 'characteristics'">
|
||||
<view class="uni-list_name">uuid:{{ item.uuid }}</view>
|
||||
<view class="uni-list_item">是否支持 read 操作:{{ item.properties.read }}</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 write 操作:{{ item.properties.write }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 notify 操作:{{ item.properties.notify }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 indicate 操作:{{ item.properties.indicate }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'bluetooth',
|
||||
disabled: [false, true, true, true, true, true, true, true, true, true, true],
|
||||
newDeviceLoad: false,
|
||||
searchLoad: false,
|
||||
maskShow: false,
|
||||
equipment: [],
|
||||
adapterState: {
|
||||
discovering: false,
|
||||
available: false
|
||||
},
|
||||
connected: false,
|
||||
showMaskType: 'device',
|
||||
servicesData: [],
|
||||
characteristicsData: [],
|
||||
valueChangeData: {},
|
||||
isStop:true ,
|
||||
list: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.onBLEConnectionStateChange();
|
||||
},
|
||||
methods: {
|
||||
moveHandle() {},
|
||||
/**
|
||||
* 关闭遮罩
|
||||
*/
|
||||
maskclose(){
|
||||
this.maskShow = false;
|
||||
},
|
||||
/**
|
||||
* 选择设备
|
||||
*/
|
||||
queryDevices() {
|
||||
// this.newDeviceLoad = true;
|
||||
this.showMaskType = 'device';
|
||||
this.maskShow = true;
|
||||
},
|
||||
tapQuery(item) {
|
||||
if (this.showMaskType === 'device') {
|
||||
this.$set(this.disabled, 4, false);
|
||||
if (this.equipment.length > 0) {
|
||||
this.equipment[0] = item;
|
||||
} else {
|
||||
this.equipment.push(item);
|
||||
}
|
||||
this.newDeviceLoad = false;
|
||||
}
|
||||
if (this.showMaskType === 'service') {
|
||||
this.$set(this.disabled, 6, false);
|
||||
if (this.servicesData.length > 0) {
|
||||
this.servicesData[0] = item;
|
||||
} else {
|
||||
this.servicesData.push(item);
|
||||
}
|
||||
}
|
||||
if (this.showMaskType === 'characteristics') {
|
||||
this.$set(this.disabled, 7, false);
|
||||
if (this.characteristicsData.length > 0) {
|
||||
this.characteristicsData[0] = item;
|
||||
} else {
|
||||
this.characteristicsData.push(item);
|
||||
}
|
||||
}
|
||||
this.maskShow = false;
|
||||
},
|
||||
/**
|
||||
* 初始化蓝牙设备
|
||||
*/
|
||||
openBluetoothAdapter() {
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
console.log('初始化蓝牙成功:' + e.errMsg);
|
||||
console.log(JSON.stringify(e));
|
||||
this.isStop = false ;
|
||||
this.$set(this.disabled, 0, true);
|
||||
this.$set(this.disabled, 1, false);
|
||||
this.$set(this.disabled, 10, false);
|
||||
this.getBluetoothAdapterState();
|
||||
},
|
||||
fail: e => {
|
||||
console.log(e)
|
||||
console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg));
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode,e.errMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 开始搜索蓝牙设备
|
||||
*/
|
||||
startBluetoothDevicesDiscovery() {
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log('开始搜索蓝牙设备:' + e.errMsg);
|
||||
this.searchLoad = true;
|
||||
this.$set(this.disabled, 1, true);
|
||||
this.$set(this.disabled, 2, false);
|
||||
this.$set(this.disabled, 3, false);
|
||||
this.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: e => {
|
||||
console.log('搜索蓝牙设备失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery(types) {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log('停止搜索蓝牙设备:' + e.errMsg);
|
||||
if (types) {
|
||||
this.$set(this.disabled, 1, true);
|
||||
} else {
|
||||
this.$set(this.disabled, 1, false);
|
||||
}
|
||||
this.$set(this.disabled, 2, true);
|
||||
// this.$set(this.disabled, 3, true);
|
||||
this.searchLoad = false;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
uni.onBluetoothDeviceFound(devices => {
|
||||
console.log('开始监听寻找到新设备的事件');
|
||||
// this.$set(this.disabled, 3, false);
|
||||
this.getBluetoothDevices();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
|
||||
*/
|
||||
getBluetoothDevices() {
|
||||
uni.getBluetoothDevices({
|
||||
success: res => {
|
||||
this.newDeviceLoad = false;
|
||||
console.log('获取蓝牙设备成功:' + res.errMsg);
|
||||
// console.log(JSON.stringify(res))
|
||||
this.list = res.devices;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取蓝牙设备错误,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取本机蓝牙适配器状态
|
||||
*/
|
||||
getBluetoothAdapterState() {
|
||||
console.log('--->');
|
||||
uni.getBluetoothAdapterState({
|
||||
success: res => {
|
||||
console.log(JSON.stringify(res));
|
||||
this.adapterState = res;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取本机蓝牙适配器状态失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 连接低功耗蓝牙
|
||||
*/
|
||||
createBLEConnection() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
uni.showToast({
|
||||
title: '连接蓝牙...',
|
||||
icon: 'loading',
|
||||
duration: 99999
|
||||
});
|
||||
uni.createBLEConnection({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
success: res => {
|
||||
console.log(res);
|
||||
console.log('连接蓝牙成功:' + res.errMsg);
|
||||
// 连接设备后断开搜索 并且不能搜索设备
|
||||
this.stopBluetoothDevicesDiscovery(true);
|
||||
uni.hideToast();
|
||||
uni.showToast({
|
||||
title: '连接成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, false);
|
||||
this.$set(this.disabled, 9, false);
|
||||
this.connected = true;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('连接低功耗蓝牙失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 断开与低功耗蓝牙设备的连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
uni.closeBLEConnection({
|
||||
deviceId,
|
||||
success: res => {
|
||||
console.log(res);
|
||||
console.log('断开低功耗蓝牙成功:' + res.errMsg);
|
||||
this.$set(this.disabled, 1, false);
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, true);
|
||||
this.$set(this.disabled, 6, true);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.$set(this.disabled, 9, true);
|
||||
this.equipment = [];
|
||||
this.servicesData = [];
|
||||
this.characteristicsData = [];
|
||||
},
|
||||
fail: e => {
|
||||
console.log('断开低功耗蓝牙成功,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取所有服务
|
||||
*/
|
||||
getBLEDeviceServices() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
console.log('获取所有服务的 uuid:' + deviceId);
|
||||
|
||||
uni.getBLEDeviceServices({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
success: res => {
|
||||
console.log(JSON.stringify(res.services));
|
||||
console.log('获取设备服务成功:' + res.errMsg);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.showMaskType = 'service';
|
||||
this.list = res.services;
|
||||
|
||||
this.characteristicsData = [];
|
||||
if (this.list.length <= 0) {
|
||||
toast('获取服务失败,请重试!');
|
||||
return;
|
||||
}
|
||||
this.maskShow = true;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取设备服务失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取某个服务下的所有特征值
|
||||
*/
|
||||
getBLEDeviceCharacteristics() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
let serviceId = this.servicesData[0].uuid;
|
||||
console.log(deviceId);
|
||||
console.log(serviceId);
|
||||
uni.getBLEDeviceCharacteristics({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||||
serviceId,
|
||||
success: res => {
|
||||
console.log(JSON.stringify(res));
|
||||
console.log('获取特征值成功:' + res.errMsg);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.valueChangeData = {};
|
||||
this.showMaskType = 'characteristics';
|
||||
this.list = res.characteristics;
|
||||
if (this.list.length <= 0) {
|
||||
toast('获取特征值失败,请重试!');
|
||||
return;
|
||||
}
|
||||
this.maskShow = true;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取特征值失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
|
||||
*/
|
||||
onBLEConnectionStateChange() {
|
||||
uni.onBLEConnectionStateChange(res => {
|
||||
// 该方法回调中可以用于处理连接意外断开等异常情况
|
||||
console.log(`蓝牙连接状态 -------------------------->`);
|
||||
console.log(JSON.stringify(res));
|
||||
if (!res.connected) {
|
||||
if(this.isStop) return ;
|
||||
console.log('断开低功耗蓝牙成功:');
|
||||
this.$set(this.disabled, 1, false);
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, true);
|
||||
this.$set(this.disabled, 6, true);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.$set(this.disabled, 9, true);
|
||||
this.searchLoad = false;
|
||||
this.equipment = [];
|
||||
this.servicesData = [];
|
||||
this.characteristicsData = [];
|
||||
this.valueChangeData = {};
|
||||
toast('已经断开当前蓝牙连接');
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 读取低功耗蓝牙设备的特征值的二进制数据值。注意:必须设备的特征值支持 read 才可以成功调用
|
||||
*/
|
||||
readBLECharacteristicValue() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
let serviceId = this.servicesData[0].uuid;
|
||||
let characteristicId = this.characteristicsData[0].uuid;
|
||||
console.log(deviceId);
|
||||
console.log(serviceId);
|
||||
console.log(characteristicId);
|
||||
uni.readBLECharacteristicValue({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||||
serviceId,
|
||||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||||
characteristicId,
|
||||
success: res => {
|
||||
console.log('读取设备数据值成功');
|
||||
console.log(JSON.stringify(res));
|
||||
this.notifyBLECharacteristicValueChange();
|
||||
},
|
||||
fail(e) {
|
||||
console.log('读取设备数据值失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.onBLECharacteristicValueChange();
|
||||
},
|
||||
/**
|
||||
* 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
|
||||
*/
|
||||
onBLECharacteristicValueChange() {
|
||||
// 必须在这里的回调才能获取
|
||||
uni.onBLECharacteristicValueChange(characteristic => {
|
||||
console.log('监听低功耗蓝牙设备的特征值变化事件成功');
|
||||
console.log(JSON.stringify(characteristic));
|
||||
this.valueChangeData = characteristic;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。
|
||||
*/
|
||||
notifyBLECharacteristicValueChange() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
let serviceId = this.servicesData[0].uuid;
|
||||
let characteristicId = this.characteristicsData[0].uuid;
|
||||
let notify = this.characteristicsData[0].properties.notify;
|
||||
console.log(deviceId);
|
||||
console.log(serviceId);
|
||||
console.log(characteristicId);
|
||||
console.log(notify);
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
state: true, // 启用 notify 功能
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||||
serviceId,
|
||||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||||
characteristicId,
|
||||
success(res) {
|
||||
console.log('notifyBLECharacteristicValueChange success:' + res.errMsg);
|
||||
console.log(JSON.stringify(res));
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter(OBJECT) {
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('断开蓝牙模块成功');
|
||||
this.isStop = true ;
|
||||
this.$set(this.disabled, 0, false);
|
||||
this.$set(this.disabled, 1, true);
|
||||
this.$set(this.disabled, 2, true);
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, true);
|
||||
this.$set(this.disabled, 6, true);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.$set(this.disabled, 9, true);
|
||||
this.$set(this.disabled, 10, true);
|
||||
this.equipment = [];
|
||||
this.servicesData = [];
|
||||
this.characteristicsData = [];
|
||||
this.valueChangeData = {};
|
||||
this.adapterState = [];
|
||||
this.searchLoad =false;
|
||||
toast('断开蓝牙模块');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断初始化蓝牙状态
|
||||
*/
|
||||
function initTypes(code, errMsg) {
|
||||
switch (code) {
|
||||
case 10000:
|
||||
toast('未初始化蓝牙适配器');
|
||||
break;
|
||||
case 10001:
|
||||
toast('未检测到蓝牙,请打开蓝牙重试!');
|
||||
break;
|
||||
case 10002:
|
||||
toast('没有找到指定设备');
|
||||
break;
|
||||
case 10003:
|
||||
toast('连接失败');
|
||||
break;
|
||||
case 10004:
|
||||
toast('没有找到指定服务');
|
||||
break;
|
||||
case 10005:
|
||||
toast('没有找到指定特征值');
|
||||
break;
|
||||
case 10006:
|
||||
toast('当前连接已断开');
|
||||
break;
|
||||
case 10007:
|
||||
toast('当前特征值不支持此操作');
|
||||
break;
|
||||
case 10008:
|
||||
toast('其余所有系统上报的异常');
|
||||
break;
|
||||
case 10009:
|
||||
toast('Android 系统特有,系统版本低于 4.3 不支持 BLE');
|
||||
break;
|
||||
default:
|
||||
toast(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框封装
|
||||
*/
|
||||
function toast(content, showCancel = false) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content,
|
||||
showCancel
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.uni-title {
|
||||
/* width: 100%; */
|
||||
/* height: 80rpx; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uni-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-scroll_box {
|
||||
height: 70%;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.uni-list-box {
|
||||
margin: 0 20rpx;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.uni-list:last-child {
|
||||
border: none;
|
||||
}
|
||||
.uni-list_name {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
.uni-list_item {
|
||||
font-size: 24rpx;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.uni-success_box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
min-height: 100rpx;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px #eee solid;
|
||||
}
|
||||
.uni-success_sub {
|
||||
/* width: 100%%; */
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
.uni-close_button {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: #ce3c39;
|
||||
color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.uni-success_content {
|
||||
height: 600rpx;
|
||||
margin: 30rpx;
|
||||
margin-top: 0;
|
||||
border: 1px #eee solid;
|
||||
padding: 30rpx;
|
||||
}
|
||||
.uni-content_list {
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
}
|
||||
.uni-tips {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<!-- #ifndef MP-TOUTIAO -->
|
||||
<view class="text-box">亮度 : {{ screen }}</view>
|
||||
<view class="uni-slider"><slider :value="screen" @changing="sliderChange" step="1" /></view>
|
||||
<!-- #endif -->
|
||||
<button type="primary" @click="keep">
|
||||
{{ keepScreenOn ? '保持常亮状态' : '关闭常亮状态' }}
|
||||
</button>
|
||||
<view class="tips">
|
||||
保持常亮时,屏幕不会熄灭。仅在当前应用生效,离开应用后设置失效。
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'brightness',
|
||||
screen: 0,
|
||||
keepScreenOn: true
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
uni.getScreenBrightness({
|
||||
success: res => {
|
||||
this.screen = (res.value * 100).toFixed();
|
||||
},
|
||||
fail(e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
sliderChange(e) {
|
||||
let screen = e.detail.value;
|
||||
// 判断是否重复
|
||||
if (this.screen !== screen) {
|
||||
console.log('当前数值:' + e.detail.value);
|
||||
uni.setScreenBrightness({
|
||||
value: screen / 100,
|
||||
success: function() {
|
||||
},
|
||||
fail(e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
this.screen = screen;
|
||||
}
|
||||
},
|
||||
keep() {
|
||||
uni.setKeepScreenOn({
|
||||
keepScreenOn: this.keepScreenOn
|
||||
});
|
||||
this.keepScreenOn = !this.keepScreenOn;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.text-box {
|
||||
margin-bottom: 40rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300rpx;
|
||||
background-color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
color: #353535;
|
||||
}
|
||||
|
||||
.uni-slider {
|
||||
margin: 100rpx 0;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
margin-top: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<canvas class="canvas-element" canvas-id="canvas" id="canvas"></canvas>
|
||||
<scroll-view class="canvas-buttons" scroll-y="true">
|
||||
<block v-for="(name, index) in names" :key="index">
|
||||
<button class="canvas-button" @click="handleCanvasButton(name)">{{name}}</button>
|
||||
</block>
|
||||
<button class="canvas-button" @click="toTempFilePath" type="primary">toTempFilePath</button>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
var context = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'createContext',
|
||||
names: ["rotate", "scale", "reset", "translate", "save", "restore", "drawImage", "fillText", "fill",
|
||||
"stroke", "clearRect", "beginPath", "closePath", "moveTo", "lineTo", "rect", "arc",
|
||||
"quadraticCurveTo", "bezierCurveTo", "setFillStyle", "setStrokeStyle", "setGlobalAlpha",
|
||||
"setShadow", "setFontSize", "setLineCap", "setLineJoin", "setLineWidth", "setMiterLimit"
|
||||
]
|
||||
}
|
||||
},
|
||||
onReady: function() {
|
||||
context = uni.createCanvasContext('canvas',this)
|
||||
},
|
||||
methods: {
|
||||
toTempFilePath: function() {
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'canvas',
|
||||
success: function(res) {
|
||||
console.log(res.tempFilePath)
|
||||
},
|
||||
fail: function(err) {
|
||||
console.error(JSON.stringify(err))
|
||||
}
|
||||
})
|
||||
},
|
||||
handleCanvasButton: function(name) {
|
||||
this[name] && this[name]();
|
||||
},
|
||||
rotate: function() {
|
||||
context.beginPath()
|
||||
context.rotate(10 * Math.PI / 180)
|
||||
context.rect(225, 75, 20, 10)
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
scale: function() {
|
||||
context.beginPath()
|
||||
context.rect(25, 25, 50, 50)
|
||||
context.stroke()
|
||||
|
||||
context.scale(2, 2)
|
||||
|
||||
context.beginPath()
|
||||
context.rect(25, 25, 50, 50)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
reset: function() {
|
||||
context.beginPath()
|
||||
|
||||
context.setFillStyle('#000000')
|
||||
context.setStrokeStyle('#000000')
|
||||
context.setFontSize(10)
|
||||
context.setGlobalAlpha(1)
|
||||
context.setShadow(0, 0, 0, 'rgba(0, 0, 0, 0)')
|
||||
|
||||
context.setLineCap('butt')
|
||||
context.setLineJoin('miter')
|
||||
context.setLineWidth(1)
|
||||
context.setMiterLimit(10)
|
||||
context.draw()
|
||||
},
|
||||
translate: function() {
|
||||
context.beginPath()
|
||||
context.rect(10, 10, 100, 50)
|
||||
context.fill()
|
||||
|
||||
context.translate(70, 70)
|
||||
|
||||
context.beginPath()
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
save: function() {
|
||||
context.beginPath()
|
||||
context.setStrokeStyle('#00ff00')
|
||||
context.save()
|
||||
|
||||
context.scale(2, 2)
|
||||
context.setStrokeStyle('#ff0000')
|
||||
context.rect(0, 0, 100, 100)
|
||||
context.stroke()
|
||||
context.restore()
|
||||
|
||||
context.rect(0, 0, 50, 50)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
restore: function() {
|
||||
[3, 2, 1].forEach(function(item) {
|
||||
context.beginPath()
|
||||
context.save()
|
||||
context.scale(item, item)
|
||||
context.rect(10, 10, 100, 100)
|
||||
context.stroke()
|
||||
context.restore()
|
||||
});
|
||||
context.draw()
|
||||
},
|
||||
drawImage: function() {
|
||||
// #ifdef APP-PLUS
|
||||
context.drawImage('../../../static/app-plus/uni@2x.png', 0, 0)
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
context.drawImage('../../../static/uni.png', 0, 0)
|
||||
// #endif
|
||||
context.draw()
|
||||
},
|
||||
fillText: function() {
|
||||
context.setStrokeStyle('#ff0000')
|
||||
|
||||
context.beginPath()
|
||||
context.moveTo(0, 10)
|
||||
context.lineTo(300, 10)
|
||||
context.stroke()
|
||||
// context.save()
|
||||
// context.scale(1.5, 1.5)
|
||||
// context.translate(20, 20)
|
||||
context.setFontSize(10)
|
||||
context.fillText('Hello World', 0, 30)
|
||||
context.setFontSize(20)
|
||||
context.fillText('Hello World', 100, 30)
|
||||
|
||||
// context.restore()
|
||||
|
||||
context.beginPath()
|
||||
context.moveTo(0, 30)
|
||||
context.lineTo(300, 30)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
fill: function() {
|
||||
context.beginPath()
|
||||
context.rect(20, 20, 150, 100)
|
||||
context.setStrokeStyle('#00ff00')
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
stroke: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.lineTo(20, 100)
|
||||
context.lineTo(70, 100)
|
||||
context.setStrokeStyle('#00ff00')
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
clearRect: function() {
|
||||
context.setFillStyle('#ff0000')
|
||||
context.beginPath()
|
||||
context.rect(0, 0, 300, 150)
|
||||
context.fill()
|
||||
context.clearRect(20, 20, 100, 50)
|
||||
context.draw()
|
||||
},
|
||||
beginPath: function() {
|
||||
context.beginPath()
|
||||
context.setLineWidth(5)
|
||||
context.setStrokeStyle('#ff0000')
|
||||
context.moveTo(0, 75)
|
||||
context.lineTo(250, 75)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
context.setStrokeStyle('#0000ff')
|
||||
context.moveTo(50, 0)
|
||||
context.lineTo(150, 130)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
closePath: function() {
|
||||
context.beginPath()
|
||||
context.setLineWidth(1)
|
||||
context.moveTo(20, 20)
|
||||
context.lineTo(20, 100)
|
||||
context.lineTo(70, 100)
|
||||
context.closePath()
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
moveTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(0, 0)
|
||||
context.lineTo(300, 150)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
lineTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.lineTo(20, 100)
|
||||
context.lineTo(70, 100)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
rect: function() {
|
||||
context.beginPath()
|
||||
context.rect(20, 20, 150, 100)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
arc: function() {
|
||||
context.beginPath()
|
||||
context.setLineWidth(2)
|
||||
context.arc(75, 75, 50, 0, Math.PI * 2, true)
|
||||
context.moveTo(110, 75)
|
||||
context.arc(75, 75, 35, 0, Math.PI, false)
|
||||
context.moveTo(65, 65)
|
||||
context.arc(60, 65, 5, 0, Math.PI * 2, true)
|
||||
context.moveTo(95, 65)
|
||||
context.arc(90, 65, 5, 0, Math.PI * 2, true)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
quadraticCurveTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.quadraticCurveTo(20, 100, 200, 20)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
bezierCurveTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.bezierCurveTo(20, 100, 200, 100, 200, 20)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
setFillStyle: function() {
|
||||
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach(function(item, index) {
|
||||
context.setFillStyle(item)
|
||||
context.beginPath()
|
||||
context.rect(0 + 75 * index, 0, 50, 50)
|
||||
context.fill()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setStrokeStyle: function() {
|
||||
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach(function(item, index) {
|
||||
context.setStrokeStyle(item)
|
||||
context.beginPath()
|
||||
context.rect(0 + 75 * index, 0, 50, 50)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setGlobalAlpha: function() {
|
||||
context.setFillStyle('#000000');
|
||||
[1, 0.5, 0.1].forEach(function(item, index) {
|
||||
context.setGlobalAlpha(item)
|
||||
context.beginPath()
|
||||
context.rect(0 + 75 * index, 0, 50, 50)
|
||||
context.fill()
|
||||
})
|
||||
context.draw()
|
||||
context.setGlobalAlpha(1)
|
||||
},
|
||||
setShadow: function() {
|
||||
context.beginPath()
|
||||
context.setShadow(10, 10, 10, 'rgba(0, 0, 0, 199)')
|
||||
context.rect(10, 10, 100, 100)
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
setFontSize: function() {
|
||||
[10, 20, 30, 40].forEach(function(item, index) {
|
||||
context.setFontSize(item)
|
||||
context.fillText('Hello, world', 20, 20 + 40 * index)
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setLineCap: function() {
|
||||
context.setLineWidth(10);
|
||||
['butt', 'round', 'square'].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setLineCap(item)
|
||||
context.moveTo(20, 20 + 20 * index)
|
||||
context.lineTo(100, 20 + 20 * index)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setLineJoin: function() {
|
||||
context.setLineWidth(10);
|
||||
['bevel', 'round', 'miter'].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setLineJoin(item)
|
||||
context.moveTo(20 + 80 * index, 20)
|
||||
context.lineTo(100 + 80 * index, 50)
|
||||
context.lineTo(20 + 80 * index, 100)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setLineWidth: function() {
|
||||
[2, 4, 6, 8, 10].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setLineWidth(item)
|
||||
context.moveTo(20, 20 + 20 * index)
|
||||
context.lineTo(100, 20 + 20 * index)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setMiterLimit: function() {
|
||||
context.setLineWidth(4);
|
||||
[2, 4, 6, 8, 10].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setMiterLimit(item)
|
||||
context.moveTo(20 + 80 * index, 20)
|
||||
context.lineTo(100 + 80 * index, 50)
|
||||
context.lineTo(20 + 80 * index, 100)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.canvas-element-wrapper {
|
||||
display: block;
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
|
||||
.canvas-element {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.canvas-buttons {
|
||||
padding: 30rpx 50rpx 10rpx;
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.canvas-button {
|
||||
float: left;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
line-height: 1;
|
||||
width: 300rpx;
|
||||
margin: 15rpx 12rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFFFFF; padding:40rpx;">
|
||||
<view class="uni-hello-text uni-center">当前位置信息</view>
|
||||
<block v-if="hasLocation === false">
|
||||
<view class="uni-h2 uni-center uni-common-mt">未选择位置</view>
|
||||
</block>
|
||||
<block v-if="hasLocation === true">
|
||||
<view class="uni-hello-text uni-center" style="margin-top:10px;">
|
||||
{{locationAddress}}
|
||||
</view>
|
||||
<view class="uni-h2 uni-center uni-common-mt">
|
||||
<text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text>
|
||||
<text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="chooseLocation">选择位置</button>
|
||||
<button @tap="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import * as util from '../../../common/util.js'
|
||||
var formatLocation = util.formatLocation;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'chooseLocation',
|
||||
hasLocation: false,
|
||||
location: {},
|
||||
locationAddress: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
chooseLocation: function () {
|
||||
uni.chooseLocation({
|
||||
success: (res) => {
|
||||
this.hasLocation = true,
|
||||
this.location = formatLocation(res.longitude, res.latitude),
|
||||
this.locationAddress = res.address
|
||||
}
|
||||
})
|
||||
},
|
||||
clear: function () {
|
||||
this.hasLocation = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page-body-info {
|
||||
padding-bottom: 0;
|
||||
height: 440rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-title">请输入剪贴板内容</view>
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<input class="uni-input" type="text" placeholder="请输入剪贴板内容" :value="data" @input="dataChange"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="setClipboard">存储数据</button>
|
||||
<button @tap="getClipboard">读取数据</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'get/setClipboardData',
|
||||
data: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
dataChange: function (e) {
|
||||
this.data = e.detail.value
|
||||
},
|
||||
getClipboard: function () {
|
||||
uni.getClipboardData({
|
||||
success: (res) => {
|
||||
console.log(res.data);
|
||||
const content = res.data ? '剪贴板内容为:' + res.data : '剪贴板暂无内容';
|
||||
uni.showModal({
|
||||
content,
|
||||
title: '读取剪贴板',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
content: '读取剪贴板失败!',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
setClipboard: function () {
|
||||
var data = this.data;
|
||||
if (data.length === 0) {
|
||||
uni.showModal({
|
||||
title: '设置剪贴板失败',
|
||||
content: '内容不能为空',
|
||||
showCancel: false
|
||||
})
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: data,
|
||||
success: () => {
|
||||
// 成功处理
|
||||
// #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
||||
uni.showToast({
|
||||
title: '设置剪贴板成功',
|
||||
icon: "success",
|
||||
mask: !1
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
fail: () => {
|
||||
// 失败处理
|
||||
// #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
||||
uni.showToast({
|
||||
title: '储存数据失败!',
|
||||
icon: "none",
|
||||
mask: !1
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
|
||||
describe('pages/API/download-file/download-file.vue', () => {
|
||||
let page;
|
||||
const versions = ['12.4', '13.7', '15.5', '17.4', '17.5_深色主题', '18.1'];
|
||||
const [platform, version] = platformInfo.split(' ');
|
||||
if (platform === 'ios_simulator' && versions.includes(version)) {
|
||||
it('skip', async () => {
|
||||
expect(1).toBe(1);
|
||||
});
|
||||
return;
|
||||
}
|
||||
beforeAll(async () => {
|
||||
page = await program.reLaunch('/pages/API/download-file/download-file')
|
||||
await page.waitFor('view')
|
||||
});
|
||||
it('check download url', async () => {
|
||||
expect.assertions(2);
|
||||
await page.callMethod('downloadImage')
|
||||
const waitTime = process.env.uniTestPlatformInfo.includes('firefox') ? 5000:2000
|
||||
const start = Date.now();
|
||||
await page.waitFor(async () => {
|
||||
return await page.data('jest_result') === true || (Date.now() - start > waitTime)
|
||||
})
|
||||
expect(await page.data('jest_result')).toBeTruthy();
|
||||
expect(await page.data('imageSrc')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view v-if="imageSrc" class="image-container">
|
||||
<image class="img" :src="imageSrc" mode="center" />
|
||||
</view>
|
||||
<block v-else style="margin-top: 50px;">
|
||||
<view class="uni-hello-text">
|
||||
点击按钮下载服务端示例图片(下载网络文件到本地临时目录)
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="downloadImage">下载</button>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'downloadFile',
|
||||
imageSrc: '',
|
||||
//自动化测试例专用
|
||||
jest_result: false
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.imageSrc = '';
|
||||
},
|
||||
methods: {
|
||||
downloadImage: function () {
|
||||
uni.showLoading({
|
||||
title:'下载中'
|
||||
})
|
||||
var self = this
|
||||
uni.downloadFile({
|
||||
url: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
|
||||
success: (res) => {
|
||||
this.jest_result = true
|
||||
console.log('downloadFile success, res is', res)
|
||||
self.imageSrc = res.tempFilePath;
|
||||
uni.hideLoading();
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('downloadFile fail, err is:', err)
|
||||
this.jest_result = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.img {
|
||||
width: 500rpx;
|
||||
height: 500rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<block v-if="tempFilePath">
|
||||
<image :src="tempFilePath" class="image" mode="aspectFit"></image>
|
||||
</block>
|
||||
<block v-if="!tempFilePath && savedFilePath">
|
||||
<image :src="savedFilePath" class="image" mode="aspectFit"></image>
|
||||
</block>
|
||||
<block v-if="!tempFilePath && !savedFilePath">
|
||||
<view class="uni-hello-addfile" @click="chooseImage">+ 请选择文件</view>
|
||||
</block>
|
||||
<view class="uni-btn-v">
|
||||
<button class="btn-savefile" @click="saveFile">保存文件</button>
|
||||
<button @click="clear">删除文件</button>
|
||||
</view>
|
||||
<!-- #ifndef MP-ALIPAY || MP-TOUTIAO -->
|
||||
<view class="btn-area">
|
||||
<button @click="openDocument">打开pdf文件</button>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'saveFile',
|
||||
tempFilePath: '',
|
||||
savedFilePath: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.savedFilePath = uni.getStorageSync('savedFilePath');
|
||||
},
|
||||
methods: {
|
||||
chooseImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: (res) => {
|
||||
this.tempFilePath = res.tempFilePaths[0];
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
},
|
||||
saveFile() {
|
||||
if (this.tempFilePath.length > 0) {
|
||||
uni.saveFile({
|
||||
tempFilePath: this.tempFilePath,
|
||||
success: (res) => {
|
||||
this.savedFilePath = res.savedFilePath;
|
||||
uni.setStorageSync('savedFilePath', res.savedFilePath);
|
||||
uni.showModal({
|
||||
title: '保存成功',
|
||||
content: '下次进入页面时,此文件仍可用',
|
||||
showCancel: false
|
||||
});
|
||||
},
|
||||
fail: (res) => {
|
||||
uni.showModal({
|
||||
title: '保存失败',
|
||||
content: '失败原因: ' + JSON.stringify(res),
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: '请选择文件',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
uni.setStorageSync('savedFilePath', '');
|
||||
this.tempFilePath = '';
|
||||
this.savedFilePath = '';
|
||||
},
|
||||
// #ifndef MP-ALIPAY || MP-TOUTIAO
|
||||
openDocument() {
|
||||
uni.downloadFile({
|
||||
url: 'https://web-assets.dcloud.net.cn/unidoc/zh/helloworld.pdf',
|
||||
success: (res) => {
|
||||
uni.openDocument({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
console.log('打开文档成功');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
}
|
||||
|
||||
.btn-savefile {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<button :loading="loading" :disabled="loading" type="primary" class="btn" @click="showAd">显示广告</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '全屏视频广告',
|
||||
loading: false,
|
||||
loadError: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// #ifdef APP-PLUS
|
||||
this.adOption = {
|
||||
adpid: '1507000611'
|
||||
};
|
||||
// #endif
|
||||
this.createAd();
|
||||
},
|
||||
methods: {
|
||||
createAd() {
|
||||
var _ad = this._ad = uni.createFullScreenVideoAd(this.adOption);
|
||||
_ad.onLoad(() => {
|
||||
this.loading = false;
|
||||
this.loadError = false;
|
||||
_ad.show();
|
||||
console.log('onLoad event')
|
||||
});
|
||||
_ad.onClose((res) => {
|
||||
// 用户点击了【关闭广告】按钮
|
||||
if (res && res.isEnded) {
|
||||
// 正常播放结束
|
||||
console.log("onClose " + res.isEnded);
|
||||
} else {
|
||||
// 播放中途退出
|
||||
console.log("onClose " + res.isEnded);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: "全屏视频" + (res.isEnded ? "成功" : "未") + "播放完毕",
|
||||
duration: 10000,
|
||||
position: 'bottom'
|
||||
})
|
||||
}, 500)
|
||||
});
|
||||
_ad.onError((err) => {
|
||||
this.loading = false;
|
||||
if (err.code) {
|
||||
this.loadError = true;
|
||||
}
|
||||
console.log('onError event', err)
|
||||
uni.showToast({
|
||||
title: err.errMsg,
|
||||
position: 'bottom'
|
||||
})
|
||||
});
|
||||
},
|
||||
showAd() {
|
||||
this.loading = true;
|
||||
this._ad.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ad-tips {
|
||||
color: #999;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFFFFF; padding:40rpx;">
|
||||
<view class="uni-hello-text uni-center">当前位置经纬度</view>
|
||||
<block v-if="hasLocation === false">
|
||||
<view class="uni-h2 uni-center uni-common-mt">未获取</view>
|
||||
</block>
|
||||
<block v-if="hasLocation === true">
|
||||
<view class="uni-h2 uni-center uni-common-mt">
|
||||
<text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text>
|
||||
<text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="getLocation">获取位置</button>
|
||||
<button @tap="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
<uni-popup :show="type === 'showpopup'" mode="fixed" @hidePopup="togglePopup('')">
|
||||
<view class="popup-view">
|
||||
<text class="popup-title">需要用户授权位置权限</text>
|
||||
<view class="uni-flex popup-buttons">
|
||||
<button class="uni-flex-item" type="primary" open-type="openSetting" @tap="openSetting">设置</button>
|
||||
<button class="uni-flex-item" @tap="togglePopup('')">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import * as util from '../../../common/util.js'
|
||||
var formatLocation = util.formatLocation;
|
||||
// #ifdef APP-PLUS
|
||||
import permision from "@/common/permission.js"
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getLocation',
|
||||
hasLocation: false,
|
||||
location: {},
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
togglePopup(type) {
|
||||
this.type = type;
|
||||
},
|
||||
showConfirm() {
|
||||
this.type = 'showpopup';
|
||||
},
|
||||
hideConfirm() {
|
||||
this.type = '';
|
||||
},
|
||||
async getLocation() {
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ
|
||||
let status = await this.getSetting();
|
||||
if (status === 2) {
|
||||
this.showConfirm();
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-HARMONY
|
||||
uni.authorize({
|
||||
scope: "scope.userLocation",
|
||||
success: () => {
|
||||
this.doGetLocation();
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: "未授权获取地理位置权限"
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifndef MP-HARMONY
|
||||
this.doGetLocation();
|
||||
// #endif
|
||||
},
|
||||
doGetLocation() {
|
||||
uni.getLocation({
|
||||
success: (res) => {
|
||||
this.hasLocation = true;
|
||||
this.location = formatLocation(res.longitude, res.latitude);
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP-BAIDU
|
||||
if (err.errCode === 202 || err.errCode === 10003) { // 202模拟器 10003真机 user deny
|
||||
this.showConfirm();
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-BAIDU
|
||||
if (err.errMsg.indexOf("auth deny") >= 0) {
|
||||
uni.showToast({
|
||||
title: "访问位置被拒绝"
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: err.errMsg
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
getSetting: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userLocation'] === undefined) {
|
||||
resolve(0);
|
||||
return;
|
||||
}
|
||||
if (res.authSetting['scope.userLocation']) {
|
||||
resolve(1);
|
||||
} else {
|
||||
resolve(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
openSetting: function() {
|
||||
this.hideConfirm();
|
||||
uni.openSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting && res.authSetting['scope.userLocation']) {
|
||||
this.doGetLocation();
|
||||
}
|
||||
},
|
||||
fail: (err) => {}
|
||||
})
|
||||
},
|
||||
async checkPermission() {
|
||||
let status = permision.isIOS ? await permision.requestIOS('location') :
|
||||
await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else if (status === 2) {
|
||||
uni.showModal({
|
||||
content: "系统定位已关闭",
|
||||
confirmText: "确定",
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
}
|
||||
})
|
||||
} else if (status.code) {
|
||||
uni.showModal({
|
||||
content: status.message
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要定位权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return status;
|
||||
},
|
||||
clear: function() {
|
||||
this.hasLocation = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.popup-view {
|
||||
width: 500rpx;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
line-height: 3;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.popup-buttons button {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view style="background:#FFFFFF; padding:40rpx;">
|
||||
<view class="uni-hello-text uni-center">网络状态</view>
|
||||
<block v-if="hasNetworkType === false">
|
||||
<view class="uni-h2 uni-center uni-common-mt">未获取</view>
|
||||
<view class="uni-hello-text uni-center uni-common-mt">请点击下面按钮获取网络状态</view>
|
||||
</block>
|
||||
<block v-if="hasNetworkType === true">
|
||||
<view class="uni-h2 uni-center uni-common-mt">{{networkType}}</view>
|
||||
</block>
|
||||
<!-- #ifndef MP-HARMONY -->
|
||||
<view v-if="hasNetworkType === true && networkType === 'wifi'" class="uni-textarea uni-common-mt">
|
||||
<textarea :value="connectedWifi"></textarea>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" @tap="getNetworkType">获取设备网络状态</button>
|
||||
<!-- #ifdef MP-WEIXIN || MP-JD-->
|
||||
<button v-if="hasNetworkType === true && networkType === 'wifi'" class="uni-common-mt" type="primary" @tap="getConnectedWifi">获取 wifi 信息</button>
|
||||
<!-- #endif -->
|
||||
<button class="uni-common-mt" @tap="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getNetworkType',
|
||||
hasNetworkType: false,
|
||||
networkType: '',
|
||||
connectedWifi: ''
|
||||
}
|
||||
},
|
||||
onUnload:function(){
|
||||
this.networkType = '',this.hasNetworkType = false;
|
||||
},
|
||||
methods: {
|
||||
getNetworkType: function () {
|
||||
uni.getNetworkType({
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
this.hasNetworkType = true, this.networkType = res.subtype || res.networkType
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
content:'获取失败!',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
clear: function () {
|
||||
this.hasNetworkType = false,
|
||||
this.networkType = '',
|
||||
this.connectedWifi = ''
|
||||
},
|
||||
// #ifdef MP-WEIXIN || MP-JD
|
||||
getConnectedWifi() {
|
||||
const that = this
|
||||
uni.startWifi({
|
||||
success: function() {
|
||||
uni.getConnectedWifi({
|
||||
success: function(res) {
|
||||
const { wifi } = res
|
||||
that.connectedWifi = JSON.stringify(wifi)
|
||||
},
|
||||
fail: function(res) {
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: function(res) {
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
describe('测试 css 变量', () => {
|
||||
let page
|
||||
const isApp = process.env.UNI_PLATFORM.includes('app');
|
||||
beforeAll(async () => {
|
||||
// 重新reLaunch至首页,并获取首页page对象(其中 program 是uni-automator自动注入的全局对象)
|
||||
page = await program.reLaunch('/pages/API/get-node-info/get-node-info')
|
||||
await page.waitFor(1000)
|
||||
})
|
||||
|
||||
it('css var', async () => {
|
||||
|
||||
if (isApp) {
|
||||
const element1 = await page.$('.box1')
|
||||
const size = await element1.size()
|
||||
expect(size.height > 0).toBe(true)
|
||||
|
||||
const element2 = await page.$('.box2')
|
||||
const size2 = await element2.size()
|
||||
expect(size2.height === 0).toBe(true)
|
||||
|
||||
const element3 = await page.$('.box3')
|
||||
const size3 = await element3.size()
|
||||
expect(size3.height === 0).toBe(true)
|
||||
|
||||
const element4 = await page.$('.box4')
|
||||
const size4 = await element4.size()
|
||||
expect(size4.height > size.height).toBe(true)
|
||||
} else {
|
||||
expect(1).toBe(1)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="movable block">
|
||||
<!-- #ifndef MP-TOUTIAO -->
|
||||
<movable-area>
|
||||
<movable-view class="target" direction="all" @change="getNodeInfo">Drag</movable-view>
|
||||
</movable-area>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-TOUTIAO -->
|
||||
<view class="target" @click="setPosition" :style="{top:top,left:left}">Click</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="movable">
|
||||
<view class="info">
|
||||
<view v-for="(item,index) in info" :key="index">
|
||||
<text class="b">{{item.key}}</text>
|
||||
<text class="span">{{item.val}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP -->
|
||||
<view>
|
||||
<view class="box box1"></view>
|
||||
<view class="box box2"></view>
|
||||
<view class="box box3"></view>
|
||||
<view class="box box4"></view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'createSelectorQuery',
|
||||
top: 0,
|
||||
left: '0px',
|
||||
info: []
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
this.getNodeInfo()
|
||||
},
|
||||
methods: {
|
||||
setPosition() {
|
||||
this.left = Math.random() * uni.upx2px(320) + 'px'
|
||||
this.top = Math.random() * uni.upx2px(320) + 'px'
|
||||
this.getNodeInfo()
|
||||
},
|
||||
getNodeInfo() {
|
||||
uni.createSelectorQuery().select('.target').boundingClientRect().exec((ret) => {
|
||||
const rect = ret[0]
|
||||
if (rect) {
|
||||
const sort = ['left','right','top','bottom','width','height']
|
||||
const info = []
|
||||
for (let i in sort) {
|
||||
let key = sort[i]
|
||||
info.push({
|
||||
'key': key,
|
||||
'val': rect[key]
|
||||
})
|
||||
}
|
||||
this.info = info
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.movable {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.block {
|
||||
height: 400rpx;
|
||||
width: 400rpx;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
movable-area {
|
||||
height: 400rpx;
|
||||
width: 400rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.target {
|
||||
height: 80rpx;
|
||||
width: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
background-color: #4cd964;
|
||||
font-size: 28rpx;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.b {
|
||||
font-weight: bold;
|
||||
width: 150rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.span {
|
||||
width: 100rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 50px;
|
||||
}
|
||||
.box1 {
|
||||
height: var(--status-bar-height);
|
||||
}
|
||||
.box2 {
|
||||
height: var(--window-bottom);
|
||||
}
|
||||
.box3 {
|
||||
height: var(--window-top);
|
||||
}
|
||||
.box4 {
|
||||
height: calc(var(--status-bar-height) + 2px);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">设备型号</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.model"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">客户端平台</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.platform"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">操作系统版本</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.system"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">语言</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.language"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">版本</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.version"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">屏幕宽度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.screenWidth"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">屏幕高度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.screenHeight"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">可使用窗口高度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.windowHeight"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">可使用窗口的顶部位置</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.windowTop"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">可使用窗口的底部位置</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.windowBottom"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">状态栏的高度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.statusBarHeight"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">DPI</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.pixelRatio"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef MP -->
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">基础库版本</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.SDKVersion"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="getSystemInfo">获取设备系统信息</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getSystemInfo',
|
||||
systemInfo: {}
|
||||
}
|
||||
},
|
||||
onUnload:function(){
|
||||
this.systemInfo = {};
|
||||
},
|
||||
methods: {
|
||||
getSystemInfo: function () {
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
this.systemInfo = res
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-pd {
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFF; padding:40rpx;">
|
||||
<block v-if="hasUserInfo === false">
|
||||
<view class="uni-hello-text uni-center">
|
||||
<text>请点击下方按钮获取用户头像及昵称或手机号</text>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasUserInfo === true">
|
||||
<view class="uni-h4 uni-center uni-common-mt">{{userInfo.nickName || userInfo.nickname || userInfo.gender || userInfo.email || userInfo.phoneNumber}}</view>
|
||||
<view v-if="userInfo.avatarUrl || userInfo.avatar_url " style="padding:30rpx 0; text-align:center;">
|
||||
<image class="userinfo-avatar" :src="userInfo.avatarUrl||userInfo.avatar_url"></image>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<!-- #ifdef APP-PLUS || MP-ALIPAY || MP-TOUTIAO -->
|
||||
<button type="primary" :loading="btnLoading" @click="getUserInfo">获取用户信息</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-JD -->
|
||||
<button type="primary" open-type="getUserInfo" @getuserinfo="mpGetUserInfo">获取用户信息</button>
|
||||
<!-- #endif -->
|
||||
<button @click="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapMutations,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getUserInfo',
|
||||
hasUserInfo: false,
|
||||
userInfo: {},
|
||||
btnLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'loginProvider',
|
||||
'isUniverifyLogin'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['getPhoneNumber']),
|
||||
// 获取用户信息 API 在小程序可直接使用,在 5+App 里面需要先登录才能调用
|
||||
getUserInfo() {
|
||||
this.btnLoading = true;
|
||||
if (this.isUniverifyLogin) {
|
||||
// 一键登录
|
||||
this.getPhoneNumber(uni.getStorageSync('univerifyInfo')).then(phoneNumber => {
|
||||
this.hasUserInfo = true;
|
||||
this.userInfo = {
|
||||
phoneNumber
|
||||
};
|
||||
}).catch(err => {
|
||||
console.error('getUserInfo fail:', err);
|
||||
this.hasUserInfo = false;
|
||||
}).finally(() => {
|
||||
this.btnLoading = false;
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.loginProvider === 'apple'){
|
||||
const nickname = uni.getStorageSync('apple_nickname')
|
||||
if(nickname){
|
||||
this.hasUserInfo = true;
|
||||
this.userInfo = { nickName:nickname }
|
||||
this.btnLoading = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uni.getUserInfo({
|
||||
provider: this.loginProvider,
|
||||
success: (result) => {
|
||||
this.hasUserInfo = true;
|
||||
this.userInfo = result.userInfo;
|
||||
},
|
||||
fail: (error) => {
|
||||
console.log('getUserInfo fail', error);
|
||||
let content = error.errMsg;
|
||||
if (~content.indexOf('uni.login')) {
|
||||
content = '请在登录页面完成登录操作';
|
||||
}
|
||||
// #ifndef APP-PLUS
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.userInfo'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要获取您的用户信息,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + content,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + content,
|
||||
showCancel: false
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
complete: () => {
|
||||
this.btnLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
mpGetUserInfo(result) {
|
||||
console.log('mpGetUserInfo', result);
|
||||
if (result.detail.errMsg !== 'getUserInfo:ok') {
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + result.detail.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.hasUserInfo = true;
|
||||
if(result.detail && result.detail.userInfo){
|
||||
this.userInfo = result.detail.userInfo;
|
||||
}else{
|
||||
// #ifdef MP-JD
|
||||
this.userInfo = result.detail.user_info;
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
this.hasUserInfo = false;
|
||||
this.userInfo = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.userinfo-avatar {
|
||||
border-radius: 128rpx;
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" :disabled="isOpen" @click="openBluetoothAdapter">打开蓝牙模块</button>
|
||||
<button type="primary" :disabled="!isOpen" @click="closeBluetoothAdapter">关闭蓝牙模块</button>
|
||||
<button type="primary" :disabled="!isOpen || isStarted" :loading="isStarted" @click="startBeaconDiscovery">开始搜索附近的iBeacon设备</button>
|
||||
<button type="primary" :disabled="!isStarted" @click="stopBeaconDiscovery">停止搜索附近的iBeacon设备</button>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view class="uni-scroll_box">
|
||||
<view class="uni-title" v-if="isStarted || deviceList.length > 0">已经发现 {{ deviceList.length }} 台设备:</view>
|
||||
<view class="uni-list-box" v-for="(item, index) in deviceList" :key="item.uuid">
|
||||
<view>
|
||||
<view class="uni-list_name">UUID: {{ item.uuid }}</view>
|
||||
<view class="uni-list_item">major: {{ item.major }}</view>
|
||||
<view class="uni-list_item">minor: {{ item.minor }}</view>
|
||||
<view class="uni-list_item">rssi: {{ item.rssi }} dBm</view>
|
||||
<view class="uni-list_item">accuracy: {{ item.accuracy }}</view>
|
||||
<view class="uni-list_item">heading: {{ item.heading }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const DEVICE_UUID_WEICHAT = 'FDA50693-A4E2-4FB1-AFCF-C6EB07647825';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'iBeacon',
|
||||
isOpen: false,
|
||||
isStarted: false,
|
||||
deviceList: [],
|
||||
isPageOpened: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.onBeaconUpdate();
|
||||
},
|
||||
onShow() {
|
||||
this.isPageOpened = true;
|
||||
},
|
||||
methods: {
|
||||
maskclose() {
|
||||
this.maskShow = false;
|
||||
},
|
||||
openBluetoothAdapter() {
|
||||
uni.openBluetoothAdapter({
|
||||
success: (res) => {
|
||||
console.log('初始化蓝牙成功:' + res.errMsg);
|
||||
console.log(res);
|
||||
this.isOpen = true;
|
||||
this.deviceList = [];
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('初始化蓝牙失败,错误码:' + (err.errCode || err.errMsg));
|
||||
if (err.errCode !== 0) {
|
||||
initTypes(err.errCode, err.errMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
closeBluetoothAdapter(OBJECT) {
|
||||
this.stopBeaconDiscovery();
|
||||
wx.closeBluetoothAdapter({
|
||||
success: (res) => {
|
||||
this.isOpen = false;
|
||||
console.log('断开蓝牙模块成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
onBeaconUpdate() {
|
||||
uni.onBeaconUpdate(res => {
|
||||
if (!this.isPageOpened || !this.isOpen || !this.isStarted) {
|
||||
return;
|
||||
}
|
||||
console.log(res);
|
||||
// if (res.code !== 0) {
|
||||
// return;
|
||||
// }
|
||||
if (res.beacons && res.beacons.length > 0) {
|
||||
this.getBeacons();
|
||||
} else if (!res.connected) {
|
||||
this.deviceList = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
startBeaconDiscovery() {
|
||||
uni.startBeaconDiscovery({
|
||||
uuids: this.getUUIDList(),
|
||||
success: (res) => {
|
||||
this.isStarted = true;
|
||||
console.log(res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
stopBeaconDiscovery(types) {
|
||||
if(this.isStarted) {
|
||||
uni.stopBeaconDiscovery({
|
||||
success: (res) => {
|
||||
this.isStarted = false;
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
getBeacons() {
|
||||
uni.getBeacons({
|
||||
success: (res) => {
|
||||
if (res.beacons && res.beacons.length > 0) {
|
||||
console.log(res.beacons);
|
||||
this.deviceList = res.beacons;
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('获取设备服务失败,错误码:' + err.errCode);
|
||||
if (errCode.errCode !== 0) {
|
||||
initTypes(errCode.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getUUIDList() {
|
||||
// #ifdef APP-PLUS
|
||||
const sysInfo = uni.getSystemInfoSync();
|
||||
if (!sysInfo) {
|
||||
return [];
|
||||
}
|
||||
let isIOS = sysInfo.platform ? (sysInfo.platform.toLowerCase() === "ios") : false;
|
||||
if (isIOS) {
|
||||
return [DEVICE_UUID_WEICHAT];
|
||||
}
|
||||
return [];
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
return [DEVICE_UUID_WEICHAT];
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.isPageOpened = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断初始化蓝牙状态
|
||||
*/
|
||||
function initTypes(code, errMsg) {
|
||||
switch (code) {
|
||||
case 10000:
|
||||
toast('未初始化蓝牙适配器');
|
||||
break;
|
||||
case 10001:
|
||||
toast('未检测到蓝牙,请打开蓝牙重试!');
|
||||
break;
|
||||
case 10002:
|
||||
toast('没有找到指定设备');
|
||||
break;
|
||||
case 10003:
|
||||
toast('连接失败');
|
||||
break;
|
||||
case 10004:
|
||||
toast('没有找到指定服务');
|
||||
break;
|
||||
case 10005:
|
||||
toast('没有找到指定特征值');
|
||||
break;
|
||||
case 10006:
|
||||
toast('当前连接已断开');
|
||||
break;
|
||||
case 10007:
|
||||
toast('当前特征值不支持此操作');
|
||||
break;
|
||||
case 10008:
|
||||
toast('其余所有系统上报的异常');
|
||||
break;
|
||||
case 10009:
|
||||
toast('Android 系统特有,系统版本低于 4.3 不支持 BLE');
|
||||
break;
|
||||
default:
|
||||
toast(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框封装
|
||||
*/
|
||||
function toast(content, showCancel = false) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content,
|
||||
showCancel
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-title {
|
||||
/* width: 100%; */
|
||||
/* height: 80rpx; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uni-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-scroll_box {
|
||||
height: 70%;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.uni-list-box {
|
||||
margin: 0 20rpx;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-list:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.uni-list_name {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.uni-list_item {
|
||||
font-size: 24rpx;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.uni-success_box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
min-height: 100rpx;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px #eee solid;
|
||||
}
|
||||
|
||||
.uni-success_sub {
|
||||
/* width: 100%%; */
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.uni-close_button {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: #ce3c39;
|
||||
color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.uni-success_content {
|
||||
height: 600rpx;
|
||||
margin: 30rpx;
|
||||
margin-top: 0;
|
||||
border: 1px #eee solid;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.uni-content_list {
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
}
|
||||
|
||||
.uni-tips {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<form>
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">图片来源</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="sourceType" @change="sourceTypeChange" :value="sourceTypeIndex" mode="selector">
|
||||
<view class="uni-input">{{sourceType[sourceTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">图片质量</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="sizeType" @change="sizeTypeChange" :value="sizeTypeIndex" mode="selector">
|
||||
<view class="uni-input">{{sizeType[sizeTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">数量限制</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="count" @change="countChange" mode="selector">
|
||||
<view class="uni-input">{{count[countIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="uni-list list-pd">
|
||||
<view class="uni-list-cell cell-pd">
|
||||
<view class="uni-uploader">
|
||||
<view class="uni-uploader-head">
|
||||
<view class="uni-uploader-title">点击可预览选好的图片</view>
|
||||
<view class="uni-uploader-info">{{imageList.length}}/9</view>
|
||||
</view>
|
||||
<view class="uni-uploader-body">
|
||||
<view class="uni-uploader__files">
|
||||
<block v-for="(image,index) in imageList" :key="index">
|
||||
<view class="uni-uploader__file">
|
||||
<image class="uni-uploader__img" :src="image" :data-src="image" @tap="previewImage"></image>
|
||||
</view>
|
||||
</block>
|
||||
<view class="uni-uploader__input-box">
|
||||
<view class="uni-uploader__input" @tap="chooseImage"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import permision from "@/common/permission.js"
|
||||
var sourceType = [
|
||||
['camera'],
|
||||
['album'],
|
||||
['camera', 'album']
|
||||
]
|
||||
var sizeType = [
|
||||
['compressed'],
|
||||
['original'],
|
||||
['compressed', 'original']
|
||||
]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'choose/previewImage',
|
||||
imageList: [],
|
||||
sourceTypeIndex: 2,
|
||||
sourceType: ['拍照', '相册', '拍照或相册'],
|
||||
sizeTypeIndex: 2,
|
||||
sizeType: ['压缩', '原图', '压缩或原图'],
|
||||
countIndex: 8,
|
||||
count: [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.imageList = [],
|
||||
this.sourceTypeIndex = 2,
|
||||
this.sourceType = ['拍照', '相册', '拍照或相册'],
|
||||
this.sizeTypeIndex = 2,
|
||||
this.sizeType = ['压缩', '原图', '压缩或原图'],
|
||||
this.countIndex = 8;
|
||||
},
|
||||
methods: {
|
||||
sourceTypeChange: function(e) {
|
||||
this.sourceTypeIndex = parseInt(e.detail.value)
|
||||
},
|
||||
sizeTypeChange: function(e) {
|
||||
this.sizeTypeIndex = parseInt(e.detail.value)
|
||||
},
|
||||
countChange: function(e) {
|
||||
this.countIndex = e.detail.value;
|
||||
},
|
||||
chooseImage: async function() {
|
||||
// #ifdef APP-PLUS
|
||||
// TODO 选择相机或相册时 需要弹出actionsheet,目前无法获得是相机还是相册,在失败回调中处理
|
||||
if (this.sourceTypeIndex !== 2) {
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (this.imageList.length === 9) {
|
||||
let isContinue = await this.isFullImg();
|
||||
console.log("是否继续?", isContinue);
|
||||
if (!isContinue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
uni.chooseImage({
|
||||
sourceType: sourceType[this.sourceTypeIndex],
|
||||
sizeType: sizeType[this.sizeTypeIndex],
|
||||
count: this.imageList.length + this.count[this.countIndex] > 9 ? 9 - this.imageList.length : this.count[this.countIndex],
|
||||
success: (res) => {
|
||||
this.imageList = this.imageList.concat(res.tempFilePaths);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log("err: ",err);
|
||||
// #ifdef APP-PLUS
|
||||
if (err['code'] && err.code !== 0 && this.sourceTypeIndex === 2) {
|
||||
this.checkPermission(err.code);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
if(err.errMsg.indexOf('cancel') !== '-1'){
|
||||
return;
|
||||
}
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = false;
|
||||
switch (this.sourceTypeIndex) {
|
||||
case 0:
|
||||
authStatus = res.authSetting['scope.camera'];
|
||||
break;
|
||||
case 1:
|
||||
authStatus = res.authSetting['scope.album'];
|
||||
break;
|
||||
case 2:
|
||||
authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
isFullImg: function() {
|
||||
return new Promise((res) => {
|
||||
uni.showModal({
|
||||
content: "已经有9张图片了,是否清空现有图片?",
|
||||
success: (e) => {
|
||||
if (e.confirm) {
|
||||
this.imageList = [];
|
||||
res(true);
|
||||
} else {
|
||||
res(false)
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
res(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
previewImage: function(e) {
|
||||
var current = e.target.dataset.src
|
||||
uni.previewImage({
|
||||
current: current,
|
||||
urls: this.imageList
|
||||
})
|
||||
},
|
||||
async checkPermission(code) {
|
||||
let type = code ? code - 1 : this.sourceTypeIndex;
|
||||
let status = permision.isIOS ? await permision.requestIOS(sourceType[type][0]) :
|
||||
await permision.requestAndroid(type === 0 ? 'android.permission.CAMERA' :
|
||||
'android.permission.READ_EXTERNAL_STORAGE');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "没有开启权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cell-pd {
|
||||
padding: 22rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-pd {
|
||||
margin-top: 50rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<view class="uni-padding-wrap">
|
||||
<page-head title="audio"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<slider :value="position" :min="0" :max="duration" @changing="onchanging" @change="onchange"></slider>
|
||||
</view>
|
||||
<!-- <view class="uni-common-mt play-time-area">
|
||||
<text class="current-time">{{currentTime}}</text>
|
||||
<text class="duration">{{duration}}</text>
|
||||
</view> -->
|
||||
<view class="play-button-area">
|
||||
<image class="icon-play" :src="playImage" @click="play"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const audioUrl = 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: "innerAudioContext",
|
||||
isPlaying: false,
|
||||
isPlayEnd: false,
|
||||
currentTime: 0,
|
||||
duration: 100
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
position() {
|
||||
return this.isPlayEnd ? 0 : this.currentTime;
|
||||
},
|
||||
playImage() {
|
||||
return this.isPlaying ? "/static/pause.png" : "/static/play.png"
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this._isChanging = false;
|
||||
this._audioContext = null;
|
||||
this.createAudio();
|
||||
},
|
||||
onUnload() {
|
||||
if (this._audioContext != null && this.isPlaying) {
|
||||
this.stop();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createAudio() {
|
||||
var innerAudioContext = this._audioContext = uni.createInnerAudioContext();
|
||||
innerAudioContext.autoplay = false;
|
||||
innerAudioContext.src = audioUrl;
|
||||
innerAudioContext.onPlay(() => {
|
||||
console.log('开始播放');
|
||||
});
|
||||
innerAudioContext.onTimeUpdate((e) => {
|
||||
if (this._isChanging === true) {
|
||||
return;
|
||||
}
|
||||
this.currentTime = innerAudioContext.currentTime || 0;
|
||||
this.duration = innerAudioContext.duration || 0;
|
||||
});
|
||||
innerAudioContext.onEnded(() => {
|
||||
this.currentTime = 0;
|
||||
this.isPlaying = false;
|
||||
this.isPlayEnd = true;
|
||||
});
|
||||
innerAudioContext.onError((res) => {
|
||||
this.isPlaying = false;
|
||||
console.log(res.errMsg);
|
||||
console.log(res.errCode);
|
||||
});
|
||||
return innerAudioContext;
|
||||
},
|
||||
onchanging() {
|
||||
this._isChanging = true;
|
||||
},
|
||||
onchange(e) {
|
||||
console.log(e.detail.value);
|
||||
console.log(typeof e.detail.value);
|
||||
this._audioContext.seek(e.detail.value);
|
||||
this._isChanging = false;
|
||||
},
|
||||
play() {
|
||||
if (this.isPlaying) {
|
||||
this.pause();
|
||||
return;
|
||||
}
|
||||
this.isPlaying = true;
|
||||
this._audioContext.play();
|
||||
this.isPlayEnd = false;
|
||||
},
|
||||
pause() {
|
||||
this._audioContext.pause();
|
||||
this.isPlaying = false;
|
||||
},
|
||||
stop() {
|
||||
this._audioContext.stop();
|
||||
this.isPlaying = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.play-time-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.duration {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.play-button-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.icon-play {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-title uni-common-mt">
|
||||
{{appear ? '小球出现' : '小球消失'}}
|
||||
</view>
|
||||
<scroll-view class="scroll-view" scroll-y>
|
||||
<view class="scroll-area">
|
||||
<text class="notice">向下滚动让小球出现</text>
|
||||
<view class="ball"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
let observer = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
appear: false,
|
||||
title:'intersectionObserver'
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
observer = uni.createIntersectionObserver(this);
|
||||
observer.relativeTo('.scroll-view').observe('.ball', (res) => {
|
||||
if (res.intersectionRatio > 0 && !this.appear) {
|
||||
this.appear = true;
|
||||
} else if (!res.intersectionRatio > 0 && this.appear) {
|
||||
this.appear = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
if (observer) {
|
||||
observer.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.scroll-view {
|
||||
height: 400rpx;
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.scroll-area {
|
||||
height: 1300rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin-top: 150rpx;
|
||||
margin: 150rpx 0 400rpx 0;
|
||||
}
|
||||
|
||||
.ball {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: #4cd964;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFF; padding:40rpx;">
|
||||
<block v-if="hasLogin === true">
|
||||
<view class="uni-h3 uni-center uni-common-mt">已登录
|
||||
<text v-if="isUniverifyLogin" style="font-size: 0.8em;">
|
||||
<i v-if="!phoneNumber.length" class="uni-icon_toast uni-loading"></i>
|
||||
<i v-else>({{phoneNumber}})</i>
|
||||
</text>
|
||||
</view>
|
||||
<view class="uni-hello-text uni-center">
|
||||
<text>每个账号仅需登录 1 次,\n后续每次进入页面即可自动拉取用户信息。</text>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasLogin === false">
|
||||
<view class="uni-h3 uni-center uni-common-mt">未登录</view>
|
||||
<view class="uni-hello-text uni-center">
|
||||
请点击按钮登录
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v uni- uni-common-mt">
|
||||
<!-- #ifdef MP-TOUTIAO -->
|
||||
<button type="primary" class="page-body-button" v-for="(value,key) in providerList" @click="tologin(value)" :key="key">
|
||||
登录
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-TOUTIAO -->
|
||||
<button type="primary" class="page-body-button" v-for="(value,key) in providerList" @click="tologin(value)"
|
||||
:loading="value.id === 'univerify' ? univerifyBtnLoading : false" :key="key">{{value.name}}</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapMutations,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
const univerifyInfoKey = 'univerifyInfo';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'login',
|
||||
providerList: [],
|
||||
phoneNumber: '',
|
||||
univerifyBtnLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['hasLogin', 'isUniverifyLogin', 'univerifyErrorMsg'])
|
||||
},
|
||||
onLoad() {
|
||||
uni.getProvider({
|
||||
service: 'oauth',
|
||||
success: (result) => {
|
||||
this.providerList = result.provider.map((value) => {
|
||||
let providerName = '';
|
||||
switch (value) {
|
||||
case 'weixin':
|
||||
providerName = '微信登录'
|
||||
break;
|
||||
case 'qq':
|
||||
providerName = 'QQ登录'
|
||||
break;
|
||||
case 'sinaweibo':
|
||||
providerName = '新浪微博登录'
|
||||
break;
|
||||
case 'xiaomi':
|
||||
providerName = '小米登录'
|
||||
break;
|
||||
case 'alipay':
|
||||
providerName = '支付宝登录'
|
||||
break;
|
||||
case 'baidu':
|
||||
providerName = '百度登录'
|
||||
break;
|
||||
case 'jd':
|
||||
providerName = '京东登录'
|
||||
break;
|
||||
case 'toutiao':
|
||||
providerName = '头条登录'
|
||||
break;
|
||||
case 'apple':
|
||||
providerName = '苹果登录'
|
||||
break;
|
||||
case 'univerify':
|
||||
providerName = '一键登录'
|
||||
break;
|
||||
case 'huawei':
|
||||
providerName = '华为登录'
|
||||
break;
|
||||
}
|
||||
return {
|
||||
name: providerName,
|
||||
id: value
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
fail: (error) => {
|
||||
console.log('获取登录通道失败', error);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.hasLogin && this.isUniverifyLogin) {
|
||||
this.getPhoneNumber(uni.getStorageSync(univerifyInfoKey)).then((phoneNumber) => {
|
||||
this.phoneNumber = phoneNumber
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['login', 'setUniverifyLogin']),
|
||||
...mapActions(['getPhoneNumber']),
|
||||
Toast(data, duration = 1000) {
|
||||
uni.showToast(Object.assign({}, data, {
|
||||
duration
|
||||
}))
|
||||
},
|
||||
tologin(provider) {
|
||||
if (provider.id === 'univerify') {
|
||||
this.univerifyBtnLoading = true;
|
||||
}
|
||||
|
||||
// 一键登录已在APP onLaunch的时候进行了预登陆,可以显著提高登录速度。登录成功后,预登陆状态会重置
|
||||
uni.login({
|
||||
provider: provider.id,
|
||||
// #ifdef MP-ALIPAY
|
||||
scopes: 'auth_user', //支付宝小程序需设置授权类型
|
||||
// #endif
|
||||
success: async (res) => {
|
||||
console.log('login success:', res);
|
||||
this.Toast({
|
||||
title: '登录成功'
|
||||
})
|
||||
// 更新保存在 store 中的登录状态
|
||||
this.login(provider.id);
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
this.setUniverifyLogin(provider.id === 'univerify')
|
||||
switch (provider.id) {
|
||||
case 'univerify':
|
||||
this.loginByUniverify(provider.id, res)
|
||||
break;
|
||||
case 'apple':
|
||||
this.loginByApple(provider.id, res)
|
||||
break;
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
console.warn('如需获取openid请参考uni-id: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
|
||||
uni.request({
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'loginByWeixin',
|
||||
params: {
|
||||
code: res.code,
|
||||
platform: 'mp-weixin'
|
||||
}
|
||||
},
|
||||
success(res) {
|
||||
console.log(res);
|
||||
if (res.data.code !== 0) {
|
||||
console.log('获取openid失败:', res.data.errMsg);
|
||||
return
|
||||
}
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
},
|
||||
fail(err) {
|
||||
console.log('获取openid失败:', err);
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('login fail:', err);
|
||||
|
||||
// 一键登录点击其他登录方式
|
||||
if (err.code == '30002') {
|
||||
uni.closeAuthView();
|
||||
this.Toast({
|
||||
title: '其他登录方式'
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
// 未开通
|
||||
if (err.code == 1000) {
|
||||
uni.showModal({
|
||||
title: '登录失败',
|
||||
content: `${err.errMsg}\n,错误码:${err.code}`,
|
||||
confirmText: '开通指南',
|
||||
cancelText: '确定',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
setTimeout(() => {
|
||||
plus.runtime.openWeb('https://ask.dcloud.net.cn/article/37965')
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 一键登录预登陆失败
|
||||
if (err.code == '30005') {
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
title: '预登录失败',
|
||||
content: this.univerifyErrorMsg || err.errMsg
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 一键登录用户关闭验证界面
|
||||
if (err.code != '30003') {
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
title: '登录失败',
|
||||
content: JSON.stringify(err)
|
||||
});
|
||||
}
|
||||
},
|
||||
complete: () => {
|
||||
this.univerifyBtnLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
loginByUniverify(provider, res) {
|
||||
this.setUniverifyLogin(true);
|
||||
uni.closeAuthView();
|
||||
|
||||
const univerifyInfo = {
|
||||
provider,
|
||||
...res.authResult,
|
||||
}
|
||||
|
||||
this.getPhoneNumber(univerifyInfo).then((phoneNumber) => {
|
||||
this.phoneNumber = phoneNumber;
|
||||
uni.setStorageSync(univerifyInfoKey, univerifyInfo)
|
||||
}).catch(err => {
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
title: '手机号获取失败',
|
||||
content: `${err.errMsg}\n,错误码:${err.code}`
|
||||
})
|
||||
console.error(res);
|
||||
})
|
||||
},
|
||||
async loginByApple(provider, res) {
|
||||
// 获取用户信息
|
||||
let getUserInfoErr, result
|
||||
// #ifndef VUE3
|
||||
[getUserInfoErr, result] = await uni.getUserInfo({
|
||||
provider
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
try {
|
||||
result = await uni.getUserInfo({
|
||||
provider
|
||||
});
|
||||
} catch(e) {
|
||||
getUserInfoErr = e
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (getUserInfoErr) {
|
||||
let content = getUserInfoErr.errMsg;
|
||||
if (~content.indexOf('uni.login')) {
|
||||
content = '请在登录页面完成登录操作';
|
||||
}
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + content,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
// uni-id 苹果登录
|
||||
console.warn('此处使用uni-id处理苹果登录,详情参考: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
|
||||
uni.request({
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'loginByApple',
|
||||
params: result.userInfo
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('uniId login success', res);
|
||||
if(res.data.code !== 0){
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
content: `苹果登录失败: ${JSON.stringify(res.data.msg)}`,
|
||||
})
|
||||
} else {
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
uni.setStorageSync('apple_nickname', res.data.userInfo.nickname)
|
||||
}
|
||||
},
|
||||
fail: (e) => {
|
||||
uni.showModal({
|
||||
content: `苹果登录失败: ${JSON.stringify(e)}`,
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
button {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-hello-text uni-center">请在下方输入电话号码</view>
|
||||
<input class="input uni-common-mt" type="number" name="input" @input="bindInput" />
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button @tap="makePhoneCall" type="primary" :disabled="disabled">拨打</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'makePhoneCall',
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
bindInput: function (e) {
|
||||
this.inputValue = e.detail.value
|
||||
if (this.inputValue.length > 0) {
|
||||
this.disabled = false
|
||||
} else {
|
||||
this.disabled = true
|
||||
}
|
||||
},
|
||||
makePhoneCall: function () {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: this.inputValue,
|
||||
success: () => {
|
||||
console.log("成功拨打电话")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.input {
|
||||
height: 119rpx;
|
||||
line-height: 119rpx;
|
||||
font-size: 78rpx;
|
||||
border-bottom: 1rpx solid #E2E2E2;
|
||||
text-align:center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<map class="map" ref="dcmap" :markers="markers" @tap="selectPoint"></map>
|
||||
<scroll-view class="scrollview" scroll-y="true">
|
||||
<button class="button" @click="reverseGeocode">reverseGeocode</button>
|
||||
<button class="button" @click="poiSearchNearBy">poiSearchNearBy</button>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 116.397477,39.908692
|
||||
let mapSearch = weex.requireModule('mapSearch')
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
markers: [{
|
||||
id: '1',
|
||||
latitude: 39.9086920000,
|
||||
longitude: 116.3974770000,
|
||||
title: '天安门',
|
||||
zIndex: '1',
|
||||
iconPath: '/static/gps.png',
|
||||
width: 20,
|
||||
height: 20,
|
||||
anchor: {
|
||||
x: 0.5,
|
||||
y: 1
|
||||
},
|
||||
callout: {
|
||||
content: '首都北京\n天安门',
|
||||
color: '#00BFFF',
|
||||
fontSize: 12,
|
||||
borderRadius: 2,
|
||||
borderWidth: 0,
|
||||
borderColor: '#333300',
|
||||
bgColor: '#CCFF11',
|
||||
padding: '1',
|
||||
display: 'ALWAYS'
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectPoint(e) {
|
||||
console.log(e);
|
||||
},
|
||||
reverseGeocode() {
|
||||
var point = this.markers[0]
|
||||
mapSearch.reverseGeocode({
|
||||
point: {
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude
|
||||
}
|
||||
}, ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
})
|
||||
},
|
||||
poiSearchNearBy() {
|
||||
var point = this.markers[0]
|
||||
mapSearch.poiSearchNearBy({
|
||||
point: {
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude
|
||||
},
|
||||
key: '停车场',
|
||||
radius: 1000
|
||||
}, ret => {
|
||||
console.log(ret);
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.map {
|
||||
width: 750rpx;
|
||||
height: 500rpx;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.scrollview {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<map class="map" id="map1" ref="map1" :controls="controls" :scale="scale" :longitude="location.longitude"
|
||||
:latitude="location.latitude" :show-location="showLocation" :enable-3D="enable3D" :rotate="rotate" :skew="skew"
|
||||
:show-compass="showCompass" :enable-overlooking="enableOverlooking" :enable-zoom="enableZoom"
|
||||
:enable-scroll="enableScroll" :enable-rotate="enableRotate" :enable-satellite="enableSatellite"
|
||||
:enable-traffic="enableTraffic" :markers="markers" :polyline="polyline" :circles="circles" :polygons="polygons"
|
||||
:include-points="includePoints" @tap="maptap" @controltap="oncontroltap" @markertap="onmarkertap"
|
||||
@callouttap="oncallouttap" @poitap="onpoitap" @updated="onupdated" @regionchange="onregionchange"></map>
|
||||
<scroll-view class="scrollview" scroll-y="true">
|
||||
<!-- <view class="list-item">
|
||||
<text class="list-text">显示3D楼块</text>
|
||||
<switch :checked="enable3D" @change="enableThreeD" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">显示指南针</text>
|
||||
<switch :checked="showCompass" @change="changeShowCompass" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">开启俯视</text>
|
||||
<switch :checked="enableOverlooking" @change="changeEnableOverlooking" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否支持缩放</text>
|
||||
<switch :checked="enableZoom" @change="changeEnableZoom" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否支持拖动</text>
|
||||
<switch :checked="enableScroll" @change="changeEnableScroll" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否支持旋转</text>
|
||||
<switch :checked="enableRotate" @change="changeEnableRotate" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否开启卫星图</text>
|
||||
<switch :checked="enableSatellite" @change="changeEnableSatellite" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否开启实时路况</text>
|
||||
<switch :checked="enableTraffic" @change="changeEnableTraffic" />
|
||||
</view> -->
|
||||
<!-- #ifndef MP-JD -->
|
||||
<button class="button" @click="changeScale">changeScale</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 || APP || MP-JD || MP-KUAISHOU -->
|
||||
<button class="button" @click="changeRotate">changeRotate</button>
|
||||
<button class="button" @click="changeSkew">changeSkew</button>
|
||||
<!-- #endif -->
|
||||
|
||||
<button class="button" @click="addMarkers">addMarkers</button>
|
||||
<button class="button" @click="addPolyline">addPolyline</button>
|
||||
<!-- #ifndef MP-JD -->
|
||||
<button class="button" @click="addPolygons">addPolygons</button>
|
||||
<!-- #endif -->
|
||||
<button class="button" @click="addCircles">addCircles</button>
|
||||
<button class="button" @click="includePoint">includePoints</button>
|
||||
<button class="button" @click="handleGetCenterLocation">getCenterLocation</button>
|
||||
<button class="button" @click="handleGetRegion">getRegion</button>
|
||||
<!-- #ifndef MP-JD -->
|
||||
<button class="button" @click="handleTranslateMarker">translateMarker</button>
|
||||
<!-- #endif -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const testMarkers = [{
|
||||
id: 0,
|
||||
latitude: 39.989631,
|
||||
longitude: 116.481018,
|
||||
title: '方恒国际 阜通东大街6号',
|
||||
zIndex: '1',
|
||||
rotate: 0,
|
||||
width: 20,
|
||||
height: 20,
|
||||
anchor: {
|
||||
x: 0.5,
|
||||
y: 1
|
||||
},
|
||||
callout: {
|
||||
content: '方恒国际 阜通东大街6号',
|
||||
color: '#00BFFF',
|
||||
fontSize: 10,
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
borderColor: '#333300',
|
||||
bgColor: '#CCFF99',
|
||||
padding: '5',
|
||||
display: 'ALWAYS'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
latitude: 39.9086920000,
|
||||
longitude: 116.3974770000,
|
||||
title: '天安门',
|
||||
zIndex: '1',
|
||||
iconPath: '/static/location.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
anchor: {
|
||||
x: 0.5,
|
||||
y: 1
|
||||
},
|
||||
callout: {
|
||||
content: '首都北京\n天安门',
|
||||
color: '#00BFFF',
|
||||
fontSize: 12,
|
||||
borderRadius: 2,
|
||||
borderWidth: 0,
|
||||
borderColor: '#333300',
|
||||
bgColor: '#CCFF11',
|
||||
padding: '1',
|
||||
display: 'ALWAYS'
|
||||
}
|
||||
}
|
||||
];
|
||||
const testPolyline = [{
|
||||
points: [{
|
||||
latitude: 39.925539,
|
||||
longitude: 116.279037
|
||||
},
|
||||
{
|
||||
latitude: 39.925539,
|
||||
longitude: 116.520285
|
||||
}
|
||||
],
|
||||
color: '#FFCCFF',
|
||||
width: 7,
|
||||
dottedLine: true,
|
||||
arrowLine: true,
|
||||
borderColor: '#000000',
|
||||
borderWidth: 2
|
||||
},
|
||||
{
|
||||
points: [{
|
||||
latitude: 39.938698,
|
||||
longitude: 116.275177
|
||||
},
|
||||
{
|
||||
latitude: 39.966069,
|
||||
longitude: 116.289253
|
||||
},
|
||||
{
|
||||
latitude: 39.944226,
|
||||
longitude: 116.306076
|
||||
},
|
||||
{
|
||||
latitude: 39.966069,
|
||||
longitude: 116.322899
|
||||
},
|
||||
{
|
||||
latitude: 39.938698,
|
||||
longitude: 116.336975
|
||||
}
|
||||
],
|
||||
color: '#CCFFFF',
|
||||
width: 5,
|
||||
dottedLine: true,
|
||||
arrowLine: true,
|
||||
borderColor: '#CC0000',
|
||||
borderWidth: 3
|
||||
}
|
||||
];
|
||||
const testPolygons = [{
|
||||
points: [{
|
||||
latitude: 39.781892,
|
||||
longitude: 116.293413
|
||||
},
|
||||
{
|
||||
latitude: 39.787600,
|
||||
longitude: 116.391842
|
||||
},
|
||||
{
|
||||
latitude: 39.733187,
|
||||
longitude: 116.417932
|
||||
},
|
||||
{
|
||||
latitude: 39.704653,
|
||||
longitude: 116.338255
|
||||
}
|
||||
],
|
||||
fillColor: '#FFCCFF',
|
||||
strokeWidth: 3,
|
||||
strokeColor: '#CC99CC',
|
||||
zIndex: 11
|
||||
},
|
||||
{
|
||||
points: [{
|
||||
latitude: 39.887600,
|
||||
longitude: 116.518932
|
||||
},
|
||||
{
|
||||
latitude: 39.781892,
|
||||
longitude: 116.518932
|
||||
},
|
||||
{
|
||||
latitude: 39.781892,
|
||||
longitude: 116.428932
|
||||
},
|
||||
{
|
||||
latitude: 39.887600,
|
||||
longitude: 116.428932
|
||||
}
|
||||
],
|
||||
fillColor: '#CCFFFF',
|
||||
strokeWidth: 5,
|
||||
strokeColor: '#CC0000',
|
||||
zIndex: 3
|
||||
}
|
||||
];
|
||||
const testCircles = [{
|
||||
latitude: 39.996441,
|
||||
longitude: 116.411146,
|
||||
radius: 15000,
|
||||
strokeWidth: 5,
|
||||
color: '#CCFFFF',
|
||||
fillColor: '#CC0000'
|
||||
},
|
||||
{
|
||||
latitude: 40.096441,
|
||||
longitude: 116.511146,
|
||||
radius: 12000,
|
||||
strokeWidth: 3,
|
||||
color: '#CCFFFF',
|
||||
fillColor: '#FFCCFF'
|
||||
},
|
||||
{
|
||||
latitude: 39.896441,
|
||||
longitude: 116.311146,
|
||||
radius: 9000,
|
||||
strokeWidth: 1,
|
||||
color: '#CCFFFF',
|
||||
fillColor: '#CC0000'
|
||||
}
|
||||
];
|
||||
const testIncludePoints = [{
|
||||
latitude: 39.989631,
|
||||
longitude: 116.481018,
|
||||
},
|
||||
{
|
||||
latitude: 39.9086920000,
|
||||
longitude: 116.3974770000,
|
||||
}
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
location: {
|
||||
longitude: 116.3974770000,
|
||||
latitude: 39.9086920000
|
||||
},
|
||||
controls: [{
|
||||
id: 1,
|
||||
position: {
|
||||
left: 5,
|
||||
top: 180,
|
||||
width: 30,
|
||||
height: 30
|
||||
},
|
||||
iconPath: '/static/logo.png',
|
||||
clickable: true
|
||||
}],
|
||||
showLocation: false,
|
||||
scale: 13,
|
||||
showCompass: true,
|
||||
enable3D: true,
|
||||
enableOverlooking: true,
|
||||
enableZoom: true,
|
||||
enableScroll: true,
|
||||
enableRotate: true,
|
||||
enableSatellite: false,
|
||||
enableTraffic: false,
|
||||
polyline: [],
|
||||
markers: [],
|
||||
polygons: [],
|
||||
circles: [],
|
||||
includePoints: [],
|
||||
rotate: 0,
|
||||
skew: 0
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onReady() {
|
||||
this.map = uni.createMapContext("map1", this);
|
||||
},
|
||||
methods: {
|
||||
// #ifndef MP-JD
|
||||
changeScale() {
|
||||
this.scale = this.scale == 9 ? 15 : 9;
|
||||
},
|
||||
changeRotate() {
|
||||
this.rotate = this.rotate == 90 ? 0 : 90;
|
||||
},
|
||||
changeSkew() {
|
||||
this.skew = this.skew == 30 ? 0 : 30;
|
||||
},
|
||||
// #endif
|
||||
enableThreeD(e) {
|
||||
this.enable3D = e.detail.value;
|
||||
},
|
||||
changeShowCompass(e) {
|
||||
this.showCompass = e.detail.value;
|
||||
},
|
||||
changeEnableOverlooking(e) {
|
||||
this.enableOverlooking = e.detail.value;
|
||||
},
|
||||
changeEnableZoom(e) {
|
||||
this.enableZoom = e.detail.value;
|
||||
},
|
||||
changeEnableScroll(e) {
|
||||
this.enableScroll = e.detail.value;
|
||||
},
|
||||
changeEnableRotate(e) {
|
||||
this.enableRotate = e.detail.value;
|
||||
},
|
||||
changeEnableSatellite(e) {
|
||||
this.enableSatellite = e.detail.value;
|
||||
},
|
||||
changeEnableTraffic(e) {
|
||||
this.enableTraffic = e.detail.value;
|
||||
},
|
||||
addMarkers() {
|
||||
this.markers = testMarkers;
|
||||
},
|
||||
addPolyline() {
|
||||
this.polyline = testPolyline;
|
||||
},
|
||||
// #ifndef MP-JD
|
||||
addPolygons() {
|
||||
this.polygons = testPolygons;
|
||||
},
|
||||
// #endif
|
||||
addCircles() {
|
||||
this.circles = testCircles;
|
||||
},
|
||||
includePoint() {
|
||||
this.includePoints = testIncludePoints;
|
||||
},
|
||||
handleGetCenterLocation() {
|
||||
this.map.getCenterLocation({
|
||||
success: ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleGetRegion() {
|
||||
this.map.getRegion({
|
||||
success: ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// #ifndef MP-JD
|
||||
handleTranslateMarker() {
|
||||
this.map.translateMarker({
|
||||
markerId: 1,
|
||||
destination: {
|
||||
latitude: 39.989631,
|
||||
longitude: 116.481018
|
||||
},
|
||||
duration: 2000
|
||||
}, ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
});
|
||||
},
|
||||
// #endif
|
||||
maptap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
onmarkertap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
oncontroltap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
oncallouttap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
onupdated(e) {
|
||||
console.log(JSON.stringify(e))
|
||||
},
|
||||
onregionchange(e) {
|
||||
console.log(JSON.stringify(e));
|
||||
},
|
||||
onpoitap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.map {
|
||||
width: 750rpx;
|
||||
/* #ifdef H5 */
|
||||
width: 100%;
|
||||
/* #endif */
|
||||
height: 350px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.scrollview {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
padding: 5px 0px;
|
||||
}
|
||||
|
||||
.list-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button type="default" @tap="modalTap">有标题的modal</button>
|
||||
<button type="default" @tap="noTitlemodalTap">无标题的modal</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'modal',
|
||||
modalHidden: true,
|
||||
modalHidden2: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
modalTap: function (e) {
|
||||
uni.showModal({
|
||||
title: "弹窗标题",
|
||||
content: "弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内",
|
||||
showCancel: false,
|
||||
confirmText: "确定"
|
||||
})
|
||||
},
|
||||
noTitlemodalTap: function (e) {
|
||||
uni.showModal({
|
||||
content: "弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内",
|
||||
confirmText: "确定",
|
||||
cancelText: "取消"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button @tap="navigateTo">跳转新页面,并传递数据</button>
|
||||
<button @tap="navigateBack">返回上一页</button>
|
||||
<button @tap="redirectTo">在当前页面打开</button>
|
||||
<button @tap="switchTab">切换到模板选项卡</button>
|
||||
<button v-if="!hasLeftWin" @tap="reLaunch">关闭所有页面,打开首页</button>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button @tap="customAnimation">使用自定义动画打开页面</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS || H5 -->
|
||||
<button @tap="preloadPage">预载复杂页面</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button @tap="unPreloadPage">取消页面预载</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS || H5 -->
|
||||
<button @tap="navigateToPreloadPage">打开复杂页面</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const preloadPageUrl = '/pages/extUI/calendar/calendar'
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'navigate'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
hasLeftWin: state => !state.noMatchLeftWindow
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
navigateTo() {
|
||||
uni.navigateTo({
|
||||
url: 'new-page/new-vue-page-1?data=Hello'
|
||||
})
|
||||
},
|
||||
navigateBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
redirectTo() {
|
||||
uni.redirectTo({
|
||||
url: 'new-page/new-vue-page-1'
|
||||
});
|
||||
},
|
||||
switchTab() {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabBar/template/template'
|
||||
});
|
||||
},
|
||||
reLaunch() {
|
||||
if (this.hasLeftWin) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/component/view/view'
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.reLaunch({
|
||||
url: '/pages/tabBar/component/component'
|
||||
});
|
||||
},
|
||||
customAnimation(){
|
||||
uni.navigateTo({
|
||||
url: 'new-page/new-vue-page-1?data=使用自定义动画打开页面',
|
||||
animationType: 'slide-in-bottom',
|
||||
animationDuration: 200
|
||||
})
|
||||
},
|
||||
preloadPage(){
|
||||
uni.preloadPage({
|
||||
url: preloadPageUrl,
|
||||
success(){
|
||||
uni.showToast({
|
||||
title:'页面预载成功'
|
||||
})
|
||||
},
|
||||
fail(e){
|
||||
console.error(e);
|
||||
uni.showToast({
|
||||
title:'页面预载失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
unPreloadPage(){
|
||||
uni.unPreloadPage({
|
||||
url: preloadPageUrl
|
||||
})
|
||||
},
|
||||
navigateToPreloadPage(){
|
||||
uni.navigateTo({
|
||||
url: preloadPageUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<view class="page-body">
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
<view class="new-page__button">
|
||||
<button class="new-page__button-item" @click="navToNvue">跳转NVUE页面</button>
|
||||
<button class="new-page__button-item" @click="navToVue">跳转VUE页面</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState,mapGetters,mapMutations} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState(['colorIndex','colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
methods:{
|
||||
...mapMutations(['setColorIndex']),
|
||||
navToNvue(){
|
||||
uni.navigateTo({
|
||||
url:'new-nvue-page-2'
|
||||
})
|
||||
},
|
||||
navToVue(){
|
||||
uni.navigateTo({
|
||||
url:'new-vue-page-2'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root{
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body{
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.new-page__text-box{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color{
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text{
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item{
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<view class="page-body">
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState,mapGetters,mapMutations} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState(['colorIndex','colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
methods:{
|
||||
...mapMutations(['setColorIndex'])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root{
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body{
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.new-page__text-box{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color{
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text{
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item{
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="page-body">
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">从上个页面接收到参数:{{data}}</text>
|
||||
</view>
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
<view class="new-page__button">
|
||||
<!-- #ifndef VUE3-->
|
||||
<button class="new-page__button-item" @click="navToNvue">跳转NVUE页面</button>
|
||||
<!-- #endif -->
|
||||
<button class="new-page__button-item" @click="navToVue">跳转VUE页面</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState,mapGetters,mapMutations} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '新页面',
|
||||
data:""
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState(['colorIndex','colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
onLoad(e){
|
||||
if(e.data){
|
||||
this.data = e.data;
|
||||
}
|
||||
uni.$on('postMsg',(res)=>{
|
||||
uni.showModal({
|
||||
content: `收到uni.$emit消息:${res.msg}`,
|
||||
showCancel: false
|
||||
})
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('postMsg')
|
||||
},
|
||||
methods:{
|
||||
...mapMutations(['setColorIndex']),
|
||||
navToNvue(){
|
||||
uni.navigateTo({
|
||||
url:'new-nvue-page-1'
|
||||
})
|
||||
},
|
||||
navToVue(){
|
||||
uni.navigateTo({
|
||||
url:'new-vue-page-2'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root{
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body{
|
||||
/* flex: 1; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__text-box{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color{
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text{
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item{
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<view class="page-body">
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
<view class="new-page__button">
|
||||
<button class="new-page__button-item" @click="emitMsg">向上一页面传递数据</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapGetters,
|
||||
mapMutations
|
||||
} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['colorIndex', 'colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setColorIndex']),
|
||||
emitMsg() {
|
||||
uni.$emit('postMsg', {
|
||||
msg: 'From: Vue Page'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.new-page__text-box {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color {
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text {
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item {
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="uni-btn-v">
|
||||
<button class="shake" @tap="shake">摇一摇</button>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="watchAcce">监听设备的加速度变化</button>
|
||||
<button type="primary" @tap="stopAcce">停止监听设备的加速度变化</button>
|
||||
</view>
|
||||
<view class="uni-textarea uni-common-mt">
|
||||
<textarea class="acc-show" :value="value" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'onAccelerometerChange',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.stopAccelerometer();
|
||||
},
|
||||
methods: {
|
||||
//#ifdef APP-PLUS
|
||||
shake() {
|
||||
uni.navigateTo({
|
||||
url: '/platforms/app-plus/shake/shake'
|
||||
})
|
||||
},
|
||||
//#endif
|
||||
watchAcce() {
|
||||
uni.onAccelerometerChange((res) => {
|
||||
this.value = "监听设备的加速度变化:\n" + "X轴:" + res.x.toFixed(2) + "\nY轴:" + res.y.toFixed(2) +
|
||||
"\nZ轴:" + res.z.toFixed(2);
|
||||
})
|
||||
},
|
||||
stopAcce() {
|
||||
uni.stopAccelerometer()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.shake {
|
||||
background-color: #FFCC33;
|
||||
color: #ffffff;
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
.uni-textarea .acc-show{
|
||||
height: 240rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-hello-text uni-center" style="padding-bottom:50rpx;">
|
||||
旋转手机即可获取方位信息
|
||||
</view>
|
||||
<view class="direction">
|
||||
<view class="bg-compass-line"></view>
|
||||
<image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'"></image>
|
||||
<view class="direction-value">
|
||||
<text>{{direction}}</text>
|
||||
<text class="direction-degree">o</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'onCompassChange',
|
||||
direction: 0
|
||||
}
|
||||
},
|
||||
onReady: function () {
|
||||
uni.onCompassChange((res) => {
|
||||
this.direction = parseInt(res.direction)
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
// #ifndef MP-ALIPAY
|
||||
uni.stopCompass();
|
||||
this.direction = 0;
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
uni.offCompassChange();
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.direction {
|
||||
position: relative;
|
||||
margin-top: 70rpx;
|
||||
display: flex;
|
||||
width: 540rpx;
|
||||
height: 540rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.direction-value {
|
||||
position: relative;
|
||||
font-size: 200rpx;
|
||||
color: #353535;
|
||||
line-height: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.direction-degree {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -40rpx;
|
||||
font-size: 60rpx;
|
||||
}
|
||||
|
||||
.bg-compass {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 540rpx;
|
||||
height: 540rpx;
|
||||
transition: .1s;
|
||||
}
|
||||
|
||||
.bg-compass-line {
|
||||
position: absolute;
|
||||
left: 267rpx;
|
||||
top: -10rpx;
|
||||
width: 6rpx;
|
||||
height: 56rpx;
|
||||
background-color: #1AAD19;
|
||||
border-radius: 999rpx;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<form @submit="openLocation">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">经度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="116.39747" name="longitude"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">纬度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="39.9085" name="latitude"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">位置名称</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="天安门" name="name"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">详细位置</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="北京市东城区东长安街" name="address"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" formType="submit">查看位置</button>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'openLocation'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openLocation: function (e) {
|
||||
console.log(e)
|
||||
var value = e.detail.value
|
||||
uni.openLocation({
|
||||
longitude: Number(value.longitude),
|
||||
latitude: Number(value.latitude),
|
||||
name: value.name,
|
||||
address: value.address
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-list-cell-left {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view style="font-size: 12px; color: #666;">注:PC 不支持下拉刷新</view>
|
||||
<view class="text" v-for="(num,index) in data" :key="index">list - {{num}}</view>
|
||||
<view class="uni-loadmore" v-if="showLoadMore">{{loadMoreText}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '下拉刷新 + 加载更多',
|
||||
data: [],
|
||||
loadMoreText: "加载中...",
|
||||
showLoadMore: false,
|
||||
max: 0
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.initData();
|
||||
},
|
||||
onUnload() {
|
||||
this.max = 0,
|
||||
this.data = [],
|
||||
this.loadMoreText = "加载更多",
|
||||
this.showLoadMore = false;
|
||||
},
|
||||
onReachBottom() {
|
||||
console.log("onReachBottom");
|
||||
if (this.max > 40) {
|
||||
this.loadMoreText = "没有更多数据了!"
|
||||
return;
|
||||
}
|
||||
this.showLoadMore = true;
|
||||
setTimeout(() => {
|
||||
this.setListData();
|
||||
}, 300);
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
console.log('onPullDownRefresh');
|
||||
this.initData();
|
||||
},
|
||||
methods: {
|
||||
initData(){
|
||||
setTimeout(() => {
|
||||
this.max = 0;
|
||||
this.data = [];
|
||||
let data = [];
|
||||
this.max += 20;
|
||||
for (var i = this.max - 19; i < this.max + 1; i++) {
|
||||
data.push(i)
|
||||
}
|
||||
this.data = this.data.concat(data);
|
||||
uni.stopPullDownRefresh();
|
||||
}, 300);
|
||||
},
|
||||
setListData() {
|
||||
let data = [];
|
||||
this.max += 10;
|
||||
for (var i = this.max - 9; i < this.max + 1; i++) {
|
||||
data.push(i)
|
||||
}
|
||||
this.data = this.data.concat(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.text {
|
||||
margin: 16rpx 0;
|
||||
width:100%;
|
||||
background-color: #fff;
|
||||
height: 120rpx;
|
||||
line-height: 120rpx;
|
||||
text-align: center;
|
||||
color: #555;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFF; padding:50rpx 0;">
|
||||
<view class="uni-hello-text uni-center"><text>支付金额</text></view>
|
||||
<view class="uni-h1 uni-center uni-common-mt">
|
||||
<text class="rmbLogo">¥</text>
|
||||
<input class="price" type="digit" :value="price" maxlength="4" @input="priceChange" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button type="primary" @click="weixinPay" :loading="loading">微信支付</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<template v-if="providerList.length > 0">
|
||||
<button v-for="(item,index) in providerList" :key="index" @click="requestPayment(item,index)" :loading="item.loading">{{item.name}}支付</button>
|
||||
</template>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'request-payment',
|
||||
loading: false,
|
||||
price: 1,
|
||||
providerList: []
|
||||
}
|
||||
},
|
||||
onLoad: function() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.getProvider({
|
||||
service: "payment",
|
||||
success: (e) => {
|
||||
console.log("payment success:" + JSON.stringify(e));
|
||||
let providerList = [];
|
||||
e.provider.map((value) => {
|
||||
switch (value) {
|
||||
case 'alipay':
|
||||
providerList.push({
|
||||
name: '支付宝',
|
||||
id: value,
|
||||
loading: false
|
||||
});
|
||||
break;
|
||||
case 'wxpay':
|
||||
providerList.push({
|
||||
name: '微信',
|
||||
id: value,
|
||||
loading: false
|
||||
});
|
||||
break;
|
||||
case 'huawei':
|
||||
providerList.push({
|
||||
name: '华为',
|
||||
id: value,
|
||||
loading: false
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})
|
||||
this.providerList = providerList;
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log("获取支付通道失败:", e);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
loginMpWeixin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success(res) {
|
||||
console.warn('此处使用uni-id处理微信小程序登录,详情参考: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
|
||||
uni.request({
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'loginByWeixin',
|
||||
params: {
|
||||
code: res.code,
|
||||
platform: 'mp-weixin'
|
||||
}
|
||||
},
|
||||
success(res) {
|
||||
if (res.data.code !== 0) {
|
||||
reject(new Error('获取openid失败:', res.result.msg))
|
||||
return
|
||||
}
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
resolve(res.data.openid)
|
||||
},
|
||||
fail(err) {
|
||||
reject(new Error('获取openid失败:' + err))
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async weixinPay() {
|
||||
let openid = uni.getStorageSync('openid')
|
||||
console.log("发起支付");
|
||||
this.loading = true;
|
||||
if (!openid) {
|
||||
try {
|
||||
openid = await this.loginMpWeixin()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
||||
if (!openid) {
|
||||
uni.showModal({
|
||||
content: '获取openid失败',
|
||||
showCancel: false
|
||||
})
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
}
|
||||
this.openid = openid
|
||||
let orderInfo = await this.getOrderInfo('wxpay')
|
||||
if (!orderInfo) {
|
||||
uni.showModal({
|
||||
content: '获取支付信息失败',
|
||||
showCancel: false
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.requestPayment({
|
||||
...orderInfo,
|
||||
success: (res) => {
|
||||
uni.showToast({
|
||||
title: "感谢您的赞助!"
|
||||
})
|
||||
},
|
||||
fail: (res) => {
|
||||
uni.showModal({
|
||||
content: "支付失败,原因为: " + res
|
||||
.errMsg,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
async requestPayment(e, index) {
|
||||
this.providerList[index].loading = true;
|
||||
const provider = e.id
|
||||
let orderInfo = await this.getOrderInfo(provider);
|
||||
if (!orderInfo) {
|
||||
uni.showModal({
|
||||
content: '获取支付信息失败',
|
||||
showCancel: false
|
||||
})
|
||||
return
|
||||
}
|
||||
console.log('--------orderInfo--------')
|
||||
console.log(orderInfo);
|
||||
uni.requestPayment({
|
||||
provider,
|
||||
orderInfo: orderInfo,
|
||||
success: (e) => {
|
||||
console.log("success", e);
|
||||
uni.showToast({
|
||||
title: "感谢您的赞助!"
|
||||
})
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log("fail", e);
|
||||
uni.showModal({
|
||||
content: "支付失败,原因为: " + e.errMsg,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
complete: () => {
|
||||
this.providerList[index].loading = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
getOrderInfo(provider) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.price) {
|
||||
reject(new Error('请输入金额'))
|
||||
}
|
||||
console.warn('此处使用uni-pay处理支付,详情参考: https://uniapp.dcloud.io/uniCloud/unipay')
|
||||
uni.request({
|
||||
method: 'POST',
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/pay',
|
||||
data: {
|
||||
provider,
|
||||
openid: this.openid,
|
||||
totalFee: Number(this.price) * 100, // 转为以分为单位
|
||||
// #ifdef APP-PLUS
|
||||
platform: 'app-plus',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
platform: 'mp-weixin',
|
||||
// #endif
|
||||
},
|
||||
success(res) {
|
||||
if (res.data.code === 0) {
|
||||
resolve(res.data.orderInfo)
|
||||
} else {
|
||||
reject(new Error('获取支付信息失败' + res.data.msg))
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
reject(new Error('请求支付接口失败' + err))
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
priceChange(e) {
|
||||
console.log(e.detail.value)
|
||||
this.price = e.detail.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.rmbLogo {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.uni-h1.uni-center {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.price {
|
||||
border-bottom: 1px solid #eee;
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
padding-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.ipaPayBtn {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-hello-text">
|
||||
请点击按钮向服务器发起请求
|
||||
</view>
|
||||
<view class="uni-textarea uni-common-mt">
|
||||
<textarea :value="res"></textarea>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" @click="sendRequest" :loading="loading">发起请求(Callback)</button>
|
||||
<button type="primary" @click="sendRequest('promise')" :loading="loading">发起请求(Promise)</button>
|
||||
<button type="primary" @click="sendRequest('await')" :loading="loading">发起请求(Async/Await)</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const requestUrl = 'https://unidemo.dcloud.net.cn/ajax/echo/text?name=uni-app'
|
||||
const duration = 2000
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'request',
|
||||
loading: false,
|
||||
res: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendRequest(mode) {
|
||||
this.loading = true;
|
||||
switch (mode) {
|
||||
case 'promise':
|
||||
this._requestPromise();
|
||||
break;
|
||||
case 'await':
|
||||
this._requestAwait();
|
||||
break;
|
||||
default:
|
||||
this._request();
|
||||
break;
|
||||
}
|
||||
},
|
||||
_request() {
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('request success', res)
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
_requestPromise() {
|
||||
// #ifndef VUE3
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
}).then(res => {
|
||||
console.log('request success', res[1]);
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res[1]);
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
}).then(res => {
|
||||
console.log('request success', res);
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res);
|
||||
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
async _requestAwait() {
|
||||
let res, err
|
||||
// #ifndef VUE3
|
||||
[err, res] = await uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
try {
|
||||
res = await uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
});
|
||||
} catch(e){
|
||||
err=e
|
||||
}
|
||||
// #endif
|
||||
if (err) {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
} else {
|
||||
console.log('request success', res)
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res);
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<button v-if="!loadError" :loading="loading" :disabled="loading" type="primary" class="btn" @click="show">显示广告</button>
|
||||
<button v-if="loadError" :loading="loading" :disabled="loading" type="primary" class="btn" @click="reloadAd">重新加载广告</button>
|
||||
</view>
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<view class="ad-tips">
|
||||
<text>小程序端的广告ID由小程序平台提供</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const ERROR_CODE = [-5001, -5002, -5003, -5004, -5005, -5006];
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '激励视频广告',
|
||||
loading: false,
|
||||
loadError: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// #ifdef APP-PLUS
|
||||
this.adOption = {
|
||||
adpid: '1507000689'
|
||||
};
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
this.adOption = {
|
||||
adUnitId: ''
|
||||
};
|
||||
// #endif
|
||||
this.createAd();
|
||||
},
|
||||
methods: {
|
||||
createAd() {
|
||||
var rewardedVideoAd = this.rewardedVideoAd = uni.createRewardedVideoAd(this.adOption);
|
||||
rewardedVideoAd.onLoad(() => {
|
||||
this.loading = false;
|
||||
this.loadError = false;
|
||||
console.log('onLoad event')
|
||||
});
|
||||
rewardedVideoAd.onClose((res) => {
|
||||
this.loading = true;
|
||||
// 用户点击了【关闭广告】按钮
|
||||
if (res && res.isEnded) {
|
||||
// 正常播放结束
|
||||
console.log("onClose " + res.isEnded);
|
||||
} else {
|
||||
// 播放中途退出
|
||||
console.log("onClose " + res.isEnded);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: "激励视频" + (res.isEnded ? "成功" : "未") + "播放完毕",
|
||||
duration: 10000,
|
||||
position: 'bottom'
|
||||
})
|
||||
}, 500)
|
||||
});
|
||||
rewardedVideoAd.onError((err) => {
|
||||
this.loading = false;
|
||||
if (err.code && ERROR_CODE.indexOf(err.code) !== -1) {
|
||||
this.loadError = true;
|
||||
}
|
||||
console.log('onError event', err)
|
||||
});
|
||||
this.loading = true;
|
||||
},
|
||||
show() {
|
||||
const rewardedVideoAd = this.rewardedVideoAd;
|
||||
rewardedVideoAd.show().catch(() => {
|
||||
rewardedVideoAd.load()
|
||||
.then(() => rewardedVideoAd.show())
|
||||
.catch(err => {
|
||||
console.log('激励视频 广告显示失败', err)
|
||||
uni.showToast({
|
||||
title: err.errMsg || err.message,
|
||||
duration: 5000,
|
||||
position: 'bottom'
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
reloadAd() {
|
||||
this.loading = true;
|
||||
this.rewardedVideoAd.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ad-tips {
|
||||
color: #999;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view v-if="imagePath !== ''" class="media-box image">
|
||||
<image class="image" mode="widthFix" :src="imagePath" />
|
||||
</view>
|
||||
<button type="primary" class="uni-button" @click="saveImage">拍摄图片并保存到本地</button>
|
||||
<view v-if="videoPath !== ''" class="media-box">
|
||||
<video
|
||||
id="myVideo"
|
||||
:src="videoPath"
|
||||
@error="videoErrorCallback"
|
||||
enable-danmu
|
||||
danmu-btn
|
||||
controls
|
||||
></video>
|
||||
</view>
|
||||
<button type="primary" class="uni-button" @click="saveVideo">录制视频并保存到本地</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'saveImage/saveVideo',
|
||||
imagePath: '',
|
||||
videoPath: ''
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
videoErrorCallback: function() {
|
||||
uni.showModal({
|
||||
content: '视频加载失败',
|
||||
showCancel: false
|
||||
});
|
||||
},
|
||||
saveImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sourceType: ['camera'],
|
||||
success: res => {
|
||||
this.imagePath = res.tempFilePaths[0];
|
||||
this.getTempFilePath(res.tempFilePaths[0], 'imageTempPath');
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
},
|
||||
saveVideo() {
|
||||
let _this = this;
|
||||
uni.chooseVideo({
|
||||
count: 1,
|
||||
sourceType: ['camera'],
|
||||
success: res => {
|
||||
console.log(res.tempFilePath)
|
||||
this.videoPath = res.tempFilePath;
|
||||
this.getTempFilePath(res.tempFilePath, 'videoTempPath');
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机获取视频,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getTempFilePath(url, types) {
|
||||
// 如果已经下载本地路径,那么直接储存
|
||||
let obj = {
|
||||
filePath: url,
|
||||
success: () => {
|
||||
console.log('save success');
|
||||
uni.showModal({
|
||||
content: '保存成功',
|
||||
showCancel: false
|
||||
});
|
||||
uni.hideLoading();
|
||||
},
|
||||
fail: e => {
|
||||
uni.hideLoading();
|
||||
uni.showModal({
|
||||
content: '保存失败',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
};
|
||||
uni.showLoading({
|
||||
title: '保存中...'
|
||||
});
|
||||
if (types === 'videoTempPath') {
|
||||
uni.saveVideoToPhotosAlbum(obj);
|
||||
} else {
|
||||
uni.saveImageToPhotosAlbum(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.media-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 30rpx 0;
|
||||
width: 100%;
|
||||
}
|
||||
.image {
|
||||
height: 400rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.image image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
video {
|
||||
width: 100%;
|
||||
}
|
||||
.uni-button {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-title">扫码结果:</view>
|
||||
<view class="uni-list" v-if="result">
|
||||
<view class="uni-cell">
|
||||
<view class="scan-result">
|
||||
{{result}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="scan">扫一扫</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import permision from "@/common/permission.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'scanCode',
|
||||
result: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async scan() {
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
uni.scanCode({
|
||||
success: (res) => {
|
||||
this.result = res.result
|
||||
},
|
||||
fail: (err) => {
|
||||
// 需要注意的是小程序扫码不需要申请相机权限
|
||||
}
|
||||
});
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
,
|
||||
async checkPermission(code) {
|
||||
let status = permision.isIOS ? await permision.requestIOS('camera') :
|
||||
await permision.requestAndroid('android.permission.CAMERA');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要相机权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return status;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.scan-result {
|
||||
min-height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
describe('pages/API/set-navigation-bar-title/set-navigation-bar-title.vue', () => {
|
||||
let page
|
||||
beforeAll(async () => {
|
||||
// 重新reLaunch至首页,并获取首页page对象(其中 program 是uni-automator自动注入的全局对象)
|
||||
page = await program.reLaunch('/pages/API/set-navigation-bar-title/set-navigation-bar-title')
|
||||
const waitTime = process.env.UNI_PLATFORM === "mp-weixin" ? 10000 : 5000
|
||||
await page.waitFor(waitTime)
|
||||
page = await program.currentPage()
|
||||
})
|
||||
it('set-navigation-bar-title 组件标题', async () => {
|
||||
let view = await page.$('.common-page-head-title')
|
||||
expect(await view.text()).toBe('nav-default')
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<view class="page">
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-helllo-text">
|
||||
本页标题栏是uni-app的默认配置,开发者可在pages.json里配置文字内容及标题颜色,也可通过api接口将其改变。
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="default" @click="setText">改变标题栏文字</button>
|
||||
<button type="primary" @click="setBg">改变标题栏颜色</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'nav-default',
|
||||
hasSetText:false,
|
||||
hasSetBg:false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setText() {
|
||||
this.hasSetText = !this.hasSetText;
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.hasSetText ? "Hello uni-app" : "默认导航栏"
|
||||
})
|
||||
},
|
||||
setBg() {
|
||||
this.hasSetBg = !this.hasSetBg;
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: this.hasSetBg ? "#000000" : "#ffffff",
|
||||
backgroundColor: this.hasSetBg ? "#F8F8F8" : "#007AFF"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-title">分享内容</view>
|
||||
<view class="uni-textarea">
|
||||
<textarea class="textarea" v-model="shareText" />
|
||||
</view>
|
||||
<view class="uni-title">分享图片:</view>
|
||||
<view class="uni-uploader" style="padding:15rpx; background:#FFF;">
|
||||
<view class="uni-uploader__input-box" v-if="!image" @tap="chooseImage"></view>
|
||||
<image class="uni-uploader__img" v-if="image" :src="image"></image>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="uni-title">分享类型:</view>
|
||||
<view>
|
||||
<radio-group @change="radioChange">
|
||||
<label class="radio">
|
||||
<radio value="1" checked="true"/>文字
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio value="2" />图片
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio value="0" />图文
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio value="5" />小程序
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt" v-if="providerList.length > 0">
|
||||
<block v-for="(value,index) in providerList" :key="index">
|
||||
<button type="primary" v-if="value" :disabled="isDisableButton(value)" @tap="share(value)">{{value.name}}</button>
|
||||
</block>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP || QUICKAPP-WEBVIEW -->
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" open-type="share">分享</button>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'share',
|
||||
shareText: 'uni-app可以同时发布成原生App、小程序、H5,邀请你一起体验!',
|
||||
href:"https://uniapp.dcloud.io",
|
||||
image: '',
|
||||
shareType:1,
|
||||
providerList: []
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
isDisableButton() {
|
||||
return function(item) {
|
||||
if(this.shareType === 0 && item.id === 'qq'){
|
||||
return true;
|
||||
}
|
||||
if(this.shareType === 5 && item.name !== '分享到微信好友'){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: this.shareText ? this.shareText : "欢迎体验uni-app",
|
||||
path: '/pages/tabBar/component/component',
|
||||
imageUrl:this.image ? this.image : 'https://web-assets.dcloud.net.cn/unidoc/zh/share-logo@3.png'
|
||||
}
|
||||
},
|
||||
onUnload:function(){
|
||||
this.shareText='uni-app可以同时发布成原生App、小程序、H5,邀请你一起体验!',
|
||||
this.href = 'https://uniapp.dcloud.io',
|
||||
this.image='';
|
||||
},
|
||||
onLoad: function () {
|
||||
uni.getProvider({
|
||||
service: 'share',
|
||||
success: (e) => {
|
||||
console.log('success', e);
|
||||
let data = []
|
||||
for (let i = 0; i < e.provider.length; i++) {
|
||||
switch (e.provider[i]) {
|
||||
case 'weixin':
|
||||
data.push({
|
||||
name: '分享到微信好友',
|
||||
id: 'weixin',
|
||||
sort:0
|
||||
})
|
||||
data.push({
|
||||
name: '分享到微信朋友圈',
|
||||
id: 'weixin',
|
||||
type:'WXSenceTimeline',
|
||||
sort:1
|
||||
})
|
||||
break;
|
||||
case 'sinaweibo':
|
||||
data.push({
|
||||
name: '分享到新浪微博',
|
||||
id: 'sinaweibo',
|
||||
sort:2
|
||||
})
|
||||
break;
|
||||
case 'qq':
|
||||
data.push({
|
||||
name: '分享到QQ',
|
||||
id: 'qq',
|
||||
sort:3
|
||||
})
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.providerList = data.sort((x,y) => {
|
||||
return x.sort - y.sort
|
||||
});
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log('获取分享通道失败', e);
|
||||
uni.showModal({
|
||||
content:'获取分享通道失败',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async share(e) {
|
||||
console.log('分享通道:'+ e.id +'; 分享类型:' + this.shareType);
|
||||
|
||||
if(!this.shareText && (this.shareType === 1 || this.shareType === 0)){
|
||||
uni.showModal({
|
||||
content:'分享内容不能为空',
|
||||
showCancel:false
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this.image && (this.shareType === 2 || this.shareType === 0)){
|
||||
uni.showModal({
|
||||
content:'分享图片不能为空',
|
||||
showCancel:false
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
let shareOPtions = {
|
||||
provider: e.id,
|
||||
scene: e.type && e.type === 'WXSceneTimeline' ? 'WXSceneTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面,“WXSceneTimeline”分享到朋友圈,“WXSceneFavorite”分享到微信收藏
|
||||
type: this.shareType,
|
||||
success: (e) => {
|
||||
console.log('success', e);
|
||||
uni.showModal({
|
||||
content: '已分享',
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log('fail', e)
|
||||
uni.showModal({
|
||||
content: e.errMsg,
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
complete:function(){
|
||||
console.log('分享操作结束!')
|
||||
}
|
||||
}
|
||||
|
||||
switch (this.shareType){
|
||||
case 0:
|
||||
shareOPtions.summary = this.shareText;
|
||||
shareOPtions.imageUrl = this.image;
|
||||
shareOPtions.title = '欢迎体验uniapp';
|
||||
shareOPtions.href = 'https://uniapp.dcloud.io';
|
||||
break;
|
||||
case 1:
|
||||
shareOPtions.summary = this.shareText;
|
||||
break;
|
||||
case 2:
|
||||
shareOPtions.imageUrl = this.image;
|
||||
break;
|
||||
case 5:
|
||||
shareOPtions.imageUrl = this.image ? this.image : 'https://web-ext-storage.dcloud.net.cn/hello-uni-app/share.png'
|
||||
shareOPtions.title = '欢迎体验uniapp';
|
||||
shareOPtions.miniProgram = {
|
||||
id:'gh_33446d7f7a26',
|
||||
path:'/pages/tabBar/component/component',
|
||||
webUrl:'https://uniapp.dcloud.io',
|
||||
type:0
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享,且是ios平台,则压缩图片
|
||||
shareOPtions.imageUrl = await this.compress();
|
||||
}
|
||||
if(shareOPtions.type === 1 && shareOPtions.provider === 'qq'){//如果是分享文字到qq,则必须加上href和title
|
||||
shareOPtions.href = 'https://uniapp.dcloud.io';
|
||||
shareOPtions.title = '欢迎体验uniapp';
|
||||
}
|
||||
uni.share(shareOPtions);
|
||||
},
|
||||
radioChange(e){
|
||||
console.log('type:' + e.detail.value);
|
||||
this.shareType = parseInt(e.detail.value);
|
||||
},
|
||||
chooseImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sourceType: ['album', 'camera'],
|
||||
sizeType: ['compressed', 'original'],
|
||||
success: (res) => {
|
||||
this.image = res.tempFilePaths[0];
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
compress(){//压缩图片 图文分享要求分享图片大小不能超过20Kb
|
||||
console.log('开始压缩');
|
||||
let img = this.image;
|
||||
return new Promise((res) => {
|
||||
var localPath = plus.io.convertAbsoluteFileSystem(img.replace('file://', ''));
|
||||
console.log('after' + localPath);
|
||||
// 压缩size
|
||||
plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
|
||||
entry.file((file) => {// 可通过entry对象操作图片
|
||||
console.log('getFile:' + JSON.stringify(file));
|
||||
if(file.size > 20480) {// 压缩后size 大于20Kb
|
||||
plus.zip.compressImage({
|
||||
src: img,
|
||||
dst: img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG'),
|
||||
width: '10%',
|
||||
height: '10%',
|
||||
quality: 1,
|
||||
overwrite: true
|
||||
}, (event) => {
|
||||
console.log('success zip****' + event.size);
|
||||
let newImg = img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG');
|
||||
res(newImg);
|
||||
}, function(error) {
|
||||
uni.showModal({
|
||||
content:'分享图片太大,需要请重新选择图片!',
|
||||
showCancel:false
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
}, (e) => {
|
||||
console.log('Resolve file URL failed: ' + e.message);
|
||||
uni.showModal({
|
||||
content:'分享图片太大,需要请重新选择图片!',
|
||||
showCancel:false
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button class="btn-load" type="primary" @click="showLoading">显示 loading 提示框</button>
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<button @click="hideLoading">隐藏 loading 提示框</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'loading'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showLoading: function() {
|
||||
uni.showLoading({
|
||||
title: 'loading'
|
||||
});
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
this._showTimer && clearTimeout(this._showTimer);
|
||||
this._showTimer = setTimeout(() => {
|
||||
this.hideLoading();
|
||||
}, 3000)
|
||||
// #endif
|
||||
},
|
||||
hideLoading: function() {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
// #ifdef MP-ALIPAY
|
||||
,
|
||||
onUnload() {
|
||||
this._showTimer && clearTimeout(this._showTimer);
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="checkIsSupportSoterAuthentication">检查支持的认证方式</button>
|
||||
<button type="primary" @click="checkIsSoterEnrolledInDeviceFingerPrint">检查是否录入指纹</button>
|
||||
<button type="primary" @click="checkIsSoterEnrolledInDeviceFaceID">检查是否录入FaceID</button>
|
||||
<button type="primary" @click="startSoterAuthenticationFingerPrint">开始指纹认证</button>
|
||||
<button type="primary" @click="startSoterAuthenticationFaceID">开始FaceID认证</button>
|
||||
</view>
|
||||
<view style="width: 100%;text-align: center;">{{ result }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '生物认证',
|
||||
result: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
checkIsSupportSoterAuthentication() {
|
||||
uni.checkIsSupportSoterAuthentication({
|
||||
success(res) {
|
||||
uni.showModal({
|
||||
content: '支持的认证方式:' + res.supportMode,
|
||||
showCancel: false
|
||||
})
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
checkIsSoterEnrolledInDeviceFingerPrint() {
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: 'fingerPrint',
|
||||
success(res) {
|
||||
if(res.isEnrolled) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '已录入指纹'
|
||||
})
|
||||
}else {
|
||||
uni.showModal({
|
||||
content: '未录入指纹',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: '未录入指纹',
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
checkIsSoterEnrolledInDeviceFaceID() {
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: 'facial',
|
||||
success(res) {
|
||||
if(res.isEnrolled) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '已录入FaceID'
|
||||
})
|
||||
}else {
|
||||
uni.showModal({
|
||||
content: '未录入FaceID',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: '未录入FaceID',
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
startSoterAuthenticationFingerPrint() {
|
||||
uni.startSoterAuthentication({
|
||||
requestAuthModes: ['fingerPrint'],
|
||||
challenge: '123456',
|
||||
authContent: '请用指纹解锁',
|
||||
success(res) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '指纹验证成功'
|
||||
})
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: '指纹验证失败,errCode:' + err.errCode,
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
startSoterAuthenticationFaceID() {
|
||||
uni.startSoterAuthentication({
|
||||
requestAuthModes: ['facial'],
|
||||
challenge: '123456',
|
||||
authContent: '请用FaceID解锁',
|
||||
success(res) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: 'FaceID验证成功'
|
||||
})
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: 'FaceID验证失败,errCode:' + err.errCode,
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v"><button type="primary" @click="openDB">打开数据库test.db</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="executeSQL">创建表database及插入数据</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="selectSQL">查询表database的数据</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="droptable">删除表database</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="closeDB">关闭数据库test.db</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="isOpenDB">查询是否打开数据库</button></view>
|
||||
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'SQLite'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDB: function() {
|
||||
plus.sqlite.openDatabase({
|
||||
name: 'first',
|
||||
path: '_doc/test.db',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('打开数据库test.db成功 ');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('打开数据库test.db失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 执行SQL语句
|
||||
executeSQL: function() {
|
||||
plus.sqlite.executeSql({
|
||||
name: 'first',
|
||||
sql: 'create table if not exists database("name" CHAR(110),"sex" CHAR(10),"age" INT(11))',
|
||||
success: function(e) {
|
||||
plus.sqlite.executeSql({
|
||||
name: 'first',
|
||||
sql: "insert into database values('彦','女','7000')",
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('创建表table和插入数据成功');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('创建表table成功但插入数据失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('创建表table失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 查询SQL语句
|
||||
selectSQL: function() {
|
||||
plus.sqlite.selectSql({
|
||||
name: 'first',
|
||||
sql: 'select * from database',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('查询SQL语句成功: ' + JSON.stringify(e));
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('查询SQL语句失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除表
|
||||
droptable: function() {
|
||||
plus.sqlite.executeSql({
|
||||
name: 'first',
|
||||
sql: 'drop table database',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('删除表database成功');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('删除表database失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 关闭数据库
|
||||
closeDB: function() {
|
||||
plus.sqlite.closeDatabase({
|
||||
name: 'first',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('关闭数据库成功');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('关闭数据库失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
isOpenDB: function() {
|
||||
if (
|
||||
plus.sqlite.isOpenDatabase({
|
||||
name: 'first',
|
||||
path: '_doc/test.db'
|
||||
})
|
||||
) {
|
||||
plus.nativeUI.alert('Opened!');
|
||||
} else {
|
||||
plus.nativeUI.alert('Unopened!');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-btn-v {
|
||||
margin: 20rpx 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">key</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入key" name="key" :value="key" @input="keyChange"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">value</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入value" name="data" :value="data" @input="dataChange"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" class="btn-setstorage" @tap="setStorage">存储数据</button>
|
||||
<button @tap="getStorage">读取数据</button>
|
||||
<button @tap="clearStorage">清理数据</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'get/set/clearStorage',
|
||||
key: '',
|
||||
data: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
keyChange: function (e) {
|
||||
this.key = e.detail.value
|
||||
},
|
||||
dataChange: function (e) {
|
||||
this.data = e.detail.value
|
||||
},
|
||||
getStorage: function () {
|
||||
var key = this.key,
|
||||
data = this.data;
|
||||
if (key.length === 0) {
|
||||
uni.showModal({
|
||||
title: '读取数据失败',
|
||||
content: "key 不能为空",
|
||||
showCancel:false
|
||||
})
|
||||
} else {
|
||||
uni.getStorage({
|
||||
key: key,
|
||||
success: (res) => {
|
||||
uni.showModal({
|
||||
title: '读取数据成功',
|
||||
content: "data: '" + res.data + "'",
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
title: '读取数据失败',
|
||||
content: "找不到 key 对应的数据",
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
setStorage: function () {
|
||||
var key = this.key
|
||||
var data = this.data
|
||||
if (key.length === 0) {
|
||||
uni.showModal({
|
||||
title: '保存数据失败',
|
||||
content: 'key 不能为空',
|
||||
showCancel:false
|
||||
})
|
||||
} else {
|
||||
uni.setStorage({
|
||||
key: key,
|
||||
data: data,
|
||||
success: (res) => {
|
||||
uni.showModal({
|
||||
title: '存储数据成功',
|
||||
// #ifndef MP-ALIPAY
|
||||
content: JSON.stringify(res.errMsg),
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
content: data,
|
||||
// #endif
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
title: '储存数据失败!',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
clearStorage: function () {
|
||||
uni.clearStorageSync()
|
||||
this.key = '',
|
||||
this.data = ''
|
||||
uni.showModal({
|
||||
title: '清除数据成功',
|
||||
content: ' ',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn-setstorage {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="example">
|
||||
<view class="example-title">从左侧滑出</view>
|
||||
<button @click="showDrawer">显示抽屉</button>
|
||||
</view>
|
||||
<view class="example">
|
||||
<view class="example-title">从上侧竖向滑出</view>
|
||||
<button @click="showPopup">显示 弹出层</button>
|
||||
</view>
|
||||
<view style="width: 100%;">
|
||||
<video v-if="showVideo" id="video"
|
||||
@play="playVideo"
|
||||
@pause="closeMask"
|
||||
:controls="false"
|
||||
src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20181126-lite.m4v"
|
||||
@error="videoErrorCallback" poster="https://web-assets.dcloud.net.cn/unidoc/zh/poster.png"></video>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'SubNvue',
|
||||
showVideo: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.closeMask();
|
||||
|
||||
// 接收 popup 的消息
|
||||
uni.$on('popup-page', (data) => {
|
||||
switch(data.type){
|
||||
case 'interactive':
|
||||
uni.showModal({
|
||||
title: '来自Popup的消息',
|
||||
content: data.info
|
||||
})
|
||||
break;
|
||||
default:
|
||||
uni.showToast({
|
||||
title: data.title,
|
||||
})
|
||||
break;
|
||||
}
|
||||
})
|
||||
// 监听 drawer 消息
|
||||
uni.$on('drawer-page', (data) => {
|
||||
uni.showToast({
|
||||
title: '点击了第' + data + '项',
|
||||
icon:"none"
|
||||
});
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('popup-page')
|
||||
uni.$off('drawer-page')
|
||||
},
|
||||
onReady() {
|
||||
this.showVideo = true
|
||||
},
|
||||
methods: {
|
||||
showDrawer() {
|
||||
uni.getSubNVueById('drawer').show('slide-in-left', 200);
|
||||
},
|
||||
showPopup() {
|
||||
// 向 popup 传递消息
|
||||
uni.$emit('page-popup', {
|
||||
title: '请阅读软件内容',
|
||||
content: 'uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台。'
|
||||
});
|
||||
const subNVue = uni.getSubNVueById('popup')
|
||||
subNVue.show('slide-in-top', 250)
|
||||
},
|
||||
videoErrorCallback: function() {
|
||||
uni.showModal({
|
||||
content: '视频加载失败',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
playVideo() {
|
||||
let subNVue = uni.getSubNVueById('video_mask')
|
||||
subNVue.show('fade-in', 200, () => {
|
||||
uni.$emit('play-video', {
|
||||
status: 'open',
|
||||
})
|
||||
})
|
||||
},
|
||||
closeMask() {
|
||||
let subNVue = uni.getSubNVueById('video_mask')
|
||||
uni.$emit('close-video', {
|
||||
status: 'close',
|
||||
})
|
||||
subNVue.hide('fade-out', 200)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
align-content: center;
|
||||
height: 100%;
|
||||
background-color: #F4F5F6;
|
||||
}
|
||||
.example {
|
||||
padding: 0 10px 10px
|
||||
}
|
||||
.example-title {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #777;
|
||||
margin: 40px 2rpx;
|
||||
position: relative
|
||||
}
|
||||
video {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
.example .example-title {
|
||||
margin: 40rpx 0
|
||||
}
|
||||
button {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.title {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
color: #8f8f94;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="nav-text">左侧列表</text>
|
||||
<list class="list-wrapper">
|
||||
<cell v-for="item in lists" :key="item.id">
|
||||
<div class="text-wrapper" @click="clickitem(item.id)">
|
||||
<text style="font-size: 30rpx; ">{{item.name}}</text>
|
||||
<text class="icon"></text>
|
||||
</div>
|
||||
</cell>
|
||||
</list>
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<div class="close-drawer" @click="hideDrawer">
|
||||
<text style="font-size: 34rpx; text-align: center;">关闭抽屉</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lists: [],
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
const domModule = weex.requireModule('dom')
|
||||
domModule.addRule('fontFace', {
|
||||
fontFamily: "unibtn",
|
||||
'src': "url('../../../../static/uni.ttf')"
|
||||
});
|
||||
},
|
||||
created() {
|
||||
for(let i = 0; i < 5; i++){
|
||||
this.lists.push({
|
||||
id: i,
|
||||
name: 'Item' + i,
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hideDrawer() {
|
||||
uni.getCurrentSubNVue().hide('auto')
|
||||
},
|
||||
clickitem(e) {
|
||||
uni.$emit('drawer-page', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 60rpx 0rpx 0rpx 20rpx;
|
||||
background-color: #F4F5F6;
|
||||
}
|
||||
.nav-text {
|
||||
color: #8f8f94;
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
margin-bottom: 40px;
|
||||
/* #endif */
|
||||
/* #ifdef APP-PLUS-NVUE */
|
||||
margin-bottom: 40rpx;
|
||||
/* #endif */
|
||||
}
|
||||
.list-wrapper {
|
||||
/* #ifdef APP-PLUS-NVUE */
|
||||
height: 450rpx;
|
||||
/* #endif */
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
height: 450px;
|
||||
/* #endif */
|
||||
}
|
||||
.text-wrapper {
|
||||
justify-content: center;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-color: rgba(0,0,0,.2);
|
||||
margin-bottom: 35rpx;
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
.close-drawer {
|
||||
background-color: #f8f8f8;
|
||||
width: 300rpx;
|
||||
padding: 15rpx;
|
||||
border-radius: 20rpx;
|
||||
border-style: solid;
|
||||
border-width: 1rpx;
|
||||
border-color: rgba(0,0,0,.2);
|
||||
}
|
||||
.icon {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
color: #000000;
|
||||
font-family: unibtn;
|
||||
font-size: 30rpx;
|
||||
font-weight: 400;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="title">{{title}}</text>
|
||||
<scroller class="scroller">
|
||||
<div>
|
||||
<text class="content">{{content}}</text>
|
||||
</div>
|
||||
<div>
|
||||
<text style="color: red; font-size: 30rpx;">以下为 Popup 内部滚动示例:</text>
|
||||
</div>
|
||||
<div class="cell" v-for="(item, index) in lists" @click="handle(item)" :key="index">
|
||||
<text class="text">{{item}}</text>
|
||||
</div>
|
||||
</scroller>
|
||||
<div class="message-wrapper">
|
||||
<text class="send-message" @click="sendMessage">向页面发送消息</text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
content: '',
|
||||
lists: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const vm = this;
|
||||
for (let i = 1; i < 20; i++) {
|
||||
this.lists.push('item' + i);
|
||||
}
|
||||
uni.$on('page-popup', (data) => {
|
||||
vm.title = data.title;
|
||||
vm.content = data.content;
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
uni.$off('drawer-page')
|
||||
},
|
||||
methods: {
|
||||
sendMessage() {
|
||||
const subNVue = uni.getCurrentSubNVue()
|
||||
uni.$emit('popup-page', {
|
||||
title: '已读完!',
|
||||
})
|
||||
},
|
||||
handle(item, index) {
|
||||
const subNVue = uni.getCurrentSubNVue()
|
||||
uni.$emit('popup-page', {
|
||||
type: 'interactive',
|
||||
info: item + ' 该元素被点击了!',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 15rpx;
|
||||
background-color: #F4F5F6;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-color: #CBCBCB;
|
||||
flex: 0;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.scroller {
|
||||
height: 400rpx;
|
||||
padding: 8rpx 15rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
color: #555555;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.message-wrapper {
|
||||
flex: 0;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1rpx;
|
||||
border-top-color: #CBCBCB;
|
||||
height: 80rpx;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.send-message {
|
||||
font-size: 30rpx;
|
||||
line-height: 80rpx;
|
||||
color: #00CE47;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.cell {
|
||||
margin: 10rpx;
|
||||
padding: 20rpx 0;
|
||||
top: 10rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10rpx;
|
||||
background-color: #5989B9;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 30rpx;
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<list class="list">
|
||||
<cell v-for="(item, index) in lists" :key="index" :ref="'item' + index" class="cell">
|
||||
<text class="name">{{item.name}}:</text>
|
||||
<text class="content">{{item.content}}</text>
|
||||
</cell>
|
||||
</list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lists: [],
|
||||
interval: null,
|
||||
yourTexts: [
|
||||
{
|
||||
name: '学员A',
|
||||
content: '老师讲的真好',
|
||||
}, {
|
||||
name: '学员B',
|
||||
content: 'uni-app值得学习',
|
||||
}, {
|
||||
name: '学员C',
|
||||
content: '老师,还有实战例子吗?',
|
||||
}, {
|
||||
name: '学员D',
|
||||
content: '老师,请问是不是要先学会vue才能学uni-app?',
|
||||
}, {
|
||||
name: '学员E',
|
||||
content: '受教了,uni-app太牛了',
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const vm = this;
|
||||
uni.$on('play-video', (data) => {
|
||||
if(data.status === 'open'){
|
||||
this.addItem();
|
||||
}else{
|
||||
this.closeItem();
|
||||
}
|
||||
})
|
||||
},
|
||||
beforeDestroy(){
|
||||
uni.$off('play-video')
|
||||
this.closeItem()
|
||||
},
|
||||
methods: {
|
||||
addItem() {
|
||||
const vm = this;
|
||||
vm.lists = [{
|
||||
name: '学员E',
|
||||
content: '受教了,uni-app太牛了',
|
||||
}];
|
||||
const dom = weex.requireModule('dom')
|
||||
vm.interval = setInterval(() => {
|
||||
if(vm.lists.length > 15) {
|
||||
vm.lists.unshift();
|
||||
}
|
||||
vm.lists.push({
|
||||
name: vm.yourTexts[vm.lists.length%4].name,
|
||||
content: vm.yourTexts[vm.lists.length%4].content
|
||||
});
|
||||
if(vm.lists.length > 5) {
|
||||
vm.$nextTick(() => {
|
||||
if(vm.$refs['item' + (vm.lists.length - 1)]){
|
||||
dom.scrollToElement(vm.$refs['item' + (vm.lists.length - 1)][0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 3500);
|
||||
},
|
||||
closeItem() {
|
||||
if(this.interval) clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
background-color: transparent;
|
||||
}
|
||||
.list {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.cell {
|
||||
padding: 10rpx 0;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.name {
|
||||
flex: 0;
|
||||
font-size: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
color: #FF5A5F;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
font-size: 20rpx;
|
||||
color: #F4F5F6;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="default" @tap="toast1Tap">点击弹出默认toast</button>
|
||||
<button type="default" @tap="toast2Tap">点击弹出设置duration的toast</button>
|
||||
<!-- #ifndef MP-HARMONY -->
|
||||
<button type="default" @tap="toast3Tap">点击弹出显示loading的toast</button>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef MP-ALIPAY || MP-HARMONY -->
|
||||
<button type="default" @tap="toast4Tap">点击弹出显示自定义图片的toast</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button type="default" @tap="toast5Tap">点击显示无图标的居底toast</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-HARMONY -->
|
||||
<button type="default" @tap="hideToast">点击隐藏toast</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'toast'
|
||||
}
|
||||
},
|
||||
// #ifdef MP-ALIPAY
|
||||
onUnload() {
|
||||
this._showTimer && clearTimeout(this._showTimer);
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
toast1Tap: function() {
|
||||
uni.showToast({
|
||||
title: "默认"
|
||||
})
|
||||
},
|
||||
toast2Tap: function() {
|
||||
uni.showToast({
|
||||
title: "duration 3000",
|
||||
duration: 3000
|
||||
})
|
||||
},
|
||||
toast3Tap: function() {
|
||||
uni.showToast({
|
||||
title: "loading",
|
||||
icon: "loading",
|
||||
duration: 5000
|
||||
})
|
||||
// #ifdef MP-ALIPAY
|
||||
this._showTimer = setTimeout(() => {
|
||||
// icon 是 loading 时,showToast 实际执行的是 showLoading
|
||||
my.hideLoading()
|
||||
// 执行完所有代码再清除定时器
|
||||
clearTimeout(this._showTimer);
|
||||
}, 3000)
|
||||
// #endif
|
||||
|
||||
},
|
||||
toast4Tap: function() {
|
||||
uni.showToast({
|
||||
title: "logo",
|
||||
image: "../../../static/uni.png"
|
||||
})
|
||||
},
|
||||
// #ifdef APP-PLUS
|
||||
toast5Tap: function() {
|
||||
uni.showToast({
|
||||
title: "显示一段轻提示",
|
||||
position: 'bottom'
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
hideToast: function() {
|
||||
uni.hideToast()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="demo">
|
||||
<block v-if="imageSrc">
|
||||
<image :src="imageSrc" class="image" mode="widthFix"></image>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="uni-hello-addfile" @click="chooseImage">+ 选择图片</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'uploadFile',
|
||||
imageSrc: ''
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.imageSrc = '';
|
||||
},
|
||||
methods: {
|
||||
chooseImage: function() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album'],
|
||||
success: (res) => {
|
||||
console.log('chooseImage success, temp path is', res.tempFilePaths[0])
|
||||
var imageSrc = res.tempFilePaths[0]
|
||||
uni.uploadFile({
|
||||
url: 'https://unidemo.dcloud.net.cn/upload',
|
||||
filePath: imageSrc,
|
||||
fileType: 'image',
|
||||
name: 'data',
|
||||
success: (res) => {
|
||||
console.log('uploadImage success, res is:', res)
|
||||
uni.showToast({
|
||||
title: '上传成功',
|
||||
icon: 'success',
|
||||
duration: 1000
|
||||
})
|
||||
this.imageSrc = imageSrc
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('uploadImage fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('chooseImage fail', err)
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.demo {
|
||||
background: #FFF;
|
||||
padding: 50rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<button class="uni-button" type="primary" @click="longshock">长震动</button>
|
||||
<button class="uni-button" @click="shortshock">短震动</button>
|
||||
|
||||
<view class="uni-tips">
|
||||
<view>Tips</view>
|
||||
<view class="uni-tips-text">iOS上只有长震动,没有短震动</view>
|
||||
<view class="uni-tips-text">iOS上需要手机设置“打开响铃时震动”或“静音时震动”,否则无法震动</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'vibrateLong/vibrateShort'
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
longshock() {
|
||||
uni.vibrateLong({
|
||||
success: function() {
|
||||
console.log('success');
|
||||
}
|
||||
});
|
||||
},
|
||||
shortshock() {
|
||||
uni.vibrateShort({
|
||||
// #ifdef MP-HARMONY
|
||||
type:"medium",
|
||||
// #endif
|
||||
success: function() {
|
||||
console.log('success');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-padding-wrap {
|
||||
margin-top: 50rpx 0;
|
||||
}
|
||||
.uni-button {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
.uni-tips {
|
||||
color: #666;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.uni-tips-text {
|
||||
margin-top: 15rpx;
|
||||
line-height: 1.2;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">视频来源</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="sourceType" @change="sourceTypeChange" :value="sourceTypeIndex">
|
||||
<view class="uni-input">{{sourceType[sourceTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
|
||||
<view class="uni-title uni-common-mt uni-common-pl">摄像头位置</view>
|
||||
<view class="uni-hello-text camera-tips">注意:部分 Android 手机下由于系统 ROM 不支持无法生效,打开拍摄界面后可操作切换</view>
|
||||
<view class="uni-list">
|
||||
<radio-group @change="radioChange">
|
||||
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in cameraList" :key="item.value">
|
||||
<radio :value="item.value" :checked="index === cameraIndex">{{item.name}}</radio>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<template v-if="!src">
|
||||
<view class="uni-hello-addfile" @tap="chooseVideo">+ 添加视频</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<video :src="src" class="video"></video>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
var sourceType = [
|
||||
['camera'],
|
||||
['album'],
|
||||
['camera', 'album']
|
||||
]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'chooseVideo',
|
||||
sourceTypeIndex: 2,
|
||||
sourceType: ['拍摄', '相册', '拍摄或相册'],
|
||||
src: '',
|
||||
cameraList: [{
|
||||
value: 'back',
|
||||
name: '后置摄像头',
|
||||
checked: 'true'
|
||||
},
|
||||
{
|
||||
value: 'front',
|
||||
name: '前置摄像头'
|
||||
},
|
||||
],
|
||||
cameraIndex: 0
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.src = '',
|
||||
this.sourceTypeIndex = 2,
|
||||
this.sourceType = ['拍摄', '相册', '拍摄或相册'];
|
||||
},
|
||||
methods: {
|
||||
radioChange(evt) {
|
||||
for (let i = 0; i < this.cameraList.length; i++) {
|
||||
if (this.cameraList[i].value === evt.detail.value) {
|
||||
this.cameraIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
sourceTypeChange: function(e) {
|
||||
this.sourceTypeIndex = parseInt(e.detail.value)
|
||||
},
|
||||
chooseVideo: function() {
|
||||
uni.chooseVideo({
|
||||
camera: this.cameraList[this.cameraIndex].value,
|
||||
sourceType: sourceType[this.sourceTypeIndex],
|
||||
success: (res) => {
|
||||
this.src = res.tempFilePath
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = false;
|
||||
switch (this.sourceTypeIndex) {
|
||||
case 0:
|
||||
authStatus = res.authSetting['scope.camera'];
|
||||
break;
|
||||
case 1:
|
||||
authStatus = res.authSetting['scope.album'];
|
||||
break;
|
||||
case 2:
|
||||
authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取视频,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.camera-tips {
|
||||
padding: 10rpx 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<block v-if="!recording && !playing && !hasRecord">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button"></view>
|
||||
<view class="page-body-button" @click="startRecord">
|
||||
<image src="../../../static/record.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button"></view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="recording === true">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button"></view>
|
||||
<view class="page-body-button" @click="stopRecord">
|
||||
<view class="button-stop-record"></view>
|
||||
</view>
|
||||
<view class="page-body-button"></view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasRecord === true && playing === false">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedPlayTime}}</text>
|
||||
<text class="time-small">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button" @click="playVoice">
|
||||
<image src="../../../static/play.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button" @click="clear">
|
||||
<image src="../../../static/trash.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasRecord === true && playing === true">
|
||||
<view class="page-body-time">
|
||||
<text class="time-big">{{formatedPlayTime}}</text>
|
||||
<text class="time-small">{{formatedRecordTime}}</text>
|
||||
</view>
|
||||
<view class="page-body-buttons">
|
||||
<view class="page-body-button" @click="stopVoice">
|
||||
<image src="../../../static/stop.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button" @click="clear">
|
||||
<image src="../../../static/trash.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
import permision from "@/common/permission.js"
|
||||
// #endif
|
||||
import * as util from '../../../common/util.js'
|
||||
var playTimeInterval = null;
|
||||
var recordTimeInterval = null;
|
||||
var recorderManager = null;
|
||||
var music = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'start/stopRecord、play/stopVoice',
|
||||
recording: false, //录音中
|
||||
playing: false, //播放中
|
||||
hasRecord: false, //是否有了一个
|
||||
tempFilePath: '',
|
||||
recordTime: 0,
|
||||
playTime: 0,
|
||||
formatedRecordTime: '00:00:00', //录音的总时间
|
||||
formatedPlayTime: '00:00:00' //播放录音的当前时间
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
this.end();
|
||||
},
|
||||
onLoad: function() {
|
||||
music = uni.createInnerAudioContext();
|
||||
music.onEnded(() => {
|
||||
clearInterval(playTimeInterval)
|
||||
var playTime = 0
|
||||
console.log('play voice finished')
|
||||
this.playing = false;
|
||||
this.formatedPlayTime = util.formatTime(playTime);
|
||||
this.playTime = playTime;
|
||||
});
|
||||
recorderManager = uni.getRecorderManager();
|
||||
recorderManager.onStart(() => {
|
||||
console.log('recorder start');
|
||||
|
||||
this.recording = true;
|
||||
recordTimeInterval = setInterval(() => {
|
||||
this.recordTime += 1;
|
||||
this.formatedRecordTime = util.formatTime(this.recordTime);
|
||||
}, 1000)
|
||||
});
|
||||
recorderManager.onStop((res) => {
|
||||
console.log('on stop');
|
||||
music.src = res.tempFilePath;
|
||||
|
||||
this.hasRecord = true;
|
||||
this.recording = false;
|
||||
});
|
||||
recorderManager.onError(() => {
|
||||
console.log('recorder onError');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async startRecord() { //开始录音
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
|
||||
// TODO ios 在没有请求过权限之前无法得知是否有相关权限,这种状态下需要直接调用录音,但没有状态或回调判断用户拒绝
|
||||
recorderManager.start({
|
||||
format: 'mp3'
|
||||
});
|
||||
},
|
||||
stopRecord() { //停止录音
|
||||
recorderManager.stop();
|
||||
clearInterval(recordTimeInterval);
|
||||
},
|
||||
playVoice() {
|
||||
console.log('play voice');
|
||||
this.playing = true;
|
||||
playTimeInterval = setInterval(() => {
|
||||
this.playTime += 1;
|
||||
this.formatedPlayTime = util.formatTime(this.playTime);
|
||||
}, 1000)
|
||||
music.play();
|
||||
},
|
||||
stopVoice() {
|
||||
clearInterval(playTimeInterval)
|
||||
this.playing = false;
|
||||
this.formatedPlayTime = util.formatTime(0);
|
||||
this.playTime = 0;
|
||||
music.stop();
|
||||
},
|
||||
end() {
|
||||
music.stop();
|
||||
recorderManager.stop();
|
||||
clearInterval(recordTimeInterval)
|
||||
clearInterval(playTimeInterval);
|
||||
this.recording = false, this.playing = false, this.hasRecord = false;
|
||||
this.playTime = 0, this.recordTime = 0;
|
||||
this.formatedRecordTime = "00:00:00", this.formatedRecordTime = "00:00:00";
|
||||
},
|
||||
clear() {
|
||||
this.end();
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
,
|
||||
async checkPermission() {
|
||||
let status = permision.isIOS ? await permision.requestIOS('record') :
|
||||
await permision.requestAndroid('android.permission.RECORD_AUDIO');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else if (status === 2) {
|
||||
uni.showModal({
|
||||
content: "系统麦克风已关闭",
|
||||
confirmText: "确定",
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要麦克风权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return status;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
image {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.page-body-wrapper {
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
margin-bottom: 300rpx;
|
||||
}
|
||||
|
||||
.page-body-time {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.time-big {
|
||||
font-size: 60rpx;
|
||||
margin: 20rpx;
|
||||
}
|
||||
|
||||
.time-small {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.page-body-buttons {
|
||||
margin-top: 60rpx;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.page-body-button {
|
||||
width: 250rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.button-stop-record {
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
border: 20rpx solid #fff;
|
||||
background-color: #f55c23;
|
||||
border-radius: 130rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head title="websocket通讯示例"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<view class="websocket-msg">{{showMsg}}</view>
|
||||
<button type="primary" @click="connect">连接websocket服务</button>
|
||||
<button v-show="connected" type="primary" @click="send">发送一条消息</button>
|
||||
<button type="primary" @click="close">断开websocket服务</button>
|
||||
<view class="websocket-tips">发送消息后会收到一条服务器返回的消息(与发送的消息内容一致)</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let platform = uni.getSystemInfoSync().platform
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
connected: false,
|
||||
connecting: false,
|
||||
msg: false,
|
||||
roomId: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showMsg() {
|
||||
if (this.connected) {
|
||||
if (this.msg) {
|
||||
return '收到消息:' + this.msg
|
||||
} else {
|
||||
return '等待接收消息'
|
||||
}
|
||||
} else {
|
||||
return '尚未连接'
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.closeSocket()
|
||||
uni.hideLoading()
|
||||
},
|
||||
methods: {
|
||||
connect() {
|
||||
if (this.connected || this.connecting) {
|
||||
uni.showModal({
|
||||
content: '正在连接或者已经连接,请勿重复连接',
|
||||
showCancel: false
|
||||
})
|
||||
return false
|
||||
}
|
||||
this.connecting = true
|
||||
uni.showLoading({
|
||||
title: '连接中...'
|
||||
})
|
||||
uni.connectSocket({
|
||||
url: 'wss://echo.websocket.org',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Hello'
|
||||
}
|
||||
},
|
||||
// #ifdef MP
|
||||
header: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
method: 'GET',
|
||||
// #endif
|
||||
success(res) {
|
||||
// 这里是接口调用成功的回调,不是连接成功的回调,请注意
|
||||
},
|
||||
fail(err) {
|
||||
// 这里是接口调用失败的回调,不是连接失败的回调,请注意
|
||||
}
|
||||
})
|
||||
uni.onSocketOpen((res) => {
|
||||
this.connecting = false
|
||||
this.connected = true
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '连接成功'
|
||||
})
|
||||
console.log('onOpen', res);
|
||||
})
|
||||
uni.onSocketError((err) => {
|
||||
this.connecting = false
|
||||
this.connected = false
|
||||
uni.hideLoading()
|
||||
uni.showModal({
|
||||
content: '连接失败,可能是websocket服务不可用,请稍后再试',
|
||||
showCancel: false
|
||||
})
|
||||
console.log('onError', err);
|
||||
})
|
||||
uni.onSocketMessage((res) => {
|
||||
this.msg = res.data
|
||||
console.log('onMessage', res)
|
||||
})
|
||||
uni.onSocketClose((res) => {
|
||||
this.connected = false
|
||||
this.startRecive = false
|
||||
this.msg = false
|
||||
console.log('onClose', res)
|
||||
})
|
||||
},
|
||||
send() {
|
||||
uni.sendSocketMessage({
|
||||
data: 'from ' + platform + ' : ' + parseInt(Math.random() * 10000).toString(),
|
||||
success(res) {
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
uni.closeSocket()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-btn-v {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.uni-btn-v button {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.websocket-room {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
border-bottom: solid 1px #DDDDDD;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.websocket-msg {
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.websocket-tips{
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head title="websocket通讯示例"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<view class="websocket-msg">{{showMsg}}</view>
|
||||
<button type="primary" @click="connect">连接websocket服务</button>
|
||||
<button v-show="connected" type="primary" @click="send">发送一条消息</button>
|
||||
<button type="primary" @click="close">断开websocket服务</button>
|
||||
<view class="websocket-tips">发送消息后会收到一条服务器返回的消息(与发送的消息内容一致)</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let platform = uni.getSystemInfoSync().platform
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
connected: false,
|
||||
connecting: false,
|
||||
socketTask: false,
|
||||
msg: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showMsg() {
|
||||
if (this.connected) {
|
||||
if (this.msg) {
|
||||
return '收到消息:' + this.msg
|
||||
} else {
|
||||
return '等待接收消息'
|
||||
}
|
||||
} else {
|
||||
return '尚未连接'
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.hideLoading()
|
||||
if (this.socketTask && this.socketTask.close) {
|
||||
this.socketTask.close()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
connect() {
|
||||
if (this.connected || this.connecting) {
|
||||
uni.showModal({
|
||||
content: '正在连接或者已经连接,请勿重复连接',
|
||||
showCancel: false
|
||||
})
|
||||
return false
|
||||
}
|
||||
this.connecting = true
|
||||
uni.showLoading({
|
||||
title: '连接中...'
|
||||
})
|
||||
this.socketTask = uni.connectSocket({
|
||||
url: 'wss://echo.websocket.org',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Hello'
|
||||
}
|
||||
},
|
||||
// #ifdef MP
|
||||
header: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
method: 'GET',
|
||||
// #endif
|
||||
success(res) {
|
||||
// 这里是接口调用成功的回调,不是连接成功的回调,请注意
|
||||
},
|
||||
fail(err) {
|
||||
// 这里是接口调用失败的回调,不是连接失败的回调,请注意
|
||||
}
|
||||
})
|
||||
console.log(this.socketTask);
|
||||
this.socketTask.onOpen((res) => {
|
||||
this.connecting = false
|
||||
this.connected = true
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '连接成功'
|
||||
})
|
||||
console.log('onOpen', res);
|
||||
})
|
||||
this.socketTask.onError((err) => {
|
||||
this.connecting = false
|
||||
this.connected = false
|
||||
uni.hideLoading()
|
||||
uni.showModal({
|
||||
content: '连接失败,可能是websocket服务不可用,请稍后再试',
|
||||
showCancel: false
|
||||
})
|
||||
console.log('onError', err);
|
||||
})
|
||||
this.socketTask.onMessage((res) => {
|
||||
this.msg = res.data
|
||||
console.log('onMessage', res)
|
||||
})
|
||||
this.socketTask.onClose((res) => {
|
||||
this.connected = false
|
||||
this.startRecive = false
|
||||
this.socketTask = false
|
||||
this.msg = false
|
||||
console.log('onClose', res)
|
||||
})
|
||||
console.log('task', this.socketTask)
|
||||
},
|
||||
send() {
|
||||
this.socketTask.send({
|
||||
data: 'from ' + platform + ' : ' + parseInt(Math.random() * 10000).toString(),
|
||||
success(res) {
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
if (this.socketTask && this.socketTask.close) {
|
||||
this.socketTask.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.uni-btn-v {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.uni-btn-v button {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.websocket-msg {
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.websocket-tips{
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
<template>
|
||||
<view class="about">
|
||||
<view class="content">
|
||||
<view class="qrcode">
|
||||
<image src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/app_download.png" @longtap="save"></image>
|
||||
<text class="tip">扫码体验uni-app</text>
|
||||
</view>
|
||||
<view class="desc">
|
||||
<text class="code">uni-app</text>
|
||||
是一个使用 <text class="code">Vue.js</text> 开发跨平台应用的前端框架。
|
||||
</view>
|
||||
<view class="source">
|
||||
<view class="title">本示例源码获取方式:</view>
|
||||
<view class="source-list">
|
||||
<view class="source-cell">
|
||||
<text space="nbsp">1. </text>
|
||||
<text>下载 HBuilderX,新建 uni-app 项目时选择 <text class="code">Hello uni-app</text> 模板。</text>
|
||||
</view>
|
||||
<view class="source-cell">
|
||||
<text space="nbsp">2. </text>
|
||||
<u-link class="link" :href="'https://github.com/dcloudio/hello-uniapp'" :text="'https://github.com/dcloudio/hello-uniapp'"></u-link>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button type="primary" @click="share">分享</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="version">
|
||||
当前版本:{{version}}
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
providerList: [],
|
||||
version: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
this.version = plus.runtime.version;
|
||||
uni.getProvider({
|
||||
service: 'share',
|
||||
success: (result) => {
|
||||
const data = [];
|
||||
for (let i = 0; i < result.provider.length; i++) {
|
||||
switch (result.provider[i]) {
|
||||
case 'weixin':
|
||||
data.push({
|
||||
name: '分享到微信好友',
|
||||
id: 'weixin'
|
||||
});
|
||||
data.push({
|
||||
name: '分享到微信朋友圈',
|
||||
id: 'weixin',
|
||||
type: 'WXSceneTimeline'
|
||||
});
|
||||
break;
|
||||
case 'qq':
|
||||
data.push({
|
||||
name: '分享到QQ',
|
||||
id: 'qq'
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.providerList = data;
|
||||
},
|
||||
fail: (error) => {
|
||||
console.log('获取分享通道失败' + JSON.stringify(error));
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
// #ifdef APP-PLUS
|
||||
save() {
|
||||
uni.showActionSheet({
|
||||
itemList: ['保存图片到相册'],
|
||||
success: () => {
|
||||
plus.gallery.save('https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/app_download.png', function() {
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'none'
|
||||
});
|
||||
}, function() {
|
||||
uni.showToast({
|
||||
title: '保存失败,请重试!',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
share(e) {
|
||||
if (this.providerList.length === 0) {
|
||||
uni.showModal({
|
||||
title: '当前环境无分享渠道!',
|
||||
showCancel: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
let itemList = this.providerList.map(function(value) {
|
||||
return value.name;
|
||||
})
|
||||
uni.showActionSheet({
|
||||
itemList: itemList,
|
||||
success: (res) => {
|
||||
let provider = this.providerList[res.tapIndex].id;
|
||||
uni.share({
|
||||
provider: provider,
|
||||
scene: this.providerList[res.tapIndex].type && this.providerList[res.tapIndex].type === 'WXSceneTimeline' ?
|
||||
'WXSceneTimeline' : "WXSceneSession",
|
||||
type: (provider === "qq") ? 1 : 0,
|
||||
title: '欢迎体验uni-app',
|
||||
summary: 'uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架',
|
||||
imageUrl: 'https://web-assets.dcloud.net.cn/unidoc/zh/8.jpg',
|
||||
href: "https://m3w.cn/uniapp",
|
||||
success: (res) => {
|
||||
console.log("success:" + JSON.stringify(res));
|
||||
},
|
||||
fail: (e) => {
|
||||
uni.showModal({
|
||||
content: e.errMsg,
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page,
|
||||
view {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
page {
|
||||
min-height: 100%;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
}
|
||||
|
||||
.about {
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 30rpx;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.qrcode .tip {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-top: 30rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.code {
|
||||
color: #e96900;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.version {
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
justify-content: center;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.source {
|
||||
margin-top: 30rpx;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.source-list {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #007AFF;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="ad-view">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<ad :unit-id="unitId" type="feed" @load="adload" @error="aderror"/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<ad adpid="1111111111" @load="adload" @error="aderror"/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="ad-tips" v-if="!isLoad">
|
||||
<text>{{adMessage}}</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<view class="ad-tips">
|
||||
<text>小程序端的广告ID由小程序平台提供</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="tips">
|
||||
<text class="tips-text">本示例页面仅演示ad组件。另点此可体验</text><text class="tips-hl" @click="gotoapi">激励视频API</text><text class="tips-text">。</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'AD组件',
|
||||
unitId: '',
|
||||
isLoad: false,
|
||||
adMessage: "广告加载中..."
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.unitId = '';
|
||||
// #endif
|
||||
// #ifdef MP-TOUTIAO
|
||||
this.unitId = ''
|
||||
// #endif
|
||||
// #ifdef MP-QQ
|
||||
this.unitId = ''
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
adload() {
|
||||
this.isLoad = true;
|
||||
},
|
||||
aderror(e) {
|
||||
this.adMessage = e.detail.errMsg;
|
||||
},
|
||||
gotoapi() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/API/rewarded-video-ad/rewarded-video-ad"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
background-color: #DBDBDB;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.ad-view {
|
||||
background-color: #FFFFFF;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ad-tips {
|
||||
color: #999;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.tips-text {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.tips-hl {
|
||||
color: #007AFF;
|
||||
margin-left: 1px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head title="audio"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-center">
|
||||
<audio style="text-align: left" :src="current.src" :poster="current.poster" :name="current.name" :author="current.author"
|
||||
:action="audioAction" controls></audio>
|
||||
<view class="">audio组件不再维护,建议使用能力更强的uni.createInnerAudioContext()</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
current: {
|
||||
poster: 'https://web-assets.dcloud.net.cn/unidoc/zh/Alice.jpeg',
|
||||
name: '致爱丽丝',
|
||||
author: '暂无',
|
||||
src: 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3',
|
||||
},
|
||||
audioAction: {
|
||||
method: 'pause'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<button type="primary">页面主操作 Normal</button>
|
||||
<button type="primary" :loading="loading">页面主操作 Loading</button>
|
||||
<button type="primary" disabled="true">页面主操作 Disabled</button>
|
||||
|
||||
<button type="default">页面次要操作 Normal</button>
|
||||
<button type="default" disabled="true">页面次要操作 Disabled</button>
|
||||
|
||||
<button type="warn">警告类操作 Normal</button>
|
||||
<button type="warn" disabled="true">警告类操作 Disabled</button>
|
||||
|
||||
<view class="button-sp-area">
|
||||
<button type="primary" plain="true">按钮</button>
|
||||
<button type="primary" disabled="true" plain="true">不可点击的按钮</button>
|
||||
|
||||
<button type="default" plain="true">按钮</button>
|
||||
<button type="default" disabled="true" plain="true">按钮</button>
|
||||
|
||||
<button class="mini-btn" type="primary" size="mini">按钮</button>
|
||||
<button class="mini-btn" type="default" size="mini">按钮</button>
|
||||
<button class="mini-btn" type="warn" size="mini">按钮</button>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN || MP-QQ || MP-JD -->
|
||||
<button open-type="launchApp" app-parameter="uni-app" @error="openTypeError">打开APP</button>
|
||||
<button open-type="feedback">意见反馈</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'button',
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this._timer = null;
|
||||
},
|
||||
onShow() {
|
||||
this.clearTimer();
|
||||
this._timer = setTimeout(() => {
|
||||
this.loading = true;
|
||||
}, 300)
|
||||
},
|
||||
onUnload() {
|
||||
this.clearTimer();
|
||||
this.loading = false;
|
||||
},
|
||||
methods: {
|
||||
openTypeError(error) {
|
||||
console.error('open-type error:', error);
|
||||
},
|
||||
clearTimer() {
|
||||
if (this._timer != null) {
|
||||
clearTimeout(this._timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
button {
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.button-sp-area {
|
||||
margin: 0 auto;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.mini-btn {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="page-body">
|
||||
<view class="page-body-wrapper">
|
||||
<!-- #ifdef APP-PLUS || H5 -->
|
||||
<canvas canvas-id="canvas" class="canvas" :start="startStatus" :change:start="animate.start"
|
||||
:data-width="canvasWidth" :data-height="canvasWidth"></canvas>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS || H5 -->
|
||||
<canvas canvas-id="canvas" id="canvas" class="canvas"></canvas>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script module="animate" lang="renderjs">
|
||||
function Ball({
|
||||
x,
|
||||
y,
|
||||
vx,
|
||||
vy,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
ctx
|
||||
}) {
|
||||
this.canvasWidth = canvasWidth
|
||||
this.canvasHeight = canvasHeight
|
||||
this.ctx = ctx
|
||||
this.x = x
|
||||
this.y = y
|
||||
this.vx = vx
|
||||
this.vy = vy
|
||||
this.radius = 5
|
||||
}
|
||||
|
||||
Ball.prototype.draw = function() {
|
||||
this.ctx.beginPath()
|
||||
this.ctx.fillStyle = '#007AFF'
|
||||
this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
|
||||
this.ctx.closePath()
|
||||
this.ctx.fill()
|
||||
}
|
||||
|
||||
Ball.prototype.move = function() {
|
||||
this.x += this.vx
|
||||
this.y += this.vy
|
||||
// 回到中心
|
||||
// if (getDistance(this.x - this.canvasWidth / 2, this.y - this.canvasHeight / 2) >
|
||||
// getDistance(this.canvasWidth / 2, this.canvasHeight / 2) + this.radius) {
|
||||
// this.x = this.canvasWidth / 2
|
||||
// this.y = this.canvasHeight / 2
|
||||
// }
|
||||
|
||||
// 边框反弹
|
||||
if (this.x < this.radius) {
|
||||
this.vx = Math.abs(this.vx)
|
||||
return
|
||||
}
|
||||
if (this.x > this.canvasWidth - this.radius) {
|
||||
this.vx = -Math.abs(this.vx)
|
||||
}
|
||||
if (this.y < this.radius) {
|
||||
this.vy = Math.abs(this.vy)
|
||||
return
|
||||
}
|
||||
if (this.y > this.canvasWidth - this.radius) {
|
||||
this.vy = -Math.abs(this.vy)
|
||||
}
|
||||
}
|
||||
|
||||
function getDistance(x, y) {
|
||||
return Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5)
|
||||
}
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
start(newVal, oldVal, owner, ins) {
|
||||
let canvasWidth = ins.getDataset().width,
|
||||
canvasHeight = ins.getDataset().height,
|
||||
canvasEle = document.querySelectorAll('.canvas>canvas')[0],
|
||||
ctx = canvasEle.getContext('2d'),
|
||||
speed = 3,
|
||||
ballList = [],
|
||||
layer = 3,
|
||||
ballInlayer = 20
|
||||
for (let i = 0; i < layer; i++) {
|
||||
let radius = getDistance(canvasWidth / 2, canvasHeight / 2) / layer * i
|
||||
for (let j = 0; j < ballInlayer; j++) {
|
||||
let deg = j * 2 * Math.PI / ballInlayer,
|
||||
sin = Math.sin(deg),
|
||||
cos = Math.cos(deg),
|
||||
x = radius * cos + canvasWidth / 2,
|
||||
y = radius * sin + canvasHeight / 2,
|
||||
vx = speed * cos,
|
||||
vy = speed * sin
|
||||
ballList.push(new Ball({
|
||||
x,
|
||||
y,
|
||||
vx,
|
||||
vy,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
ctx,
|
||||
radius: 5
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
function animate(ballList) {
|
||||
ctx.clearRect(0, 0, canvasEle.width, canvasEle.height)
|
||||
ballList.forEach(function(item) {
|
||||
item.move()
|
||||
item.draw()
|
||||
})
|
||||
requestAnimationFrame(function() {
|
||||
animate(ballList)
|
||||
})
|
||||
}
|
||||
animate(ballList)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// #ifndef APP-PLUS || H5
|
||||
|
||||
let ctx = null,
|
||||
interval = null;
|
||||
|
||||
function Ball(x, y, vx, vy, canvasWidth, canvasHeight, ctx) {
|
||||
this.canvasWidth = canvasWidth
|
||||
this.canvasHeight = canvasHeight
|
||||
this.ctx = ctx
|
||||
this.x = x
|
||||
this.y = y
|
||||
this.vx = vx
|
||||
this.vy = vy
|
||||
this.radius = 5
|
||||
}
|
||||
|
||||
Ball.prototype.draw = function() {
|
||||
this.ctx.setFillStyle('#007AFF')
|
||||
this.ctx.beginPath()
|
||||
this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
|
||||
this.ctx.closePath()
|
||||
this.ctx.fill()
|
||||
}
|
||||
|
||||
Ball.prototype.move = function() {
|
||||
this.x += this.vx
|
||||
this.y += this.vy
|
||||
// 回到中心
|
||||
// if (getDistance(this.x - this.canvasWidth / 2, this.y - this.canvasHeight / 2) >
|
||||
// getDistance(this.canvasWidth / 2, this.canvasHeight / 2) + this.radius) {
|
||||
// this.x = this.canvasWidth / 2
|
||||
// this.y = this.canvasHeight / 2
|
||||
// }
|
||||
|
||||
// 边框反弹
|
||||
if (this.x < this.radius) {
|
||||
this.vx = Math.abs(this.vx)
|
||||
return
|
||||
}
|
||||
if (this.x > this.canvasWidth - this.radius) {
|
||||
this.vx = -Math.abs(this.vx)
|
||||
}
|
||||
if (this.y < this.radius) {
|
||||
this.vy = Math.abs(this.vy)
|
||||
return
|
||||
}
|
||||
if (this.y > this.canvasWidth - this.radius) {
|
||||
this.vy = -Math.abs(this.vy)
|
||||
}
|
||||
}
|
||||
|
||||
function getDistance(x, y) {
|
||||
return Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5)
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'canvas',
|
||||
canvasWidth: 0,
|
||||
startStatus: false,
|
||||
ballList: []
|
||||
}
|
||||
},
|
||||
onReady: function() {
|
||||
this.$nextTick(() => {
|
||||
uni.createSelectorQuery().select(".canvas").boundingClientRect(data => {
|
||||
this.canvasWidth = data.width
|
||||
// #ifdef APP-PLUS || H5
|
||||
this.startStatus = true
|
||||
// #endif
|
||||
// #ifndef APP-PLUS || H5
|
||||
ctx = uni.createCanvasContext('canvas')
|
||||
this.drawBall()
|
||||
// #endif
|
||||
}).exec()
|
||||
})
|
||||
},
|
||||
// #ifndef APP-PLUS || H5
|
||||
onUnload: function() {
|
||||
clearInterval(interval);
|
||||
},
|
||||
methods: {
|
||||
drawBall: function() {
|
||||
let canvasWidth = this.canvasWidth,
|
||||
canvasHeight = this.canvasWidth,
|
||||
speed = 3,
|
||||
ballList = [],
|
||||
layer = 3,
|
||||
ballInlayer = 20
|
||||
for (let i = 0; i < layer; i++) {
|
||||
let radius = getDistance(canvasWidth / 2, canvasHeight / 2) / layer * i
|
||||
for (let j = 0; j < ballInlayer; j++) {
|
||||
let deg = j * 2 * Math.PI / ballInlayer,
|
||||
sin = Math.sin(deg),
|
||||
cos = Math.cos(deg),
|
||||
x = radius * cos + canvasWidth / 2,
|
||||
y = radius * sin + canvasHeight / 2,
|
||||
vx = speed * cos,
|
||||
vy = speed * sin
|
||||
ballList.push(new Ball(x, y, vx, vy, canvasWidth, canvasHeight, ctx))
|
||||
}
|
||||
}
|
||||
|
||||
function animate(ballList) {
|
||||
// ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||
ballList.forEach(function(item) {
|
||||
item.move()
|
||||
item.draw()
|
||||
})
|
||||
ctx.draw()
|
||||
}
|
||||
|
||||
interval = setInterval(function() {
|
||||
animate(ballList)
|
||||
}, 17)
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page-body-wrapper {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
width: 610rpx;
|
||||
height: 610rpx;
|
||||
margin: auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-title uni-common-mt">默认样式</view>
|
||||
<view>
|
||||
<checkbox-group>
|
||||
<label>
|
||||
<checkbox value="cb1" checked="true" />选中
|
||||
</label>
|
||||
<label>
|
||||
<checkbox value="cb" />未选中
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<view class="uni-title uni-common-mt">不同颜色和尺寸的checkbox</view>
|
||||
<view>
|
||||
<checkbox-group>
|
||||
<label>
|
||||
<checkbox value="cb1" checked="true" color="#FFCC33" style="transform:scale(0.7)" />选中
|
||||
</label>
|
||||
<label>
|
||||
<checkbox value="cb" color="#FFCC33" style="transform:scale(0.7)" />未选中
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-title uni-common-mt">
|
||||
推荐展示样式
|
||||
<text>\n使用 uni-list 布局</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list">
|
||||
<checkbox-group @change="checkboxChange">
|
||||
<label class="uni-list-cell uni-list-cell-pd" v-for="item in items" :key="item.value">
|
||||
<view>
|
||||
<checkbox :value="item.value" :checked="item.checked" />
|
||||
</view>
|
||||
<view>{{item.name}}</view>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'checkbox 复选框',
|
||||
items: [{
|
||||
value: 'USA',
|
||||
name: '美国'
|
||||
},
|
||||
{
|
||||
value: 'CHN',
|
||||
name: '中国',
|
||||
checked: 'true'
|
||||
},
|
||||
{
|
||||
value: 'BRA',
|
||||
name: '巴西'
|
||||
},
|
||||
{
|
||||
value: 'JPN',
|
||||
name: '日本'
|
||||
},
|
||||
{
|
||||
value: 'ENG',
|
||||
name: '英国'
|
||||
},
|
||||
{
|
||||
value: 'FRA',
|
||||
name: '法国'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkboxChange: function (e) {
|
||||
var items = this.items,
|
||||
values = e.detail.value;
|
||||
for (var i = 0, lenI = items.length; i < lenI; ++i) {
|
||||
const item = items[i]
|
||||
if(values.indexOf(item.value) >= 0){
|
||||
this.$set(item,'checked',true)
|
||||
}else{
|
||||
this.$set(item,'checked',false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-list-cell {
|
||||
justify-content: flex-start
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<view>
|
||||
<video ref="video" id="myVideo" class="video" :src="src" controls="true">
|
||||
<cover-view class="coverview" style="overflow-y: scroll;">
|
||||
<text class="text">{{ '\uEA06\uEA0E\uEA0C\uEA0A 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view 我是可以滚动的cover-view' }}</text>
|
||||
</cover-view>
|
||||
</video>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'cover-view',
|
||||
src: "https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20181126-lite.m4v"
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
text-align: center;
|
||||
height: 400rpx;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 200rpx;
|
||||
width: 200rpx;
|
||||
margin-top: 200rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
color: #8f8f94;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #4CD964;
|
||||
font-family: unincomponents;
|
||||
}
|
||||
|
||||
.video {
|
||||
width: 750rpx;
|
||||
height: 400rpx;
|
||||
background-color: #808080;
|
||||
}
|
||||
|
||||
.coverview {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0rpx;
|
||||
height: 150rpx;
|
||||
border-width: 10rpx;
|
||||
border-color: #4CD964;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head title="cover-view用于覆盖map、video等原生组件"></page-head>
|
||||
<view class="cover-content" v-if="showMap">
|
||||
<!-- TODO暂时条件编译解决支付宝小程序不能正常显示 cover-x -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<map>
|
||||
<cover-view class="cover-view">简单的cover-view</cover-view>
|
||||
<cover-image class="cover-image" src="/static/uni.png"></cover-image>
|
||||
</map>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<!-- #ifndef MP-QQ -->
|
||||
<map></map>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- TODO QQ暂不支持地图组件 -->
|
||||
<!-- #ifdef MP-QQ -->
|
||||
<video class="video" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20181126-lite.m4v"></video>
|
||||
<!-- #endif -->
|
||||
|
||||
<cover-view class="cover-view">简单的cover-view</cover-view>
|
||||
<!-- #ifndef MP-QQ -->
|
||||
<cover-image class="cover-image" src="/static/uni.png"></cover-image>
|
||||
<!-- #endif -->
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showMap: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS || MP-BAIDU
|
||||
setTimeout(()=>{
|
||||
this.showMap = true
|
||||
},350)
|
||||
// #endif
|
||||
// #ifndef APP-PLUS || MP-BAIDU
|
||||
this.showMap = true
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
map {
|
||||
width: 750rpx;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cover-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cover-view {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
width: 375rpx;
|
||||
text-align: center;
|
||||
background-color: #DDDDDD;
|
||||
}
|
||||
|
||||
.cover-image {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,248 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<view class="page-body">
|
||||
<view class='wrapper'>
|
||||
<view class='toolbar' @tap="format" style="height: 80px;overflow-y: auto;">
|
||||
<view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu" data-name="bold">
|
||||
</view>
|
||||
<view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti" data-name="italic">
|
||||
</view>
|
||||
<view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian"
|
||||
data-name="underline"></view>
|
||||
<view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian"
|
||||
data-name="strike"></view>
|
||||
<!-- #ifndef MP-BAIDU -->
|
||||
<view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi"
|
||||
data-name="align" data-value="left"></view>
|
||||
<!-- #endif -->
|
||||
<view :class="formats.align === 'center' ? 'ql-active' : ''" class="iconfont icon-juzhongduiqi"
|
||||
data-name="align" data-value="center"></view>
|
||||
<view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi"
|
||||
data-name="align" data-value="right"></view>
|
||||
<view :class="formats.align === 'justify' ? 'ql-active' : ''" class="iconfont icon-zuoyouduiqi"
|
||||
data-name="align" data-value="justify"></view>
|
||||
<!-- #ifndef MP-BAIDU -->
|
||||
<view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height"
|
||||
data-name="lineHeight" data-value="2"></view>
|
||||
<view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing"
|
||||
data-name="letterSpacing" data-value="2em"></view>
|
||||
<view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju"
|
||||
data-name="marginTop" data-value="20px"></view>
|
||||
<view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
|
||||
data-name="marginBottom" data-value="20px"></view>
|
||||
<!-- #endif -->
|
||||
|
||||
<view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
|
||||
|
||||
<!-- #ifndef MP-BAIDU -->
|
||||
<view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font"
|
||||
data-name="fontFamily" data-value="Pacifico"></view>
|
||||
<view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
|
||||
data-name="fontSize" data-value="24px"></view>
|
||||
<!-- #endif -->
|
||||
<view :class="formats.color === '#0000ff' ? 'ql-active' : ''" class="iconfont icon-text_color"
|
||||
data-name="color" data-value="#0000ff"></view>
|
||||
<view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
|
||||
class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view>
|
||||
<view class="iconfont icon-date" @tap="insertDate"></view>
|
||||
<view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
|
||||
<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie"
|
||||
data-name="list" data-value="ordered"></view>
|
||||
<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
|
||||
data-name="list" data-value="bullet"></view>
|
||||
|
||||
<view class="iconfont icon-undo" @tap="undo"></view>
|
||||
<view class="iconfont icon-redo" @tap="redo"></view>
|
||||
|
||||
<view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
|
||||
<view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
|
||||
<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
|
||||
<view class="iconfont icon-charutupian" @tap="insertImage"></view>
|
||||
<view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
|
||||
data-name="header" :data-value="1"></view>
|
||||
<view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
|
||||
data-name="script" data-value="sub"></view>
|
||||
<view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao"
|
||||
data-name="script" data-value="super"></view>
|
||||
|
||||
<view class="iconfont icon-shanchu" @tap="clear"></view>
|
||||
|
||||
<view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl"
|
||||
data-name="direction" data-value="rtl"></view>
|
||||
</view>
|
||||
|
||||
<view class="editor-wrapper">
|
||||
<editor id="editor" class="ql-container" placeholder="开始输入..." show-img-size show-img-toolbar
|
||||
show-img-resize @statuschange="onStatusChange" :read-only="readOnly" @ready="onEditorReady">
|
||||
</editor>
|
||||
</view>
|
||||
<view>
|
||||
<button @tap="getCon">打印文本内容</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
readOnly: false,
|
||||
formats: {}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// #ifndef MP-BAIDU
|
||||
uni.loadFontFace({
|
||||
family: 'Pacifico',
|
||||
source: 'url("/static/font/Pacifico-Regular.ttf")',
|
||||
success() {
|
||||
console.log('success load font')
|
||||
},
|
||||
fail() {
|
||||
console.log('fail load font load')
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
readOnlyChange() {
|
||||
this.readOnly = !this.readOnly
|
||||
},
|
||||
getCon() {
|
||||
this.editorCtx.getContents({
|
||||
success: (res) => {
|
||||
console.log('文本详情:', res)
|
||||
},
|
||||
fail: (err) => {
|
||||
// console.log(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
onEditorReady() {
|
||||
// #ifdef MP-BAIDU
|
||||
this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editor');
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS || MP-WEIXIN || H5
|
||||
uni.createSelectorQuery().select('#editor').context((res) => {
|
||||
this.editorCtx = res.context
|
||||
}).exec()
|
||||
// #endif
|
||||
},
|
||||
undo() {
|
||||
this.editorCtx.undo()
|
||||
},
|
||||
redo() {
|
||||
this.editorCtx.redo()
|
||||
},
|
||||
format(e) {
|
||||
let {
|
||||
name,
|
||||
value
|
||||
} = e.target.dataset
|
||||
if (!name) return
|
||||
// console.log('format', name, value)
|
||||
this.editorCtx.format(name, value)
|
||||
},
|
||||
onStatusChange(e) {
|
||||
const formats = e.detail
|
||||
this.formats = formats
|
||||
},
|
||||
insertDivider() {
|
||||
this.editorCtx.insertDivider({
|
||||
success: function() {
|
||||
console.log('insert divider success')
|
||||
}
|
||||
})
|
||||
},
|
||||
clear() {
|
||||
uni.showModal({
|
||||
title: '清空编辑器',
|
||||
content: '确定清空编辑器全部内容?',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
this.editorCtx.clear({
|
||||
success: function(res) {
|
||||
console.log("clear success")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
removeFormat() {
|
||||
this.editorCtx.removeFormat()
|
||||
},
|
||||
insertDate() {
|
||||
const date = new Date()
|
||||
const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
|
||||
this.editorCtx.insertText({
|
||||
text: formatDate
|
||||
})
|
||||
},
|
||||
insertImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: (res) => {
|
||||
this.editorCtx.insertImage({
|
||||
src: res.tempFilePaths[0],
|
||||
alt: '图像',
|
||||
success: function() {
|
||||
console.log('insert image success')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import "./editor-icon.css";
|
||||
|
||||
.page-body {
|
||||
height: calc(100vh - var(--window-top) - var(--status-bar-height));
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.editor-wrapper {
|
||||
height: calc(100vh - var(--window-top) - var(--status-bar-height) - 80px - 46px);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
display: inline-block;
|
||||
padding: 8px 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0;
|
||||
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
.ql-container {
|
||||
box-sizing: border-box;
|
||||
padding: 12px 15px;
|
||||
width: 100%;
|
||||
min-height: 30vh;
|
||||
height: 100%;
|
||||
/* margin-top: 20px; */
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.ql-active {
|
||||
color: #06c;
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue