上一次写小程序还是五年前,最近心血来潮用
uniapp开发了一款微信小程序应用,发现坑是真多啊,有些在我看来比较基础的东西,竟然是微信小程序官方底层的BUG,甚至BUG存在好几年了都不修复,离谱,最后只能曲线救国。用这篇文章记录一下以免后续遇到再浪费时间找解决方案。(持续更新)
注意:我只有ios机器,以下问题均在ios机型上复现,安卓机型不一定有这些问题
小程序问题汇总
1️⃣ textarea组件设置了maxlength时,拼音输入阶段会因为超过字数限制而被打断,无法正常输入中文,且光标位置错乱
1、将 maxlength 设置为 -1
2、在 @input 方法中
handleInput(e){
//...
return {
cursor: e.detail.cursor,
value: e.detail.value
};
}
2️⃣ textarea组件,聚焦键盘弹出会遮挡文本域下面的内容
添加属性 :cursor-spacing="100"
3️⃣ input、textarea重新聚焦时光标始终在最前面,且用focus聚焦时仅第一次会聚焦失败
pages.json 文件中 globalStyle 属性中增加 "renderingMode": "seperated" 关闭同层渲染
注意:这个设置会关闭所有组件的同层渲染,会导致一些问题,如canvas组件在弹窗中时会有残影,关闭弹窗canvas的图形还在,所以要单独给canvas开启同层渲染:在
globalStyle中增加属性"mixedRenderComponents": ["canvas"]
4️⃣ 首次加载页面时,页面中的图片会全屏闪一下
image 标签 mode 属性使用 scaleToFill,再用css设置固定的长高
5️⃣ pre标签失效
设置css属性 white-space: pre-wrap;
6️⃣ 想实现计算器功能,但是eval函数不支持
使用自定义js函数代替:
...
try {
console.log(expr)
const result = this.safeEval(expr);
return isNaN(result) ? "错误" : result.toString();
} catch (e) {
console.log(e)
return "错误";
}
...
/**
* 安全计算表达式值(支持负数)
* @param {string} expr 输入的数学表达式字符串
* @returns {number} 计算结果
*
* 支持功能:
* - 四则运算:+、-、*、/
* - 负数支持:包括一元运算符和负数操作数
* - 括号支持:允许任意嵌套的括号
* - 错误处理:无效表达式返回 NaN
*/
safeEval(expr) {
// 1. 预处理:移除空格并验证表达式
expr = expr.replace(/\s+/g, '');
if (!expr) return NaN;
// 2. 标记化处理(支持负数)
const tokens = [];
let current = '';
for (let i = 0; i < expr.length; i++) {
const char = expr[i];
const isDigitOrDecimal = /[\d\.]/.test(char);
const isOperator = /[\+\-\*\/\(\)]/.test(char);
// 处理负数的特殊情况
const isUnaryMinus = (
(char === '-') &&
(i === 0 || /[\+\-\*\/\(]/.test(expr[i - 1]))
);
if (isUnaryMinus) {
// 一元负号处理
if (current) tokens.push(current);
current = '-';
} else if (isDigitOrDecimal) {
current += char;
} else if (isOperator) {
if (current) {
tokens.push(current);
current = '';
}
tokens.push(char);
}
}
if (current) tokens.push(current);
// 3. 将一元负号转换为特殊标识
const processedTokens = [];
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (token === '-' && (i === 0 || /[\+\-\*\/\(]/.test(tokens[i - 1]))) {
// 一元负号后面跟着左括号的处理
if (tokens[i + 1] === '(') {
processedTokens.push('~');
}
// 一元负号后面是数字的处理
else if (/^-?\d/.test(tokens[i + 1])) {
processedTokens.push('' + (-parseFloat(tokens[i + 1])));
i++;
}
// 其他情况
else {
processedTokens.push('~');
}
} else {
processedTokens.push(token);
}
}
// 4. 运算符优先级定义
const precedence = {
'~': 5, // 一元负号(最高优先级)
'*': 4,
'/': 4,
'+': 3,
'-': 3,
'(': 0,
')': 0
};
// 5. 转换中缀表达式为后缀表达式(逆波兰表示法)
const output = [];
const operators = [];
for (let token of processedTokens) {
// 数字直接输出
if (!isNaN(token)) {
output.push(parseFloat(token));
}
// 左括号压栈
else if (token === '(') {
operators.push(token);
}
// 右括号处理
else if (token === ')') {
while (operators.length > 0 && operators[operators.length - 1] !== '(') {
output.push(operators.pop());
}
if (operators[operators.length - 1] === '(') operators.pop();
}
// 运算符处理
else {
while (
operators.length > 0 &&
precedence[operators[operators.length - 1]] >= precedence[token] &&
operators[operators.length - 1] !== '('
) {
output.push(operators.pop());
}
operators.push(token);
}
}
// 输出剩余运算符
while (operators.length > 0) {
output.push(operators.pop());
}
// 6. 计算后缀表达式
const stack = [];
for (let token of output) {
if (typeof token === 'number') {
stack.push(token);
}
// 处理一元负号
else if (token === '~') {
if (stack.length < 1) return NaN;
const a = stack.pop();
stack.push(-a);
}
// 二元运算符处理
else {
if (stack.length < 2) return NaN;
const b = stack.pop();
const a = stack.pop();
switch (token) {
case '+':
stack.push(a + b);
break;
case '-':
stack.push(a - b);
break;
case '*':
stack.push(a * b);
break;
case '/':
if (b === 0) return NaN; // 除零错误
stack.push(a / b);
break;
default:
return NaN;
}
}
}
// 7. 返回计算结果
if (stack.length !== 1 || isNaN(stack[0])) {
return NaN; // 无效表达式
}
return stack[0];
}
7️⃣ scroll-view组件将scroll-top设置为 0,置顶无效
需要动态设置scroll-top 属性的值,如:
this.contentScrollTop = this.contentScrollTop === 0 ? -1 : 0;
8️⃣ 页面滚动时,textarea不跟随滚动
textarea只能跟随Page滚动,如果是采用overflow滚动的就会出现这个问题
解决方法:要么去掉父层级的overflow 只让最外层的Page滚动;要么换种交互,新开一页去编辑内容(很多app,如微信小红书等,编辑姓名描述都是点击后跳转到新页面编辑)
写在最后
时间比较赶,所以只简单记录下最终的解决方法。想看具体效果的可以访问小程序查看:搜索【公途领航】查看