mixin.js
4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"use strict";
const common_vendor = require("../../../../common/vendor.js");
const mixin = {
// 定义每个组件都可能需要用到的外部样式以及类名
props: {
// 每个组件都有的父组件传递的样式,可以为字符串或者对象形式
customStyle: {
type: [Object, String],
default: () => ({})
},
customClass: {
type: String,
default: ""
},
// 跳转的页面路径
url: {
type: String,
default: ""
},
// 页面跳转的类型
linkType: {
type: String,
default: "navigateTo"
}
},
data() {
return {};
},
onLoad() {
this.$u.getRect = this.$uGetRect;
},
created() {
this.$u.getRect = this.$uGetRect;
},
computed: {
// 在2.x版本中,将会把$u挂载到uni对象下,导致在模板中无法使用uni.$u.xxx形式
// 所以这里通过computed计算属性将其附加到this.$u上,就可以在模板或者js中使用uni.$u.xxx
// 只在nvue环境通过此方式引入完整的$u,其他平台会出现性能问题,非nvue则按需引入(主要原因是props过大)
$u() {
return common_vendor.index.$u.deepMerge(common_vendor.index.$u, {
props: void 0,
http: void 0,
mixin: void 0
});
},
/**
* 生成bem规则类名
* 由于微信小程序,H5,nvue之间绑定class的差异,无法通过:class="[bem()]"的形式进行同用
* 故采用如下折中做法,最后返回的是数组(一般平台)或字符串(支付宝和字节跳动平台),类似['a', 'b', 'c']或'a b c'的形式
* @param {String} name 组件名称
* @param {Array} fixed 一直会存在的类名
* @param {Array} change 会根据变量值为true或者false而出现或者隐藏的类名
* @returns {Array|string}
*/
bem() {
return function(name, fixed, change) {
const prefix = `u-${name}--`;
const classes = {};
if (fixed) {
fixed.map((item) => {
classes[prefix + this[item]] = true;
});
}
if (change) {
change.map((item) => {
this[item] ? classes[prefix + item] = this[item] : delete classes[prefix + item];
});
}
return Object.keys(classes);
};
}
},
methods: {
// 跳转某一个页面
openPage(urlKey = "url") {
const url = this[urlKey];
if (url) {
this.$u.route({ type: this.linkType, url });
}
},
// 查询节点信息
// 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21)
// 解决办法为在组件根部再套一个没有任何作用的view元素
$uGetRect(selector, all) {
return new Promise((resolve) => {
common_vendor.index.createSelectorQuery().in(this)[all ? "selectAll" : "select"](selector).boundingClientRect((rect) => {
if (all && Array.isArray(rect) && rect.length) {
resolve(rect);
}
if (!all && rect) {
resolve(rect);
}
}).exec();
});
},
getParentData(parentName = "") {
if (!this.parent)
this.parent = {};
this.parent = common_vendor.index.$u.$parent.call(this, parentName);
if (this.parent.children) {
this.parent.children.indexOf(this) === -1 && this.parent.children.push(this);
}
if (this.parent && this.parentData) {
Object.keys(this.parentData).map((key) => {
this.parentData[key] = this.parent[key];
});
}
},
// 阻止事件冒泡
preventEvent(e) {
e && typeof e.stopPropagation === "function" && e.stopPropagation();
},
// 空操作
noop(e) {
this.preventEvent(e);
}
},
onReachBottom() {
common_vendor.index.$emit("uOnReachBottom");
},
beforeDestroy() {
if (this.parent && common_vendor.index.$u.test.array(this.parent.children)) {
const childrenList = this.parent.children;
childrenList.map((child, index) => {
if (child === this) {
childrenList.splice(index, 1);
}
});
}
}
};
exports.mixin = mixin;