在使用本地图标时
当 ssr:false 时,UIcon 会提示没有找到图标。因为图标默认是从服务端渲染弄出来的。
需要设置 provider 为 none 或者 iconify
建议设置为 iconify ,不然nuxt ui的图标会显示不出来
相关 issue https://github.com/nuxt/icon/issues/178
// nuxt.config.ts
icon: {
provider: "none",
customCollections: [
{
prefix: "ai",
dir: "./app/assets/icons"
}
]
},
vite.config.js 中有一个 base 说用来指定打包路径的,如果部署上服务器出现页面 404,百分之九十是 base 错了
直接看不同的 base 打包出来的结果:




public 下的文件不会参与打包,不会生成文件 hash,直接会放到 dist。
可以在 public 中存放一些静态文件,如 JSON 等。
解决办法:删除 build 下的拆分打包,因为把包拆的太多了,vite 引入包的顺序出问题了,导致样式被覆盖
vite.config.ts
export default defineConfig({
// 生产环境打包配置
build: {
chunkSizeWarningLimit: 1000,
rollupOptions: {
// 将打包出来的文件,拆分成多个小文件
output: {
manualChunks(id) {
if (id.includes("node_modules")) {
return id
.toString()
.split("node_modules/")[1]
.split("/")[0]
.toString();
}
}
}
}
}
});
FormData 指的是表单数据。
const formData = new FormData();
formData.append("scene", "sqlite");
formData.append("file", chunk);
formData.append("index", `${index}`);
formData.append("total", `${total}`);
formData.append("name", name);
formData.append("ext", "db");
formData.forEach((value, key) => {
console.log(key, value);
});
使用 js-cookie 存储数据时,其他操作无误的情况下,却没有存进去,大概率是由于 cookie 的大小限制。
给 window 新增 tinyMce 属性 ts 报错:类型“Window & typeof globalThis”上不存在属性 ‘tinyMce’
声明 Window ,在根目录下新建一个 xxx.d.ts 文件(ts 会自动读取全局的 .d.ts 文件)
declare interface Window {
tinyMce: any;
}
元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型 “Object“。 在类型 “Object“ 上找不到具有类型为 “string“ 的参数的索引签名
解决:key 值的类型不是 string,在 javascript 中是默认给你转好的,而在 Typescript 中则不是,因此要么转,要么声明,要么忽略…
"suppressImplicitAnyIndexErrors": true
interface Myobject {
[key: string]: boolean; // 字段扩展声明
}
使用 vant 和 element-plus 的 button 组件时,tailwind 的 button 样式会覆盖掉 vant 和 element-plus 的 button 样式 解决办法:
// vant
import "vant/es/button/style";
// element-plus
import "element-plus/es/components/button/style/css";
// 删除以下打包拆分
build: {
rollupOptions: {
// 将打包出来的文件,拆分成多个小文件
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString()
}
}
}
}
}
div {
-webkit-user-select: none; /*谷歌 /Chrome*/
-moz-user-select: none; /*火狐/Firefox*/
-ms-user-select: none; /*IE 10+*/
user-select: none;
}
text-align 的属性值常用的有:right,left,center(行内内容居中
justify(向两侧对齐,最后一行无效),justify-all(与 justify 一致,强制最后一行两端对齐)等
引入本地图片可能找不到资源,解决方法:
new URL,写相对路径。<template>
<van-image src="url" class="w-full" />
</template>
<script setup lang="ts">
const url = new URL("./assets/image.png", import.meta.url).href;
</script>
require<template>
<van-image :src="require('./image.png')" />
</template>
image 提供的加载中提示,宽高是父容器的 100% ,给父容器设置固定宽高
image 的懒加载在 swiper 中存在问题,建议使用 swiper 自带的 懒加载,注意看文档最开始的文字。
在 <script setup> 中可以直接使用 Vant 组件,不需要进行组件注册。
官方文档的示例中加了 van ,如<van-count-down :time="time" />, 在 setup 中不需要。
有些特殊的组件必须要 van,如 dialog。
具体情况见每个组件的组件调用(setup)部分。
<template>
<count-down time="60000" />
<van-dialog v-model:show="show" title="标题" show-cancel-button>
<img src="https://fastly.jsdelivr.net/npm/@vant/assets/apple-3.jpeg" />
<van-dialog>
</template>
<script lang="ts" setup>
import { CountDown,Dialog } from 'vant';
const VanDialog = Dialog.Component;
const show = ref(true);
</script>
大概率是 el-from 还没挂载,from 上的 data 就赋值了。因为 resetField 是将其值重置为初始值,初始值指的是创建 form 时 data 的值。
解决办法是在 el-from 渲染之后再去赋值,可以使用 nexttick,这种 bug 尤其出现在 el-from 写在 dialog 里面的情况。因为 dialog 挂在页面上时,为了性能,默认是不加载 dialog 里面的内容,只有打开 dialog 之后才加载
使用 element plus 时,出现奇怪的问题。可能是数据定义的问题,导致 eleemnt plus 赋值的时候出现了问题 导致失去响应式,尝试切换 ref reactive。
覆盖 element 样式时 直接覆盖对应的样式变量,如想让 el-button 的颜色变化。
.el-button--success.is-disabled {
--el-button-disabled-bg-color: #fff;
--el-button-disabled-border-color: #ccc;
}
element Plus 的树形控件支持自定义渲染字段,可以根据层级渲染,可以根据节点数据渲染。
<template>
<el-tree
:data="departmentTree"
show-checkbox
ref="treeRef"
@check-change="handleCheckChange"
node-key="sid"
default-expand-all
:expand-on-click-node="false"
:props="{ class: customNodeClass, label: customLabel }"
/>
</template>
<script lang="ts" setup>
import type Node from "element-plus/es/components/tree/src/model/node";
// 根据数据:如果当前节点的数据有staffId 表示当前节点应该渲染员工名字,否则渲染部门名字
const customLabel = (data: any) => {
if (data.staffId) {
return data.staffName;
}
return data.name;
};
// 根据层级:如果当前节点属于第一级,...
const customLabel = (data: any, node: Node) => {
if (node.level === 1) {
return "xxx";
}
};
</script>
根据节点数据渲染结果如下(黑色是部门,绿色是员工):

<template>
<!-- value用reactive定义好像有问题? -->
<el-select v-model="value" value-key="id">
<el-option
v-for="item in options"
:key="item.id"
:label="item.label"
:value="item"
/>
</el-select>
</template>
el-form-item 上要写 prop,对应得是 rules 对象内的规则
callback() 表示校验通过,否则校验不会出结果
@click="toggleDark 没有加 (),不加括号时该方法的第一个参数是 event而不是 isDark<template>
<!-- toggleDark() -->
<button @click="toggleDark">
{{ isDark ? "Dark" : "Light" }}
</button>
</template>
<script setup lang="ts">
import { useDark, useToggle } from "@vueuse/core";
const isDark = useDark();
const toggleDark = useToggle(isDark);
</script>
在使用 TS 时,将响应的 res 赋值给变量时报错:
原因是 AxiosResponse 上并没有自己规定返回的一些字段,所以 ts 会报错,所以我们要定义一下类型
详见 axios ts 封装
在 src 目录下创建一个 compiler-vue.d.ts 文件
// compiler-vue.d.ts
import { AxiosRequestConfig } from "axios";
declare module "axios" {
interface AxiosInstance {
(config: AxiosRequestConfig): Promise<any>;
}
}
next() : 放行next('/login') : 中断当前路由去 login在 addRoutes()之后第一次访问被添加的路由会白屏,这是因为刚刚 addRoutes()就立刻访问被添加的路由,然而此时 addRoutes()没有执行结束,因而找不到刚刚被添加的路由导致白屏。因此需要从新访问一次路由才行。
解决方法:next({...to,replace:true})
next({...to,replace:true}) :...to 如果 addRoutes 并未完成,路由守卫会重复执行去,直到 addRoutes 完成,找到对应的路由replace:true 在 to 执行的时候不允许用户点击回退,防止产生异常官方 issue 的回答是拦不住,用户多次点击回退不能把他困在当前页面
routes: [
{
path: "/",
redirect: "/login"
},
{
path: "/login",
name: "login",
component: () => import("@/views/login/login.vue")
},
// url为 /map 会显示PageLayout及子路由map
// 虽然输入 / 重定向到 login ,但是输入 /map 会进入map
{
path: "/",
component: PageLayout,
redirect: "/map",
children: [
{
path: "map",
component: () => import("@/views/map/index.vue")
}
]
}
情景:
'/login' 的情况login 的方法

问题:
/login 页面,只要一进入就调用 login 方法解决:产生问题的原因可能是由于编译之后,方法名与 router 的 path 名称一致,改掉方法名


const getUserList = async () => {
const res: any = await userList({});
state.userList = res;
};
将 setTimeout 的延迟时间设置为 0 ,是为了将函数放在异步队列,等同步任务完成才执行
setTimeout(() => {}, 0);
const array = [1, 2, 3, 4];
array.forEach((ele) => {
ele = ele * 3;
});
console.log(array); // [1,2,3,4]
const objArr = [
{
name: "wxw",
age: 22
},
{
name: "wxw2",
age: 33
}
];
objArr.forEach((ele) => {
if (ele.name === "wxw2") {
ele.age = 88;
}
});
console.log(objArr); // [{name: "wxw", age: 22},{name: "wxw2", age: 88}]
const changeItemArr = [
{
name: "wxw",
age: 22
},
{
name: "wxw2",
age: 33
}
];
changeItemArr.forEach((ele) => {
if (ele.name === "wxw2") {
ele = {
name: "change",
age: 77
};
}
});
console.log(changeItemArr); // [{name: "wxw", age: 22},{name: "wxw2", age: 33}]
ele,只是forEach给在另一个地方复制创建新元素,是和原数组这个元素没有半毛钱联系的!所以,我们使命给循环拿到的 ele 赋值都是无用功!forEach 的基本原理也是 for 循环,使用arr[index]的形式赋值改变,无论什么就都可以改变了。// 对象的键可以是数字、字符串、变量、symbol,但是都会被转化为字符串
const xx = Symbol("xx");
const name = {
1: "小李",
2: "小虞",
3: "张三",
A: "aa",
[xx]: "王五"
};
console.log(name[1]); // 小李
console.log(name["3"]); // 张三
console.log(name["A"]); // aa
console.log(name.A); // aa
console.log(name[xx]); // 王五
使用:deep()时,他的父级必须是当前 vue 文件定义的某个选择器,如下列的.my-dialog
.my-dialog {
:deep(.el-dialog__header) {
border-bottom: 1px solid #d8d8d8;
}
}
遇到数组、对象(引用类型)赋值时一定要考虑是否需要深拷贝
问题:红圈处开始时直接赋值,在后面 arrTemp 使用了 splice 方法,由于此时赋值的时内存地址,导致 taskData.value 也发生了改变

问题:使用 try catch 捕获异常,抛出错误时 报错 (local var) error: unknown,或者其他错误。
使用 async / await 时,可以用 try...catch 处理异步函数抛出的错误;也可以将错误交给调用方处理。
try {
// ...
} catch (error) {
throw new Error(error);
}
解决:在 ts.config.json 中配置:
"compilerOptions": {
// ...
"useUnknownInCatchVariables": false,
// ...
}
// iframe
window.parent.postMessage(data, "*");
//父级
window.addEventListener(
"message",
function (e) {
console.log(e);
},
false
);
(top as Window).window.location.href = "url";
场景: 使用 element 的输入框,当 Google 自动填充密码时,会出现背景色
原因:由于浏览器的预设样式,导致输入框的背景色变化


/* 去除浏览器input自动填充的默认样式 */
input:-internal-autofill-selected {
/* 这里#fff是底色 */
-webkit-box-shadow: 0 0 0px 1000px #fff inset;
-webkit-text-fill-color: #333;
}
