31. 如何让一个页面所有的逻辑重新执行一遍?
- 给组件加一个动态的key
- 其次,跳转页面时加一个时间戳
<Layout class="basic-layout-main">
<router-view v-slot="{ Component }">
<component :is="Component" :key="$route.fullPath" />
</router-view>
<BaseWaterMark container=".basic-layout-main" />
</Layout>
<script>
const onNext = (id: string) => {
router.push(`/xxx/${id}/edit?timestamp=${Date.now()}`);
};
</script>
30. vite+vue3 出现 [Vue warn]: Failed to resolve component XXX 如何解决?
vite+vue3编译时出现不能识别的组件警告时,可以用如下配置解决:
// vue语法支持
import vue from '@vitejs/plugin-vue';
export default ({ command, mode }: ConfigEnv) => {
plugins: [
vue({
template: {
// 消除控制台wx-open-launch-weapp引起的警告
compilerOptions: {
isCustomElement: (tag) => {
return tag === 'wx-open-launch-weapp';
},
},
},
}),
],
})
29. [Vue warn]: Component inside renders non-element root node that cannot be animated. 是什么意思,如何解决?
这句话的意思是: <Transition>
里面的组件没有根元素,无法添加动画效果。只要给component加一个根元素,就可以了。
<template>
<router-view v-slot="{ Component, route }">
<div>
<transition>
<keep-alive :include="keepAliveList">
<div :key="route.name">
<component :is="Component" />
</div>
</keep-alive>
</transition>
</div>
</router-view>
</template>
28. v-for循环,key重复的话,会不会造成渲染的内容不断增加?
如下的代码,每次切换tab时,dataClientReport的内容会变化,需要重新渲染dataClientReport列表数据,
因为这里的key取的是item.value,而这个值会重复,最终看到的现象是,在tab切换时,第一轮切换没问题,第二轮切换时,发现重复的记录越来越多,将:key="item.value"
修改成唯一键:key="item.name"
之后,发现这个问题就解决了。
<template v-for="(item, index) in dataClientReport" :key="item.value">
<div class="item" v-if="briefingActive !== 3 || index <= 1">
<div class="name">{{ item.name }}</div>
<div class="value">
{{
briefingActive === 3 && !isManagerKeep && index === 1
? '--'
: item.value
}}
</div>
<div class="supplement" v-if="item.supplement">
{{ item.supplement }}
</div>
</div>
</template>
27. 为什么有些小问题,别人不提,我们发现不了?
比如说图表纵轴表现以人为单位,却出现小数,不合理我们却习以为常,没有先于业务发现。还是欠缺产品思维。
如果使用的是ECharts的话,修正方法是:
yAxis: {
minInterval : 1,
}
26. 为什么设置了style属性,却不生效?
如下vue中的代码,设置的style并不生效,很神奇。后面将style和class的书写顺序调整一下之后,就正常了。在vue的模板中style的渲染规则有点不同于html,html的style必须定义在class属性之后,才能生效。
<template v-if="state.leftInfo.value">
<div class="left">
<div
style="line-height: 0.84rem; font-size: 0.64rem"
class="infoValue text-ellipsis"
>
{{ state.leftInfo?.value }}
</div>
<div class="infoKey">{{ state.leftInfo?.name }}</div>
</div>
</template>
25. VSCode自带的git工具,把项目添加到VSCode中以后,用可视化窗口向远程仓库推送代码报错。怎么办?
解决方案是,基于项目路径打开终端,在终端命令行手动执行一次git push
指令,你会发现可视化界面向远程仓库推送代码功能就正常了。
24. 问题如下,利率有一部分字符展示成乱码,是什么原因?
刚开始以为是字体文件加载报错造成的,后面发现是因为左侧的div宽度不足造成的。发生在IOS 15.4.1上,记录一下,下次就遇到就不慌了。
23. 为什么vue页面引入的组件,突然之间按Ctrl键+鼠标左键点击时无法正常跳转定义处?
最后发现Vue Language Features (Volar) 最近的版本出现问题,升级到1.8.0版本,或者回退到1.7.11版本,组件跳转定义功能正常。刚开始还以为是VSCode版本升级引起的,差点把VSCode版本回退。所以以后升级版本时,记住对哪些扩展进行了升级,要是原本使用正常的功能不能用了,肯定是那些扩展最新的版本出了问题,进行版本回退就可以了。
22. 如何看懂控制台的警告?
如下的控制台警告信息, 如何找到出错的地方。出错信息都是从内向外输出错误。最上面的错误信息,是引起警告的源头。从源头上可以看到一些组件的属性信息,根据这些属性去查找出错的组件,如果点开出错信息左边的小三角,就会进入误区,不太好查找实际出错的地方。
21. 加载页面,vue-router导航报错,可能的原因是?
可能的原因是:
- 页面因为多种原因出现脚本错误
- 网络不好,造成的资源和数据请求错误
20. 使用useInfiniteScroll工具监听容器是否滚动到底,为什么在切换tab的时候,有时加载到底事件会执行两次?
这是因为如果调用了scrollRef.value?.scrollTo(0, 0);
之后,也会触发滚动到底事件,造成误加载,要把这种情况过滤掉。修复之后的代码逻辑如下图所示:
import { useInfiniteScroll } from '@vueuse/core';
const scrollRef = ref<HTMLElement>();
useInfiniteScroll(
scrollRef,
() => {
console.log('上拉加载', scrollRef.value?.scrollTop);
// 上拉加载更多
scrollRef.value!.scrollTop > 0 && emit('loadMoreFun', true);
},
{ distance: 5 }
);
19. 日常开发中有哪些场景,需要提高代码的执行效率?
我能想到的场景有:
- 高频触发的事件 如mouse,scroll, 需要节流或者使用RAF
- 移动dom元素位置,要开启GPU加速
- 查找树形结构的某个元素,要将深度遍历改成广度遍历。
- dom操作,要批量执行。
18. flex布局,为什么一侧的容器被挤扁?
<style>
.flex{
display:flex;
width:300px;
}
.avatar{
width:100px;
height:100px;
background-color:green;
border-radius:100%;
}
.info-desc{
width:220px;
}
</style>
<div class="flex">
<div class="avatar"></div>
<div class="info">
<div class="info-desc">123456</div>
</div>
</div>
效果如下图所示: 可以看出,头像被挤扁。对flex属性不太熟悉的新手,遇到这种诡异现象,一时肯定不知如何排查bug,解决方法就是让info下面的元素,宽度不要溢出。本例中宽度不能超过200px.
17. 今天发现, 微信分享出去的卡片,png格式的图片,在Android手机上展示不正常?
16. 下面的代码有什么问题?
下面的代码看着简单, 如果不细想,可能导致页面跳转出错。如果props.productDetail.productLink
中没有查询参数,下面的代码在运行时就会造成页面一片空白。
const jumpUrl = props.productDetail.productLink + `&a=foo`;
正确的写法是:
const joiner = props.productDetail.productLink.includes('?') ? '&' : '?';
const jumpUrl = props.productDetail.productLink + `${joiner}a=foo`;
15. 基于nx+workspace微前端架构,跨feature使用hooks, hooks变量是undefined,如何解决?
首先,要将hooks定义在shared特性库,这样才能被访问到。其次,hooks要定义成函数,才能在页面加载的时候正确执行。
import { computed } from 'vue';
export function useProduct() {
const amount=computed(()=>props.data * 2);
return {amount};
}
14. git stash pop之后,代码出现冲突,如何撤销操作?
切错了分支, 执行git stash pop
后,引起代码冲突。想撤销git stash pop
弹出储存的内容,如何撤销,既能将代码状态恢复到冲突之前,还能保留git stash
保存的内容。 答案是执行git reset --hard
,这个指令说出来你肯定知道,可是在特定场景下的其它功效,你可能未必清楚。
13. async/await 出错之后,会不会执行到await之后的程序片段?
如下, 如果const res= await Api.getData(params)
执行出错,是不会走到console.log(res)
这里的,然而我发现,许多人以为可以执行到,在后面写了一些错误判断处理逻辑,其实是在做无用功。
async foo(){
const res= await Api.getData(params);
console.log(res);
}
12. 上拉加载更多功能, 除了用IScroll,还有哪些选择?
今天发现在vue中,一个比较好用的判断是否滚动到容器底部的方法useInfiniteScroll
,用法如下:
<script setup lang="ts">
import { ref } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
const el = ref<HTMLElement>(null)
const data = ref([1, 2, 3, 4, 5, 6])
useInfiniteScroll(
el,
() => {
// load more
data.value.push(...moreData)
},
{ distance: 10 }
)
</script>
<template>
<div ref="el">
<div v-for="item in data">
{{ item }}
</div>
</div>
</template>
11. 组件中错误的v-if/v-else-if逻辑,造成下拉滚动列表, 每次数据加载的时候,无法复用上次渲染的数据,会滚动到容器顶部, 怎么处理?
这是错误的流程,错误之处在于,每次loading值发生变化时,ArticleListItem组件会被重新渲染。
<Loading class="loading" v-if="isLoading" />
<template v-else-if="list?.length > 0">
<ArticleListItem
v-for="(item, index) in list"
:key="index"
:data="item"
:queryType="queryType"
@click="openArticleDetailPage"
/>
<BaseEndLine class="bottom-tips" v-if="showEnd">已经到底啦</BaseEndLine>
</template>
改成这样就对了
<Loading v-if="isLoading" class="loading" />
<div class="article-list" ref="scrollRef">
<template v-if="list?.length > 0">
<ArticleListItem
v-for="(item, index) in list"
:key="index"
:data="item"
:queryType="queryType"
@click="openArticleDetailPage"
/>
<BaseEndLine class="bottom-tips" v-if="showEnd">已经到底啦</BaseEndLine>
</template>
</div>
10. axios 如何对post请求,json数据进行提交前的转换?
方式一: 使用transformRequest函数
const instance = axios.create({
baseURL: 'api-url.com',
transformRequest: [
(data, headers) => {
// 入参data是对象
const transData = trans(data);
// 出参要返回字符串才行
return JSON.stringify(transData);
},
],
});
方式二: 直接修改config.data
instance.interceptors.request.use(
function (config) {
config.data=trans(config.data);
}
)
9. Chrome浏览器的微信调试功能,为什么有时候突然没有反应?
如下图所示, Chrome的H5页面调试功能,有时突然不展示任何H5页面内容。
这是因为手机上的微信,会时不时的自动进行更新。每次更新之后,之前设置的调试功能会被覆盖。所以需要重新设置。在微信中点击下面的链接http://debugxweb.qq.com/?inspector=true
,就可重新开启微信H5页面的调试功能。
8. 如何提取字符串中的数字?
提取连续在一起的单个数字:
const mixsStr = '1000起投';
// 将非数字字符全部替换成空字符
const num = mixStr.replace(/[^0-9]/ig, '');
num 结果 "1000"
上面的方法,并不通用,更通用的提取字符串中数字的方法是:
// 匹配以
const reg = /[1-9][0-9]*/g;
// 如果要匹配数字0,这里要改成
// const reg = /\d*/g;
const mixStr= '1000元起投,递增金额100元';
const num = mixStr.match(reg);
// num 结果 ["1000", "100"]
7. ant-design-vue, 如何禁用表格复选框的某些记录?
在官网查了一下如何禁用多选表格某些选项的示例,发现示例并不满足要求,不是按照记录中的某个属性设置禁用,看了好几篇文章,发现下面的方法是可行的。
const rowSelection = {
selectedRowKeys,
onSelect: (record, selected, selectedRows) => {
// ...
},
onSelectAll: (selected, selectedRows, changeRows) => {
// ...
},
getCheckboxProps: (record) => {
if (record.isDelete == 1) {
return { disabled: true };
} else {
return null;
}
},
};
6. 如何让一张图片铺满整个屏幕,且不变形?
body{
min-height:100vh;
background-url:url('xxx');
}
横向铺不满或铺满之后图片会变形的解决方法:
background-size: 100% auto;
横向图片铺不满或铺满之后图片会变形的解决方法:
纵向图片铺不满的解决方法:
background-color: '和背景图片的主色调一致';
5. 在Chrome浏览器的Console工作台,如何安装使用npm工具包?
首先需要给Chrome浏览器安装一个Console Importer
的扩展。
安装完之后,重启浏览器,我们安装一下dayjs,试试效果。
注意安装的npm包仅是在当前tab页,当次生效。
4. 网页的性能如何可视化 ?
第一步 安装stats.js工具包
pnpm add stats.js
第二步 启动浏览器的时候,添加--enable-precise-memory-info
参数
第三步:将fps/ms/mb仪盘添加到页面中。
var stats = new Stats();
// ms是需要多长时间可能渲染一帧
stats.showPanel( 1 ); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild( stats.dom );
function animate() {
stats.begin();
// monitored code goes here
stats.end();
requestAnimationFrame( animate );
}
requestAnimationFrame( animate );
然后就能看到如下效果:
3. F12调试控制台被禁用怎么办?
有时候,想看看别人做的页面酷炫效果。使用了什么样式,可是有时发现,浏览器调试控制台打不开。以下3种打开方式, 统统失效。
- ctrl+shifit+I
- F12
- 鼠标右键。
这个时候咋办呢,正确的打开浏览器控制台的方式是从浏览器设置栏打开开发者工具。 点击浏览器右上角的...
==>更多工具
==>开发者工具
, 就可打开调试控制台。
2. 如何避免tag太长引起的内容溢出?
业务要求,每行最多展示两个tag, tag不能换行展示。如下图所示,出现两个tag时,第二个tag发生溢出,虽然可以加宽tag标签外层容器的宽度,缓解这种问题,可是如果tag中的文字过长的话,还是无法彻底解决这个问题。所以除了要加宽tag外层容器的宽度外,还要限定tag文字的长度,过长的话显示省略号。
/* 省略号的实现 */
.tag {
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
1. useRequest 如何约束响应数据的ts类型?
查看了一下import { useRequest } from 'vue-request';
的类型定义,如下所示:
declare function useRequest<R, P extends unknown[] = any>(service: IService<R, P>): RequestResult<R, P>;
从中可以看出,useRequest有两个泛型,一个用来约束响应数据,一个用来约束请求数据。所以约束响应数据的类型定义的写法就很easy了。
interface ResponseData {
ret: number;
msg: string;
retdata: {
id: number;
name: string;
};
}
const {
data: dataOverviewData,
run: fetchDataOverview,
loading: loadingDataOverview,
error: dataOverviewError,
} = useRequest<ResponseData>(managerSummaryApi.getDataOverview, {
manual: true,
formatResult: (res) => {
return res.retdata || {};
},
});