18. IOS兼容性问题--部分手机丢失换行符
后端接口返回的数据如下,在管理后台编辑的时候,是有换行效果的,可是把接口数据展示在html的textarea标签中,发现在iPhone6 Plus和iPhone11上没有换行效果,在Android手机上和部分评估机型上,换行效果正常。

添加如下样式之后,iPhone6 Plus和iPhone11上的换行效果就正常了。
css
textarea {
white-space: pre-wrap;
}
17. 遇到一个IOS兼容性问题,html的textarea标签,设置了maxlength的情况下,未达到最大输入字符限制,已不能输入
在网上查了一下,说是IOS系统下拼音输入法会存在这样的问题,那也不可能不让用户不使用拼音输入法,最后用Vant
的Field
组件,解决了这个问题。我看Vant
的Field
组件最终渲染出来的节点也是textarea标签,但看不到maxlength属性,我使用的html的textarea标签渲染出来有maxlength属性,说明Vant组件做了一定的处理。
html
<Field
:style="style"
class="vant-textarea"
v-model="textArr[0]"
autosize
type="textarea"
:maxlength="13 * charsPerLine"
placeholder=""
/>>
<script>
import { Field } from 'vant';
</script>
16. textarea每行可以容纳的字数计算
js
const elements = document.getElementsByTagName('textarea');
let textareaWidth = elements[0].clientWidth;
// 设置聚焦
elements[0].setSelectionRange(-1, -1);
elements[0].focus();
// 一个中文占一个字符宽度,一个英文占0.5个字符宽度,在绝大多数字符是中文的情况下
// 假定输入的每个字符的字符宽度是0.9
const fontSize = parseInt(getComputedStyle(elements[0]).fontSize) * 0.9;
charsPerLine.value = Math.floor(textareaWidth / fontSize);
15. Array(length).fill({})浅复制的坑
js
const list = ref([]);
// 错误写法--改变某一项某个属性值,所有项都会改变
list.value = Array(tradeProductList.value.length).fill({
pageNum: 1,
total: 10,
list: [],
show: false,
loading: false,
});
// 正确写法
for (let index = 0, len = tradeProductList.value.length; index < len; index++) {
tradeDetailList.value[index] = {
pageNum: 1,
total: 10,
list: [],
show: false,
loading: false,
};
}
14. 点击一个元素时,让元素位于可视区域?
一个横向的tab,位于页面边缘的tab,点击高亮显示之后,一半位于可视区域,另外一半处于不可见状态,交互体验不好,点击元素之后,让元素处于可视区域的方法是:
需要用到element.scrollIntoView(scrollIntoViewOptions)
, scrollIntoViewOptions是一个配置对象,包含三个属性:
- behavior:定义动画过渡效果,"auto"或 "smooth" 之一。默认为 "auto"。
- block:定义垂直方向的对齐, "start", "center", "end", 或 "nearest"之一。默认为 "start"。
- inline:定义水平方向的对齐, "start", "center", "end", 或 "nearest"之一。默认为 "nearest"。
html
<div class="nav">
<ThemeTabButton
v-for="(item, index) in tabs"
:key="index"
:active="tabName === item.name"
@click="changeTab(name,$event)"
>
{{ item.name }}
</ThemeTabButton>
</div>
<script>
const changeTab = (name: string, e: Event) => {
(e.target as HTMLDivElement).scrollIntoView({
behavior: 'smooth',
block: 'start',
});
// ...
}
</script>
<style>
.nav{
// 要设置水平方向可滚动
overflow-x:auto;
// ...
}
</style>
13. 选项数据定义成数组还是对象好?
有一个picker选项框,数据类型可以定义成下面两种,到底哪种更优雅,答案是第二种,取值的时候更方便,并且vue的v-for
指令也支持对对象进行遍历
js
// 第一种 定义成数组
const options=[
{name:'今天',value:'today'},
{name:'本周',value:'week'},
// ...
];
// 第二种--定义成对象
const options={
'今天':'today',
'本周':'week',
// ...
}
12. flex布局,横向内容超出时引发的两个问题解决方案
问题一:子项内容超出时,无法滚动,重点是要将子项的伸缩属性设置为0,不伸缩。
css
.flex-container{
overflow-x:auto;
}
.flex-item{
flex-shrink: 0;
}
问题2:flex布局横向内容超出屏幕宽度时,设置了justify-content: space-evenly;
,会导致第一项显示不全, 不设置这个属性的话显示就正常,所以要判断一下。
html
<div class="nav" :style="{ justifyContent: cardTh.length > 3 ? 'unset' : 'space-evenly' }">
11. url参数中有特殊字符,将链接复制到移动端微信中之后,发现打不开,如何解决?
url中如果含义一些特殊字符,比如说[]()
, 即便对这些特殊字符用encodeURIComponent
进行编码处理,复制网址到手机上的微信中,这些特殊字符后面的参数会丢失,造成页面打开报错。正确的姿势是对这些字符进行加解密处理,能完美解决参数中含有特殊字符,导致网址复制到移动端微信中无法打开的问题。代码实现如下:
js
// 用法 -- 加密
router.push({
path: '/home',
query: {
texts: encrypt(JSON.stringify(formatTexts.texts)),
},
});
// 解密
const texts=JSON.parse(decrypt(route.query.texts) || '[]');
js
import CryptoJS from 'crypto-js';
// 十六位十六进制数作为密钥
const SECRET_KEY = CryptoJS.enc.Utf8.parse('随便写一串英文+数字的16位字符串');
// 十六位十六进制数作为密钥偏移量
const SECRET_IV = CryptoJS.enc.Utf8.parse('随便写一串英文+数字的16位字符串');
/**
* 加密方法
* @param data
* @returns {string}
*/
export function encrypt(data: any) {
if (typeof data === 'object') {
try {
// eslint-disable-next-line no-param-reassign
data = JSON.stringify(data);
} catch (error) {
console.log('encrypt error:', error);
}
}
const dataHex = CryptoJS.enc.Utf8.parse(data);
const encrypted = CryptoJS.AES.encrypt(dataHex, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.ciphertext.toString();
}
/**
* 解密方法
* @param data
* @returns {string}
*/
export function decrypt(data: any) {
const encryptedHexStr = CryptoJS.enc.Hex.parse(data);
const str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(str, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
后续发现,个别iPhone机型,即使没有特殊字符 ,当url过长时, 在手机端微信中链接会被截断,造成网页打开出现错误,Android机型无此问题。
10. 让光标出现在输入编辑框的最后面的技巧
js
eleDom.setSelectionRange(-1, -1);
eleDom.focus();
9. 有的网站配置了防盗链,引用时需注意
如下的图片地址https://img-home.csdnimg.cn/images/20201124032511.png
,在浏览器中访问正常,在localhost域名下也访问正常,可是在线上环境,就展示为裂图。引用外部图片时,最好不要直接引用,保存到公司的文件服务器上之后再引用。

8.url上的参数是中文,在下一个页面接收参数的一个坑
浏览器会自动对链接上的中文参数进行编码,下一页面如果直接取值使用的话,显示的都是编码之后的字符,完全看不出原来的中文是什么

7. 网站使用的是https
协议,接口返回的用户头像数据,头像链接是http
协议,为什么在有的环境显示正常,有的环境显示不正常?
这主要取决于,每个环境的nginx配置,有没有添加设置HTTP请求自动跳转HTTPS
bash
# 设置HTTP请求自动跳转HTTPS
server {
listen 80;
# 将www.example.com替换成自己的域名
server_name www.example.com;
rewrite ^(.*)$ https://$host$1;
# ...
}
6. 同样的样式设置,在PC端和移动端的效果大不一样
less
.poster-modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
overflow-y: auto;
background-color: transparent;
transform: translate3d(0, 0, 0);
.poster-modal-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: calc(100% - 0.6rem);
height: auto;
overflow-y: auto;
.modal-close-icon {
margin-top: 1.08rem;
color: #fff;
}
}
}
移动端van-popup组件的样式并未被覆盖
PC端van-popup组件的样式被覆盖

修正方法,加多几个选择器,增加选择器的权重,将.poster-modal
改成.poster-modal.van-popup--center.van-popup
。
另外要修改van-popup组件里面元素的样式,要用:deep(.className)
进行选择
5.长链变短链原理
可以看到,有一个短链接服务器,是短链跳转长链的核心。访问短链,请求会先到短链服务器,短链服务器用真实的长链地址进行重定向,最后用户看到的页面内容将会是长链地址内容。

4. Ant-Mobile Modal 组件和Vant Popup组件的差异
Modal 组件再次显示时,里面的dom节点元素会重新创建,Popup组件则会复用上一次的展示元素,在特定的场景,比如说每次打开弹窗之后,在后续的操作中,因业务需要,会给弹窗里面通过js原生操作dom的方式插入新元素,Popup组件会引起bug,因为不会删除上一次创建的dom元素。可以在Popup里面,用v-if控制内容元素根节点,实现与Modal组件相同的效果。
3. 编程心得
- 在业务文件不超过600行的情况下,vue文件的样式最好定义在当前文件中,这样做是因为VSCode支持当前文件定义的样式快捷跳转,查找修改样式很方便
- 在VSCode中安装一下
Vue VSCode Snippets
扩展,创建Vue空白模板很方便。 - Vite热更新并不总是可靠,有时修改了vue文件中的脚本和样式,Vite的热更新并不生效,需要手动刷新才能看到页面修改效果。
- 可选链使用时容易出错的一个点 ,形如
obj?.fooA?.length
,判断一个对象的属性值的长度是否大于0,后面的?.length
判断不能省,省了会引起报错。
2.vue控制台输出的错误日志的偏门解读方法
vue框架在控制台打印的错误日志,有时看的人一头雾水,例如如下的报错信息,把我误导了个把小时。

实际出错的是220行,而非标红的242行,很是误导人,结合报错信息,前后位置都看一下,才能定位到真正的错误。

1. 微软商店引起的一起事故
Win10 操作系统自动升级后, 微软商店的一个服务AppX Deployment Service
CPU和内存占用率异常的高,禁用服务之后,电脑启动之后会卡死,无法操作,最后通过重装系统解决。微软商店是个毒瘤,无法卸载,禁用之后系统无法正常使用。

