解决 HBuilderX + UniApp + Ts + 父组件Prop 在微信小程序中 无法绑定的 BUG;
项目转到 TS 以后,基本就没有使用过 Js 了。。所以下面的所有代码都使用 TS 作为说明; (PS.,我的项目的 ts 和 vue 是分开的)。
父组件 BaseUniComponent.ts 就是定义了一个 父组件中的 prop
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
export default class BaseUniComponent extends Vue{
@Prop({ default: null})
propInParent: null | string;
}
子组件 UserMoneyDetail.ts (继承子父组件,并且定义了一个子组件内的 prop)
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import BaseUniComponent from './Basic/BaseUniComponent';
@Component({})
export default class UserIncome extends BaseUniComponent {
@Prop({default: null})
propInComponent: null | string;
}
子组件页面: UserMoneyDetail.vue ( 显示传入进来的 prop 的值)
<template>
<view class="content">
<view>propInComponent: {{propInComponent}}</view>
<view>propInParent: {{propInParent}}</view>
</view>
</template>
<script lang="ts" src='./UserMoneyDetail.ts'></script>
入口页面 unientry.ts
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import UserMoney from './UserMoneyDetail.vue';
@Component({
components: {
UserMoney
}
})
export default class index extends Vue {
title: string = 'Hello';
}
入口页面 unientry.vue (分别绑定了定义在子组件内部的 prop 和 子组件继承自父类的 prop)
<template>
<view>
<UserMoney :propInComponent='title' :propInParent='title'></UserMoney>
</view>
</template>
<script lang="ts" src='./unientry.ts'></script>
在 h5 中这个毫无疑问正常,会显示 2个 Hello,
但是,编译到微信小程序中,却只会显示一个 Hello; ( 我的版本 , HBuilder X 2.2.2.20190816, )
最终发现一个是 HBuilder x 将代码编译成 微信小程序的问题, 也就是 uni-mp-weixin/dist/index.js 编译时,会丢失从父类继承过来的 prop 的定义;
此文件中第 682行定义了如下函数:
function initVueComponent (Vue, vueOptions) {
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
根据 vue.d.ts , 我没有找到 extendOptions 的任何说明,估计是一个未公开的属性吧;
但是 VueComponent.extendOptions 这个属性里面不包含有继承自父类的 Prop,这也就使得,后面在根据返回的 vueOptions 去创建 Vue 的实例时,也丢失了从父类继承而来的 Prop, 进而使得在 unientry.vue 中 :propInParent='title' 无法绑定子组件继承子父组件的 Prop;
问题找到,改正倒是非常简单。 修改 initVueComponent 的函数定义就可以了;
function initVueComponent (Vue, vueOptions) {
let inputVueOptions = vueOptions; //方便调试
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
//#region 往 vueOptions 中补充定义在父组件中但未定义在子组件中的 prop
let defaultInputVueOptions = inputVueOptions['default'];
if (defaultInputVueOptions && defaultInputVueOptions.options && defaultInputVueOptions.options.props) {
if (!vueOptions.props) vueOptions.props = {};
let propsInDefaultInputVueOptions = defaultInputVueOptions.options.props;
for (var oneProp in propsInDefaultInputVueOptions) {
if (!vueOptions.props[oneProp]) {
vueOptions.props[oneProp] = propsInDefaultInputVueOptions[oneProp];
}
}
}
//#endregion
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
编译到微信小程序中,显示正常( 我的版本 , HBuilder X 2.2.2.20190816, )
顺带做了一个项目模板: https://github.com/hesi726/HBuildX-UniApp-Ts-Template
项目转到 TS 以后,基本就没有使用过 Js 了。。所以下面的所有代码都使用 TS 作为说明; (PS.,我的项目的 ts 和 vue 是分开的)。
父组件 BaseUniComponent.ts 就是定义了一个 父组件中的 prop
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
export default class BaseUniComponent extends Vue{
@Prop({ default: null})
propInParent: null | string;
}
子组件 UserMoneyDetail.ts (继承子父组件,并且定义了一个子组件内的 prop)
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import BaseUniComponent from './Basic/BaseUniComponent';
@Component({})
export default class UserIncome extends BaseUniComponent {
@Prop({default: null})
propInComponent: null | string;
}
子组件页面: UserMoneyDetail.vue ( 显示传入进来的 prop 的值)
<template>
<view class="content">
<view>propInComponent: {{propInComponent}}</view>
<view>propInParent: {{propInParent}}</view>
</view>
</template>
<script lang="ts" src='./UserMoneyDetail.ts'></script>
入口页面 unientry.ts
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import UserMoney from './UserMoneyDetail.vue';
@Component({
components: {
UserMoney
}
})
export default class index extends Vue {
title: string = 'Hello';
}
入口页面 unientry.vue (分别绑定了定义在子组件内部的 prop 和 子组件继承自父类的 prop)
<template>
<view>
<UserMoney :propInComponent='title' :propInParent='title'></UserMoney>
</view>
</template>
<script lang="ts" src='./unientry.ts'></script>
在 h5 中这个毫无疑问正常,会显示 2个 Hello,
但是,编译到微信小程序中,却只会显示一个 Hello; ( 我的版本 , HBuilder X 2.2.2.20190816, )
最终发现一个是 HBuilder x 将代码编译成 微信小程序的问题, 也就是 uni-mp-weixin/dist/index.js 编译时,会丢失从父类继承过来的 prop 的定义;
此文件中第 682行定义了如下函数:
function initVueComponent (Vue, vueOptions) {
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
根据 vue.d.ts , 我没有找到 extendOptions 的任何说明,估计是一个未公开的属性吧;
但是 VueComponent.extendOptions 这个属性里面不包含有继承自父类的 Prop,这也就使得,后面在根据返回的 vueOptions 去创建 Vue 的实例时,也丢失了从父类继承而来的 Prop, 进而使得在 unientry.vue 中 :propInParent='title' 无法绑定子组件继承子父组件的 Prop;
问题找到,改正倒是非常简单。 修改 initVueComponent 的函数定义就可以了;
function initVueComponent (Vue, vueOptions) {
let inputVueOptions = vueOptions; //方便调试
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
//#region 往 vueOptions 中补充定义在父组件中但未定义在子组件中的 prop
let defaultInputVueOptions = inputVueOptions['default'];
if (defaultInputVueOptions && defaultInputVueOptions.options && defaultInputVueOptions.options.props) {
if (!vueOptions.props) vueOptions.props = {};
let propsInDefaultInputVueOptions = defaultInputVueOptions.options.props;
for (var oneProp in propsInDefaultInputVueOptions) {
if (!vueOptions.props[oneProp]) {
vueOptions.props[oneProp] = propsInDefaultInputVueOptions[oneProp];
}
}
}
//#endregion
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
编译到微信小程序中,显示正常( 我的版本 , HBuilder X 2.2.2.20190816, )
顺带做了一个项目模板: https://github.com/hesi726/HBuildX-UniApp-Ts-Template
收起阅读 »MUI-POPOVER中加入mui-scroll无法滚动的问题
MUI-POPOVER中加入mui-scroll无法滚动的问题
最近遇到个需求,需要在mui-popover弹出框中加入列表并且有分页,所以就用了mui的上拉加载和下拉刷新,结果发现mui-scroll在mui-popover中不能滑动,经过查询资料得知,mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动)。
最后在mui.js中注市调如下代码就没问题了
参考文章
修改方法:
var onPopoverShown = function(e) {
this.removeEventListener('webkitTransitionEnd', onPopoverShown);
// 发现说是mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动),注释掉下面这段就好了
// this.addEventListener($.EVENT_MOVE, $.preventDefault);
$.trigger(this, 'shown', this);
}
MUI-POPOVER中加入mui-scroll无法滚动的问题
最近遇到个需求,需要在mui-popover弹出框中加入列表并且有分页,所以就用了mui的上拉加载和下拉刷新,结果发现mui-scroll在mui-popover中不能滑动,经过查询资料得知,mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动)。
最后在mui.js中注市调如下代码就没问题了
参考文章
修改方法:
var onPopoverShown = function(e) {
this.removeEventListener('webkitTransitionEnd', onPopoverShown);
// 发现说是mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动),注释掉下面这段就好了
// this.addEventListener($.EVENT_MOVE, $.preventDefault);
$.trigger(this, 'shown', this);
}
收起阅读 »
在 WebStorm 中开发 uni-app
CLI 工程
全局安装 vue-cli 3.x(如已安装请跳过此步骤)
npm install -g @vue/cli
通过 CLI 创建 uni-app 项目
vue create -p dcloudio/uni-preset-vue my-project
此时,会提示选择项目模板,初次体验建议选择 hello uni-app
项目模板,如下所示:
<div>
<img src="http://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/h5-cli-01.png" width="300">
</div>
在 WebStorm 中打开项目
CLI 工程默认带了 uni-app 语法提示和 5+App 语法提示
运行项目
npm run dev:%PLATFORM%
发布项目
npm run build:%PLATFORM%
%PLATFORM%
可取值如下:
值 | 平台 |
---|---|
h5 | H5 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
mp-weixin | 微信小程序 |
mp-toutiao | 头条小程序 |
mp-qq | qq 小程序 |
HBuilderX 工程
HBuilderX 创建的工程默认不带 types 语法提示,在 WebStorm 中编辑的时候,可以自行安装
初始化npm(如已初始化跳过此步骤)
npm init -y
安装 uni-app 语法提示
npm i @dcloudio/types -D
注意
webstorm不识别rpx等单位
如果想了解HBuilderX为uni-app做了什么更好的优化,参考:https://ask.dcloud.net.cn/article/35451
CLI 工程
全局安装 vue-cli 3.x(如已安装请跳过此步骤)
npm install -g @vue/cli
通过 CLI 创建 uni-app 项目
vue create -p dcloudio/uni-preset-vue my-project
此时,会提示选择项目模板,初次体验建议选择 hello uni-app
项目模板,如下所示:
<div>
<img src="http://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/h5-cli-01.png" width="300">
</div>
在 WebStorm 中打开项目
CLI 工程默认带了 uni-app 语法提示和 5+App 语法提示
运行项目
npm run dev:%PLATFORM%
发布项目
npm run build:%PLATFORM%
%PLATFORM%
可取值如下:
值 | 平台 |
---|---|
h5 | H5 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
mp-weixin | 微信小程序 |
mp-toutiao | 头条小程序 |
mp-qq | qq 小程序 |
HBuilderX 工程
HBuilderX 创建的工程默认不带 types 语法提示,在 WebStorm 中编辑的时候,可以自行安装
初始化npm(如已初始化跳过此步骤)
npm init -y
安装 uni-app 语法提示
npm i @dcloudio/types -D
注意
webstorm不识别rpx等单位
如果想了解HBuilderX为uni-app做了什么更好的优化,参考:https://ask.dcloud.net.cn/article/35451
收起阅读 »uniapp安卓缓存计算、缓存清理
官方有个未显示的文档http://www.html5plus.org/doc/zh_cn/cache.html用于管理应用缓存
但有些方法在uniapp上报错
感谢二位大佬提供的文章
师大酸梅杨
https://ask.dcloud.net.cn/article/1191
绝地求生
https://ask.dcloud.net.cn/article/13375
通过两位大佬的文章结合做出一个在uniapp安卓系统上可以计算缓存和清理缓存的代码,ios上可以计算但未找到获取缓存路径的方法,希望官方给出方案
计算缓存大小方法
formatSize() {
let that = this;
plus.cache.calculate(function(size) {
let sizeCache = parseInt(size);
if (sizeCache == 0) {
that.fileSizeString = "0B";
} else if (sizeCache < 1024) {
that.fileSizeString = sizeCache + "B";
} else if (sizeCache < 1048576) {
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
} else if (sizeCache < 1073741824) {
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
} else {
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
}
});
}
安卓清理缓存方法
clearCache() {
let that = this;
let os = plus.os.name;
if (os == 'Android') {
let main = plus.android.runtimeMainActivity();
let sdRoot = main.getCacheDir();
let files = plus.android.invoke(sdRoot, "listFiles");
let len = files.length;
for (let i = 0; i < len; i++) {
let filePath = '' + files[i]; // 没有找到合适的方法获取路径,这样写可以转成文件路径
plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
if (entry.isDirectory) {
entry.removeRecursively(function(entry) { //递归删除其下的所有文件及子目录
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize(); // 重新计算缓存
}, function(e) {
console.log(e.message)
});
} else {
entry.remove();
}
}, function(e) {
console.log('文件路径读取失败')
});
}
} else { // ios暂时未找到清理缓存的方法,以下是官方提供的方法,但是无效,会报错
plus.cache.clear(function() {
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize();
});
}
}
官方有个未显示的文档http://www.html5plus.org/doc/zh_cn/cache.html用于管理应用缓存
但有些方法在uniapp上报错
感谢二位大佬提供的文章
师大酸梅杨
https://ask.dcloud.net.cn/article/1191
绝地求生
https://ask.dcloud.net.cn/article/13375
通过两位大佬的文章结合做出一个在uniapp安卓系统上可以计算缓存和清理缓存的代码,ios上可以计算但未找到获取缓存路径的方法,希望官方给出方案
计算缓存大小方法
formatSize() {
let that = this;
plus.cache.calculate(function(size) {
let sizeCache = parseInt(size);
if (sizeCache == 0) {
that.fileSizeString = "0B";
} else if (sizeCache < 1024) {
that.fileSizeString = sizeCache + "B";
} else if (sizeCache < 1048576) {
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
} else if (sizeCache < 1073741824) {
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
} else {
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
}
});
}
安卓清理缓存方法
clearCache() {
let that = this;
let os = plus.os.name;
if (os == 'Android') {
let main = plus.android.runtimeMainActivity();
let sdRoot = main.getCacheDir();
let files = plus.android.invoke(sdRoot, "listFiles");
let len = files.length;
for (let i = 0; i < len; i++) {
let filePath = '' + files[i]; // 没有找到合适的方法获取路径,这样写可以转成文件路径
plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
if (entry.isDirectory) {
entry.removeRecursively(function(entry) { //递归删除其下的所有文件及子目录
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize(); // 重新计算缓存
}, function(e) {
console.log(e.message)
});
} else {
entry.remove();
}
}, function(e) {
console.log('文件路径读取失败')
});
}
} else { // ios暂时未找到清理缓存的方法,以下是官方提供的方法,但是无效,会报错
plus.cache.clear(function() {
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize();
});
}
}
收起阅读 »
uni 统计自定义事件说明
自定义事件是为了给开发者提供自定义上报统计数据的功能,如统计登录、注册、分享、点击某个按钮,我们都可以称之为自定义事件。
自定义事件 API
uni.report( eventName , options)
参数说明
参数 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名称,最大长度不超过 255 个字符 |
options | String 、 Object | 事件参数 |
Tips
- eventName 为 String 类型,并且字符长度必须小于255
- options 为 String 类型时,字符长度必须小于255
- options 为 Object 类型时,该对象的值只能为 String 类型
- 字符串支持特殊字符但不包括(英文逗号 , 英文冒号 : 点 .)
- eventName 为
title
时为内容标题上报,用户不能自定义。此时数据会展现在uni统计的首页-内容统计及左侧导航的内容统计中。方便查看内容页数据。 - 用户在使用
uni.login()
会执行登录事件,不携带参数。如果如需上报携带具体参数的数据,需要手动调用uni.report('login',{...})
- 用户在使用
uni.share()
或触发onShareAppMessage
会执行分享事件,不携带参数。如果如需上报携带具体参数的数据,需要手动调用uni.report('share',{...})
- 用户在使用
uni.requestPayment()
会执行支付事件,不携带参数。如果如需上报携带具体参数的数据,需要手动调用uni.report('pay_success',{...})
和uni.report('pay_fail',{...})
示例
// 内容统计
// 当 eventName 为 title 时,options 只能为 String 类型
uni.report('title','首页')
// 登录
uni.report('login',{
'name':'uni-app',
'age':'21',
// ...
})
// 分享
uni.report('share','分享')
// 支付成功
uni.report('pay_success','支付成功')
// or
uni.report('pay_success',{
"订单金额":'20元',
"订单名称":'鼠标',
// ...
})
// 支付失败
uni.report('pay_fail','支付失败')
// or
uni.report('pay_fail',{
"订单金额":'20元',
"订单名称":'鼠标',
// ...
})
// 注册
uni.report('register',{
'name':'uni-app',
'age':'21',
// ...
})
// 搜索
uni.report('search','搜索内容')
// or
uni.report('search',{
'内容':'搜索内容'
})
自定义事件上报后,在统计后台的事件和转换
栏目中,可以看到上报的事件情况。
自定义事件是为了给开发者提供自定义上报统计数据的功能,如统计登录、注册、分享、点击某个按钮,我们都可以称之为自定义事件。
自定义事件 API
uni.report( eventName , options)
参数说明
参数 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名称,最大长度不超过 255 个字符 |
options | String 、 Object | 事件参数 |
Tips
- eventName 为 String 类型,并且字符长度必须小于255
- options 为 String 类型时,字符长度必须小于255
- options 为 Object 类型时,该对象的值只能为 String 类型
- 字符串支持特殊字符但不包括(英文逗号 , 英文冒号 : 点 .)
- eventName 为
title
时为内容标题上报,用户不能自定义。此时数据会展现在uni统计的首页-内容统计及左侧导航的内容统计中。方便查看内容页数据。 - 用户在使用
uni.login()
会执行登录事件,不携带参数。如果如需上报携带具体参数的数据,需要手动调用uni.report('login',{...})
- 用户在使用
uni.share()
或触发onShareAppMessage
会执行分享事件,不携带参数。如果如需上报携带具体参数的数据,需要手动调用uni.report('share',{...})
- 用户在使用
uni.requestPayment()
会执行支付事件,不携带参数。如果如需上报携带具体参数的数据,需要手动调用uni.report('pay_success',{...})
和uni.report('pay_fail',{...})
示例
// 内容统计
// 当 eventName 为 title 时,options 只能为 String 类型
uni.report('title','首页')
// 登录
uni.report('login',{
'name':'uni-app',
'age':'21',
// ...
})
// 分享
uni.report('share','分享')
// 支付成功
uni.report('pay_success','支付成功')
// or
uni.report('pay_success',{
"订单金额":'20元',
"订单名称":'鼠标',
// ...
})
// 支付失败
uni.report('pay_fail','支付失败')
// or
uni.report('pay_fail',{
"订单金额":'20元',
"订单名称":'鼠标',
// ...
})
// 注册
uni.report('register',{
'name':'uni-app',
'age':'21',
// ...
})
// 搜索
uni.report('search','搜索内容')
// or
uni.report('search',{
'内容':'搜索内容'
})
自定义事件上报后,在统计后台的事件和转换
栏目中,可以看到上报的事件情况。
uni统计1.0入门教程
uni统计2.0已经发布 ,uni统计2.0 是开源、全端、云端一体的统计平台
。另行查看:文档
以下是uni统计1.0的文档
- 无需在各端接不同的sdk、无需在不同报表看数据。uni统计:一张报表看遍业务全景。
- 拉通内容。让你知道用户到底喜欢你提供的什么内容,不管是新闻app里的新闻,还是购物app里的商品,都可以一目了然的看到全景。
web控制台地址:https://tongji.dcloud.net.cn
第一步、配置统计开关
自 uni-app 2.2.3版本后,uni-app
项目在发布时会默认启用 uni统计,开发者可在https://tongji.dcloud.net.cn查看数据报表。
但从 uni-app 2.7起,默认值改为了不启用。需要在manifest中手动配置开启。
在HBuilderX中打开manifest,选择 uni统计,如下图:
如果不使用HBuilderX,也可在 manifest.json
的源码视图中手动关闭 uni统计
将 manifest.json -> uniStatistics
下的 enable
字段设置为 false
来关闭 uni 统计
//...
"uniStatistics": {
"enable": false//全局关闭
},
//...
注意:uniStatistics
支持分平台设置,比如若需仅关闭微信平台的 uni统计,则在mp-weixin
节点下设置uniStatistics ->enable
即可,如下:
//...
"mp-weixin":{
"uniStatistics": {
"enable": false //微信平台关闭统计
}
}
第二步、小程序端需添加域名访问白名单
由于各家小程序对可访问的域名要配置白名单,否则无法联网,所以需要将tongji.dcloud.io
配入服务器域名列表。详细教程可参考https://ask.dcloud.net.cn/article/36298
第三步、使用HBuilderX 2.2.3以上或对应的cli版发行应用
应用在运行、调试时不会上报统计数据,仅在发行后,并启动新版的App、h5、小程序,才会上报数据。
第四步、登陆统计后台看数据
uni统计报表网址:https://tongji.dcloud.net.cn
请使用正确的DCloud账户登陆后台,每个DCloud账户登陆后可看到自己名下创建的应用。如果看不到期待的应用,那说明这个账户不是某个应用的所有者。
如果appid对应的项目的所有者发生变更,请参考如何转让应用
数据报表更新有延时,手机端上报数据后延迟几十分钟可在后台报表看到数据。
发行时为什么提示“当前应用未配置Appid,无法使用uni统计”
uni统计
以appid区分不同应用,因此在编译项目时,若发现当前应用未配置appid,则会在控制台显示如下警告提醒:
当前应用未配置Appid,无法使用uni统计
此时,开发者可通过HBuilderX、DCloud开发者中心两个入口创建应用,获取Appid。
方式1. 登录HBluiderX获取
在HBluiderX中先登录,然后在项目根目录打开 manifest.json
,在可视化界面点击获取 APPID
获取,无需其他设置,如下图
方式2. 登录DCoud开发者中心获取(即将支持)
登录DCloud开发者中心,在线创建应用,然后将新应用的appid填写到manifest.json中
{
// ...
"appid":"创建的 appid"
// ...
}
Tips
- 使用 uni 统计必须配置
APPID
才能正常使用 - 获取以及创建的
APPID
是与您的DCloud
账号绑定的,请不要随意填写,否则将不能正常获取上报内容 - 部分开发者不重视Appid,在不同应用中使用相同的appid,请修改这些错误的行为。
- 附参考文章:DCloud的Appid有什么用,如需转让应用怎么做
注意事项
- uni统计具备当日实时数据统计功能,但这个实时,仍然要经历一定运算时间,一般在3分钟到1个小时内的不等。
- 如果开发者连续3日不登录uni统计控制台,则暂停实时统计服务;再次登录后1小时内会开始进行实时统计。这种暂停不影响日报、不影响整体数据准确性。
- 如果开发者连续1个月不登录uni统计控制台,则暂停数据上报功能。再次登录后点击按钮恢复数据上报。暂停前系统会发送提醒邮件给开发者。暂停期间,数据不再记录,历史数据不受影响。恢复后,暂停期间的数据也无法恢复。
常见问题
-
后台数据一直显示 0 ,看不到数据上报
- 请检查
manifest.json
是否配置 uni 统计为开启 - 如已经配置请检查
HBuilderX
是否升级到2.2.3
版本以上,CLI
方式是否升级到最新。 - 请确认小程序的服务器域名名单中加入了
tongji.dcloud.io
- 请确认带有uni统计的新版本已经发布到手机上并且启动运行
- 统计数据有几十分钟的延迟,如果是刚配上,请等一会再刷新报表
- 应用需发布后才有数据,运行期不上报数据
- 当日实时统计显示逻辑:3天内未登录统计后台的应用不会处理当日实时统计;再次登录后1小时内会开始进行实时统计。
- 请检查
-
自定义事件怎么用
使用uni.report()
API 上报数据,详见自定义事件说明 -
内容统计是什么/ 页面规则怎么配置
内容统计是uni统计的特色功能之一,是内容详情页的访问统计,详见内容统计说明 -
不支持导入老数据合并统计。uni统计需要自开通上线后才有数据
-
售卖用户数据,或未经用户同意共享数据给第三方,属于违法行为,DCloud严格遵守国家法律要求,uni统计可安心使用。
uni统计2.0已经发布 ,uni统计2.0 是开源、全端、云端一体的统计平台
。另行查看:文档
以下是uni统计1.0的文档
- 无需在各端接不同的sdk、无需在不同报表看数据。uni统计:一张报表看遍业务全景。
- 拉通内容。让你知道用户到底喜欢你提供的什么内容,不管是新闻app里的新闻,还是购物app里的商品,都可以一目了然的看到全景。
web控制台地址:https://tongji.dcloud.net.cn
第一步、配置统计开关
自 uni-app 2.2.3版本后,uni-app
项目在发布时会默认启用 uni统计,开发者可在https://tongji.dcloud.net.cn查看数据报表。
但从 uni-app 2.7起,默认值改为了不启用。需要在manifest中手动配置开启。
在HBuilderX中打开manifest,选择 uni统计,如下图:
如果不使用HBuilderX,也可在 manifest.json
的源码视图中手动关闭 uni统计
将 manifest.json -> uniStatistics
下的 enable
字段设置为 false
来关闭 uni 统计
//...
"uniStatistics": {
"enable": false//全局关闭
},
//...
注意:uniStatistics
支持分平台设置,比如若需仅关闭微信平台的 uni统计,则在mp-weixin
节点下设置uniStatistics ->enable
即可,如下:
//...
"mp-weixin":{
"uniStatistics": {
"enable": false //微信平台关闭统计
}
}
第二步、小程序端需添加域名访问白名单
由于各家小程序对可访问的域名要配置白名单,否则无法联网,所以需要将tongji.dcloud.io
配入服务器域名列表。详细教程可参考https://ask.dcloud.net.cn/article/36298
第三步、使用HBuilderX 2.2.3以上或对应的cli版发行应用
应用在运行、调试时不会上报统计数据,仅在发行后,并启动新版的App、h5、小程序,才会上报数据。
第四步、登陆统计后台看数据
uni统计报表网址:https://tongji.dcloud.net.cn
请使用正确的DCloud账户登陆后台,每个DCloud账户登陆后可看到自己名下创建的应用。如果看不到期待的应用,那说明这个账户不是某个应用的所有者。
如果appid对应的项目的所有者发生变更,请参考如何转让应用
数据报表更新有延时,手机端上报数据后延迟几十分钟可在后台报表看到数据。
发行时为什么提示“当前应用未配置Appid,无法使用uni统计”
uni统计
以appid区分不同应用,因此在编译项目时,若发现当前应用未配置appid,则会在控制台显示如下警告提醒:
当前应用未配置Appid,无法使用uni统计
此时,开发者可通过HBuilderX、DCloud开发者中心两个入口创建应用,获取Appid。
方式1. 登录HBluiderX获取
在HBluiderX中先登录,然后在项目根目录打开 manifest.json
,在可视化界面点击获取 APPID
获取,无需其他设置,如下图
方式2. 登录DCoud开发者中心获取(即将支持)
登录DCloud开发者中心,在线创建应用,然后将新应用的appid填写到manifest.json中
{
// ...
"appid":"创建的 appid"
// ...
}
Tips
- 使用 uni 统计必须配置
APPID
才能正常使用 - 获取以及创建的
APPID
是与您的DCloud
账号绑定的,请不要随意填写,否则将不能正常获取上报内容 - 部分开发者不重视Appid,在不同应用中使用相同的appid,请修改这些错误的行为。
- 附参考文章:DCloud的Appid有什么用,如需转让应用怎么做
注意事项
- uni统计具备当日实时数据统计功能,但这个实时,仍然要经历一定运算时间,一般在3分钟到1个小时内的不等。
- 如果开发者连续3日不登录uni统计控制台,则暂停实时统计服务;再次登录后1小时内会开始进行实时统计。这种暂停不影响日报、不影响整体数据准确性。
- 如果开发者连续1个月不登录uni统计控制台,则暂停数据上报功能。再次登录后点击按钮恢复数据上报。暂停前系统会发送提醒邮件给开发者。暂停期间,数据不再记录,历史数据不受影响。恢复后,暂停期间的数据也无法恢复。
常见问题
-
后台数据一直显示 0 ,看不到数据上报
- 请检查
manifest.json
是否配置 uni 统计为开启 - 如已经配置请检查
HBuilderX
是否升级到2.2.3
版本以上,CLI
方式是否升级到最新。 - 请确认小程序的服务器域名名单中加入了
tongji.dcloud.io
- 请确认带有uni统计的新版本已经发布到手机上并且启动运行
- 统计数据有几十分钟的延迟,如果是刚配上,请等一会再刷新报表
- 应用需发布后才有数据,运行期不上报数据
- 当日实时统计显示逻辑:3天内未登录统计后台的应用不会处理当日实时统计;再次登录后1小时内会开始进行实时统计。
- 请检查
-
自定义事件怎么用
使用uni.report()
API 上报数据,详见自定义事件说明 -
内容统计是什么/ 页面规则怎么配置
内容统计是uni统计的特色功能之一,是内容详情页的访问统计,详见内容统计说明 -
不支持导入老数据合并统计。uni统计需要自开通上线后才有数据
-
售卖用户数据,或未经用户同意共享数据给第三方,属于违法行为,DCloud严格遵守国家法律要求,uni统计可安心使用。
页面绑定的数据深层次更新,Dom没有检测到导致页面并没有重新渲染。
这是一个上拉加载的回调函数,调用getListDataFromNet函数从服务端获取数据,然后更新到页面数据orderList中,因为orderList是一个二维数组,所以深层的数据更新不会触发Dom的重新渲染,于是在数据更新后添加强制重新渲染 this.$forceUpdate(); 问题解决。
upCallback(mescroll) {
//联网加载数据
this.getListDataFromNet(mescroll.num, mescroll.size, (curPageData)=>{
//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
mescroll.endSuccess(curPageData.length);
//设置列表数据
if(mescroll.num == 1) this.orderList[this.tabIndex] = []; //如果是第一页需手动制空列表
this.orderList[this.tabIndex]=this.orderList[this.tabIndex].concat(curPageData); //追加新数据
console.log(this.orderList[this.tabIndex])
this.$forceUpdate();
}, () => {
//联网失败的回调,隐藏下拉刷新的状态
mescroll.endErr();
})
},
这是一个上拉加载的回调函数,调用getListDataFromNet函数从服务端获取数据,然后更新到页面数据orderList中,因为orderList是一个二维数组,所以深层的数据更新不会触发Dom的重新渲染,于是在数据更新后添加强制重新渲染 this.$forceUpdate(); 问题解决。
upCallback(mescroll) {
//联网加载数据
this.getListDataFromNet(mescroll.num, mescroll.size, (curPageData)=>{
//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
mescroll.endSuccess(curPageData.length);
//设置列表数据
if(mescroll.num == 1) this.orderList[this.tabIndex] = []; //如果是第一页需手动制空列表
this.orderList[this.tabIndex]=this.orderList[this.tabIndex].concat(curPageData); //追加新数据
console.log(this.orderList[this.tabIndex])
this.$forceUpdate();
}, () => {
//联网失败的回调,隐藏下拉刷新的状态
mescroll.endErr();
})
},
收起阅读 »
QQ小程序qq.getMenuButtonBoundingClientRect()获取为空
没关系,它不给,我们可以用模拟器+真机调试自己算
先给结论
{width:80,height:30,left:e.windowWidth-12-80,right:e.windowWidth-12,top:e.statusBarHeight+10,bottom:e.statusBarHeight+10+30};
这里的e是用uni.getSystemInfo得到的。可以看到效果如下
没关系,它不给,我们可以用模拟器+真机调试自己算
先给结论
{width:80,height:30,left:e.windowWidth-12-80,right:e.windowWidth-12,top:e.statusBarHeight+10,bottom:e.statusBarHeight+10+30};
这里的e是用uni.getSystemInfo得到的。可以看到效果如下
uni 内容统计说明
内容统计是uni统计的特色功能之一,是内容详情页的访问统计。
如果你做的是新闻App,那么新闻详情页就是内容统计,你可以方便的了解什么样的新闻访问次数、分享次数更高。
如果你做的是电商App,那么商品详情页就是内容统计,你可以方便的了解什么样的商品人们最感兴趣、分享次数更多。
如果详情页标题,是pages.json配置的原生导航,且正是内容标题本身,那么无需配置。在uni统计里可直接查看报表。
但如果使用自定义导航栏或者内容标题写在了别处,参考本文下方【页面标题采集】一节上报正确的页面标题,以方便报表展示。
内容统计会根据 url 的参数进行分析,根据参数的不同,将相同的页面进行分组。如资讯类应用的新闻页面,不同的新闻内容计为多个内容页。 商城类应用的商品详情页面,不同的产品计为多个内容页
【重要】为了保证采集到的内容 url 是正确有效的,需要先配置【页面规则】才会采集内容页面。页面规则介绍及配置方法详见下文。
实际场景使用说明
我们以社区版的 Hello uni-app 为例,现在我们想知道每个帖子的访问人数最多,那个问题是用户最关注的, 这个时候就需要用到内容统计了。
那么我们如果统计到同一个页面不同的内容呢 ?
内容统计名词说明
-
页面
不同 url 表示一个不同的页面,如在pages.json --> pages
下的每一项都表示一个不同页面 -
内容页
相同的 url,不同的参数值表示一个内容页面 -
内容名称
可以让用户直观感受的名称,如某个商品的详情,某个新闻的描述,可通过自定义事件自主上报
什么是页面规则
页面规则是用于生成内容统计 url 的规则。通过设置页面有效参数,通过带参数的 url 对内容进行标识。
如当前我们需要统计的页面地址为 pages/forum/detail/detial
的一个详情内容页,而这个页面是需要从前一个页面携带参数跳转过来的。通过携带的参数,我们才能知道这个页面的内容是什么。
例:
如下是一个页面完整的 url 表达
pages/forum/detail/detial?id=1&type=2&title=搜索内容
当前 url 传递了三个参数 id
、type
、title
,但是只有 id
和type
这两个参数才是有效参数,需要通过这两个参数来决定展示内容(如 request 请求数据)
id
、type
就是当前页面的页面规则,这两个参数是区分页面的唯一方式,缺一不可。
配置页面规则
进入到统计后台,点击列表左侧导航的 内容统计 --> 页面规则 --> 编辑规则
如下图,点击添加参数,添加 id
和 type
,确定保存规则,
这个时候的规则如下
-
当前页面 url 中包含
id
、type
两个参数,且这两个参数值相同的情况下,我们认为这是同一个内容页面 -
当前页面 url 中包含
id
、type
两个参数,且这两个参数值不同的情况下,我们认为这是一个新的内容页面 -
当前页面 url 中不包含任何规则中的参数,那么此页面将不会在内容统计中显示
Tips
- 每条规则可以添加多个参数,进行匹配时,每条规则单独生效。
- 每个页面可以添加多个规则(最多 5 个规则),进行匹配时,后添加的规则优先级较高
- 目前的匹配规则只能处理通过 url 显式传递参数,且参数形式为上述示例中的键值对格式。
页面标题采集
在页面规则配置成功之后,在 内容统计 --> 内容统计
中的会显示根据规则匹配到的页面,到这一步,应该可以正常统计到详情页,为了更直观的感受,需要采集页面标题。
统计 SDK 会自动采集页面标题,页面标题的采集来源有以下几种
- 采集原生导航栏标题(通过 pages.json 获取)
- 采集 uni.setNavigationBarTitle()
- 采集 uni.reprot()
如果采集的页面标题不符合业务需求,可以通过后台手动修改页面标题。
如果以上几种设置页面标题的行为同时存在,则统计后台按照以下优先级显示页面标题 :
后台直接修改页面标题 > uni.report > uni.setNavigationBarTitle > 原生导航栏获取
如果配置正确的页面规则,正确采集标题,则如下图展示
内容统计是uni统计的特色功能之一,是内容详情页的访问统计。
如果你做的是新闻App,那么新闻详情页就是内容统计,你可以方便的了解什么样的新闻访问次数、分享次数更高。
如果你做的是电商App,那么商品详情页就是内容统计,你可以方便的了解什么样的商品人们最感兴趣、分享次数更多。
如果详情页标题,是pages.json配置的原生导航,且正是内容标题本身,那么无需配置。在uni统计里可直接查看报表。
但如果使用自定义导航栏或者内容标题写在了别处,参考本文下方【页面标题采集】一节上报正确的页面标题,以方便报表展示。
内容统计会根据 url 的参数进行分析,根据参数的不同,将相同的页面进行分组。如资讯类应用的新闻页面,不同的新闻内容计为多个内容页。 商城类应用的商品详情页面,不同的产品计为多个内容页
【重要】为了保证采集到的内容 url 是正确有效的,需要先配置【页面规则】才会采集内容页面。页面规则介绍及配置方法详见下文。
实际场景使用说明
我们以社区版的 Hello uni-app 为例,现在我们想知道每个帖子的访问人数最多,那个问题是用户最关注的, 这个时候就需要用到内容统计了。
那么我们如果统计到同一个页面不同的内容呢 ?
内容统计名词说明
-
页面
不同 url 表示一个不同的页面,如在pages.json --> pages
下的每一项都表示一个不同页面 -
内容页
相同的 url,不同的参数值表示一个内容页面 -
内容名称
可以让用户直观感受的名称,如某个商品的详情,某个新闻的描述,可通过自定义事件自主上报
什么是页面规则
页面规则是用于生成内容统计 url 的规则。通过设置页面有效参数,通过带参数的 url 对内容进行标识。
如当前我们需要统计的页面地址为 pages/forum/detail/detial
的一个详情内容页,而这个页面是需要从前一个页面携带参数跳转过来的。通过携带的参数,我们才能知道这个页面的内容是什么。
例:
如下是一个页面完整的 url 表达
pages/forum/detail/detial?id=1&type=2&title=搜索内容
当前 url 传递了三个参数 id
、type
、title
,但是只有 id
和type
这两个参数才是有效参数,需要通过这两个参数来决定展示内容(如 request 请求数据)
id
、type
就是当前页面的页面规则,这两个参数是区分页面的唯一方式,缺一不可。
配置页面规则
进入到统计后台,点击列表左侧导航的 内容统计 --> 页面规则 --> 编辑规则
如下图,点击添加参数,添加 id
和 type
,确定保存规则,
这个时候的规则如下
-
当前页面 url 中包含
id
、type
两个参数,且这两个参数值相同的情况下,我们认为这是同一个内容页面 -
当前页面 url 中包含
id
、type
两个参数,且这两个参数值不同的情况下,我们认为这是一个新的内容页面 -
当前页面 url 中不包含任何规则中的参数,那么此页面将不会在内容统计中显示
Tips
- 每条规则可以添加多个参数,进行匹配时,每条规则单独生效。
- 每个页面可以添加多个规则(最多 5 个规则),进行匹配时,后添加的规则优先级较高
- 目前的匹配规则只能处理通过 url 显式传递参数,且参数形式为上述示例中的键值对格式。
页面标题采集
在页面规则配置成功之后,在 内容统计 --> 内容统计
中的会显示根据规则匹配到的页面,到这一步,应该可以正常统计到详情页,为了更直观的感受,需要采集页面标题。
统计 SDK 会自动采集页面标题,页面标题的采集来源有以下几种
- 采集原生导航栏标题(通过 pages.json 获取)
- 采集 uni.setNavigationBarTitle()
- 采集 uni.reprot()
如果采集的页面标题不符合业务需求,可以通过后台手动修改页面标题。
如果以上几种设置页面标题的行为同时存在,则统计后台按照以下优先级显示页面标题 :
后台直接修改页面标题 > uni.report > uni.setNavigationBarTitle > 原生导航栏获取
如果配置正确的页面规则,正确采集标题,则如下图展示
收起阅读 »小程序统计域名配置
由于小程序有域名访问白名单限制。在各平台小程序中使用 uni
统计,需要配置合法域名 tongji.dcloud.io
,不然统计无法生效。
以微信小程序为例配置合法域名
- 登录微信公众平台
点击开发 --> 开发设置 --> 服务器域名 --> 修改
- 需要管理员权限微信扫码确认身份
- 在 request 合法域名中配置
tongji.dcloud.io
为合法域名,点击保存并提交
- 打开微信开发者工具,配置对应
appid
,点击详情 --> 项目配置
,在域名信息下 request 合法域名中可以看到第四步配置的tongji.dcloud.io
,表示配置成功
其他小程序平台类似,请在后台添加域名。
注意事项
HBuilderX Alpha 2.2.7 +
版本优化统计接口上报性能,已启用uni统计的历史项目,尽早在小程序后台request安全域名中新增 tongji.dcloud.io
由于小程序有域名访问白名单限制。在各平台小程序中使用 uni
统计,需要配置合法域名 tongji.dcloud.io
,不然统计无法生效。
以微信小程序为例配置合法域名
- 登录微信公众平台
点击开发 --> 开发设置 --> 服务器域名 --> 修改
- 需要管理员权限微信扫码确认身份
- 在 request 合法域名中配置
tongji.dcloud.io
为合法域名,点击保存并提交
- 打开微信开发者工具,配置对应
appid
,点击详情 --> 项目配置
,在域名信息下 request 合法域名中可以看到第四步配置的tongji.dcloud.io
,表示配置成功
其他小程序平台类似,请在后台添加域名。
注意事项
HBuilderX Alpha 2.2.7 +
版本优化统计接口上报性能,已启用uni统计的历史项目,尽早在小程序后台request安全域名中新增 tongji.dcloud.io
unipopup+picker-view,这么低级的bug都有
app效果:
h5,微信小程序无此bug
代码如下
<template>
<view>
<view style="height: 100rpx;"></view>
{{JSON.stringify(value)}}
<button @click="openPopup">打开选择器</button>
<uniPopup :show="false" ref="popup" type="bottom" >
<picker-view class="single-picker" indicator-style="height: 80rpx;" @change="changePicker" :value="value">
<picker-view-column>
<block v-for="(item,index) in list" :key="index">
<view class="disease-item">{{item[labelKey]}}</view>
</block>
<!-- 匿名插槽,可用于 插入显示列表加载提示 -->
<slot></slot>
</picker-view-column>
</picker-view>
</uniPopup>
</view>
</template>
<script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'
export default {
name: "getlocation",
components:{
uniPopup
},
data() {
return {
labelKey: "name",
list: [],
value: [0]
}
},
onLoad() {
this.getList();
},
methods: {
getList() {
for (var i = 0; i < 12; i++) {
this.list.push({
name: "picker-" + i,
id: i
})
}
},
changePicker(e) {
console.log(e.detail.value)
this.value = e.detail.value;
//this.$emit("change",e.detail.value);
},
openPopup() {
this.$refs.popup.open();
},
changePopUp(obj) {
console.log(this.value)
}
}
}
</script>
<style lang="scss">
.single-picker{
height: 50vh;
}
</style>
app效果:
h5,微信小程序无此bug
代码如下
<template>
<view>
<view style="height: 100rpx;"></view>
{{JSON.stringify(value)}}
<button @click="openPopup">打开选择器</button>
<uniPopup :show="false" ref="popup" type="bottom" >
<picker-view class="single-picker" indicator-style="height: 80rpx;" @change="changePicker" :value="value">
<picker-view-column>
<block v-for="(item,index) in list" :key="index">
<view class="disease-item">{{item[labelKey]}}</view>
</block>
<!-- 匿名插槽,可用于 插入显示列表加载提示 -->
<slot></slot>
</picker-view-column>
</picker-view>
</uniPopup>
</view>
</template>
<script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'
export default {
name: "getlocation",
components:{
uniPopup
},
data() {
return {
labelKey: "name",
list: [],
value: [0]
}
},
onLoad() {
this.getList();
},
methods: {
getList() {
for (var i = 0; i < 12; i++) {
this.list.push({
name: "picker-" + i,
id: i
})
}
},
changePicker(e) {
console.log(e.detail.value)
this.value = e.detail.value;
//this.$emit("change",e.detail.value);
},
openPopup() {
this.$refs.popup.open();
},
changePopUp(obj) {
console.log(this.value)
}
}
}
</script>
<style lang="scss">
.single-picker{
height: 50vh;
}
</style>