1. JS语法
1.1. JS基础
1.1.1. 报错: xxx is not defined
错误描述: 什么xxx变量未定义
-
有问题代码:
var arr = [1, 5, 3, 2, 10]; Arr.push(100);
-
分析
Uncaught ReferenceError: Arr is not defined 未捕获到 引用错误 Arr变量 是 没有 定义的 Arr 没有定义过 参考代码和报错, 发现我们实际上想使用的变量名叫arr, 所以你不小心写错了
-
解决, 改成正确的变量名
var arr = [1, 5, 3, 2, 10]; arr.push(100);
-
总结: 再发现xxx is not defined, 就是你变量没有访问到, 检查下你的代码
1.1.2. 问题: Cannot read property ‘forEach’ of undefined
错误描述: undefined不能读取属性forEach
- 有问题代码:
// 1.2 (基础) - 把数组数据铺设到页面上
var arr = res.date;
arr.forEach(function(obj){
let {
id, publisher, author, bookname} = obj;
var theTr = `<tr> <td>${
id}</td> <td>${
bookname}</td> <td>${
author}</td> <td>${
publisher}</td> <td> <a href="javascript:;" class="del">删除</a> </td> </tr>`;
$("#tb").prepend(theTr);
})
- 错误分析
在第80行有问题, 查看报错的代码
是arr读取的forEach方法, 报错说arr是个undefined(说明arr变量里的值是undefined)
顺藤摸瓜:
那么观察arr的值是在上面res.date给的
那打印res观察 (很关键, 一定要学会打印)
发现res的数据再data属性上, 而非date. 发现是拼写错误咯
- 解决:
var arr = res.data;
- 总结: 当发现问题后, 要学会顺腾摸瓜, 变量只是个代号, 而变量里装的什么只有打印出来才知道
1.1.3. 问题: xxx.foreach is not a function
错误描述: xxx调用了foreach, 但不是一个方法
- 有问题代码
var arr = [1, 2, 3];
arr.foreach(function (val) {
console.log(val);
})
- 分析
Uncaught TypeError: arr.foreach is not a function
未捕获到 引用错误 arr.foreach 不是一个方法
说白了, 就是arr对象身上没有foreach方法, 为啥呢?
你打印arr变量, 展开前面小箭头, 你好好看看foreach方法怎么写的 是不是叫forEach
注意了JS这门语言是区分大小写的 就是foreach和forEach不是一个人
- 解决
arr.forEach
- 总结: 在遇到 xxx.yyy 不是一个方法, 那就证明这个对象没有这个方法, 打印这个对象先看看 好好合计合计
1.1.4. 报错: Failed to execute ‘append’ on ‘FormData’: 2 arguments required, but only 1 present.
错误描述: 未能对“FormData”执行“append”:需要2个参数,但仅存在1个参数。
- 有问题代码
var fileObj = $("#file1")[0].files[0];
var fd = new FormData();
fd.append(fileObj); // 这行报错了, 正确写法 fd.append("参数名", 值")
- 分析
Failed to execute 'append' on 'FormData': 2 arguments required, but only 1 present.
执行失败 在FormData上使用append: 必须2个参数, 但是目前仅仅1个
发现代码里append相关有-确实fileObj应该是值, 少个参数名
- 解决
fd.append("img", fileObj); // 传参给后台, 参数名要跟后台对上
- 总结: 看不懂翻译, 可以百度翻译.
1.2. JS高级
1.2.1. 报错:Must call super constructor …
错误描述: 必须调用父类的constructor构造函数
- 有问题代码
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
constructor(x, y) {
this.x = x;
super();
}
}
new Son();
- 分析:使用ES6对其它类进行继承时,语法报错
Must call super constructor in derived class before accessing 'this' or returning from derived constructor
在访问“ this”或从派生构造函数返回之前,必须在派生类中调用super 构造函数
所以: 在继承其它构造函数之前,需要使用super关键字对父级的形参进行确认;再使用this
- 解决:
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
constructor(x, y) {
super(); // 要在使用this之前使用super()
this.x = x;
}
}
new Son();
- 总结:无论父亲上面有没有属性,只要在子类中构造器函数内部操作this,就需要super 把父级相关的 属性进行确认;
1.2.2. 逻辑: 在constructor里返回的不是实例对象
描述: 发现new完返回来的对象上没有模板里的属性
- 有问题代码
class Person {
constructor() {
this.name = "";
this.age = 0;
return {
ok: 100 }
}
run(){
}
}
var per = new Person();
console.log(per); // {ok: 100}
// 原因 - 因为constructor默认返回this的值(new出来的实例对象), 但是如果你显示的有return就会覆盖, per就是return后的值了
-
分析:
new会创建一个空白对象, 在constructor里绑定属性和方法后, 默认返回到new的地方, 打印发现per对象里没有name和age
那就证明return有问题
综合代码发现return竟然不是默认的, 而是手写了一个新的对象
-
解决: 把return {ok: 100} 去掉, 默认返回实例对象
class Person { constructor() { this.name = ""; this.age = 0; } run(){ } } var per = new Person(); console.log(per); // {name: "", age: 0}
-
总结: 不要在constructor里写return 哦
1.3. jQ
1.3.1. 报错: Cannot read property 0 of undefined
错误描述: undefined不能读取属性0
- 有问题代码:
// 1. 按钮 - 点击事件
$("#sendBtn").on("click", function(){
// 2. 要值
var nameInp = $("#nameInp").val;
let aInp = $("#aInp").val();
let pInp = $("#pInp").val();
// 3. ajax -> 发给后台
$.post("http://123.57.109.30:3006/api/addbook", {
bookname: nameInp,
author: aInp,
publisher: pInp,
appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a"
}, function(res){
console.log(res);
})
})
- 分析
1.根据报错提示, jQ的8436行代码有问题, 但是jQ又不是你的代码所以不用看
2.发现下面还有一些代码片段提示, 倒数第三个是自己写的html文件, 第23行代码报错了
3.回头看23行代码, 是$.post() 这行发送网络请求的代码 - 但是怎么也看不出来读取0, 谁读0了, 咋办?
4.和对url和appkey都是复制的没问题, 那就是变量有问题了, 打印这几个变量观察值到底是什么?
console.log(nameInp, aInp, pInp)
-
发现第一个参数是个函数, 不是具体的值
-
那nameInp变量的值是在上面用=赋值运算符给的
-
所以var nameInp = $(“#nameInp”).val; 右侧有问题, 发现val是JQ的方法得加()啊
-
解决:
// 1. 按钮 - 点击事件
$("#sendBtn").on("click", function(){
// 2. 要值
var nameInp = $("#nameInp").val();
let aInp = $("#aInp").val();
let pInp = $("#pInp").val();
// 3. ajax -> 发给后台
$.post("http://123.57.109.30:3006/api/addbook", {
bookname: nameInp,
author: aInp,
publisher: pInp,
appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a"
}, function(res){
console.log(res);
})
})
- 总结: jQ一般都是方法, 记得加()
1.3.2. 问题: 点击按钮 - 无反应
问题描述: 点了按钮什么反应也没有
- 有问题代码
$("#goto-register2").on("click", () => {
$("#register").stop().show();
})
- 分析:
1. 那证明里面这行代码可能没执行, 可以在这打印下$("#register")
(1): 如果打印执行了, 证明外面$("#goto-register2").on("click")肯定没问题 - 再分析内部
(2): 如果没打印, 证明外面$("#goto-register2")可能没获取到, 打印看看值对不对, 顺腾摸瓜
2. 这道题发现什么都没打印, 那肯定是(2)方式, 绑定有误所以打印$("#goto-register2")发现有问题
后来去对了下#后面的id值, 发现写错了没有2
- 解决
$("#goto-register").on("click", () => {
console.log($("#register"));
$("#register").stop().show();
})
- 总结: 学会顺腾摸瓜找到问题
2. 网络编程
2.1. 报错: net::ERR_INTERNET_DISCONNECTED
错误描述: 因特网已经断开连接
- 互联网已经断开
- 解决: 请确认自己的网络是否正常 (可以开一个网页看看能不能上淘宝)
2.2. 报错: 只要见到timeout
- 网络超时, 用接口调试工具排查是否是后台接口的问题, 具体看后台有无响应
- 无响应, 找后台人去重启服务器
- 有响应, 根据错误提示解决问题
2.3. 报错: 404 (Not Found)
错误描述: 没有找到你想访问的
- 有问题代码:
axios({
method: 'get',
url: 'http://123.57.109.30:3006/api/getbooks2',
params: {
id: 1,
bookname: '西游记'
}
}).then(function (res) {
console.log(res)
})
-
分析: axios.js 不是我的代码啊, 左边有个箭头展开, 下面有个小箭头指向的是你自己的代码引发的错误, 所以发现是axios请求有问题
-
解决
根据业务, 把url改成正确的后台地址即可
-
总结:
只要再看到404, 就是你要请求的url地址不对, 具体是哪一个, 根据报错的提示行数即可找到
2.4. 报错: Access to XMLHttpRequest
错误描述: Ajax链接有问题
- 有问题代码:
axios({
method: 'get',
url: 'http://localhost:2001/api/getbooks',
params: {
id: 1,
bookname: '西游记'
}
}).then(function (res) {
console.log(res)
})
- 分析:
Access to XMLHttpRequest
Ajax跨域了 从 http://127.0.0.1:5501 要请求 http://localhost:2001/api/getbooks
概念: 协议/ip域名/端口 ajax所在页面的, 和ajax要请求的 有一个对不上的, 就发生了跨域
浏览器默认虽然支持cors跨域资源访问, 但是后台如果不允许的话, 浏览器会拦截这个ajax请求
所以报错的后半句是: 没有再响应头里找到Access-Control-Allow-Origin的头(后台没有允许)
-
解决
要么去让后台开启cors跨域资源共享, 或者是前端使用服务器代理请求
3. vscode相关插件
3.1. 问题: vscode插件 - post请求不发送
问题描述, 点击Rest Client插件编写的.http文件上的Send Request本想发送这个http请求, 但是右下角报错
- 分析
Header name must be a valid HTTP
请求头 名字 必须是一个合法的
注意, http请求报文结构中,
第一行是请求方式, 请求URL地址
第二行往下每行都是一对请求头的名字:值 (千万不能带分号后面, 这也不是js代码, 这是http请求报文)
空行 (必须的, 规定, 因为下面是请求体的参数不再是请求头的一部分了)
请求体的内容参数和值
- 解决: 在Content-Type下面加一行空行就好了
- 总结: 注意Content-Type下面一行必须有空行(用回车隔出来一个哦) - 这是这个插件的规定
4. git
4.1. 问题: not a git repository
错误描述: 没有一个git仓库(存储)
- 分析
fatal: not a git repository (or any of the parent directories): .git
致命错误: 没有git仓库(或任何父目录中) 有.git文件夹的
这个.git文件夹 (要么git clone拉取远程仓库产生), 要么git本地仓库(git init)初始化的
你现在少这个.git隐藏的文件夹啊
补充知识: .git里管理着git相关的一切
- 解决: 这里是要把项目传到服务器上, 所以需要本地自己初始化一个 运行命令git init
- 总结: 根据错误提示, 想想怎么解决/百度解决问题的方法
4.2. 问题: failed to push some refs to ‘xxxxx’
错误描述: xxxx地址看你自己的, 跟我的可能不一样, 但是前面错误提示是一样的
- 分析
error: src refspec master does not match any
错误: master分支里没有任何匹配的东西
error: failed to push some refs to 'gitee.com:itcz_jiaoyu/good122.git'
错误: 推送文件到'地址'的时候失败了
综上所述: 是你本地没有暂存和提交, 没什么可以推送的啊
- 解决: 先去git add 和 git commit -m ‘提示’
- 总结: 根据英文就知道什么意思啦
4.3. 问题: Access deined You do not have premission push to this repository
错误描述: 您没有预授权,访问此存储库
- 分析
1. 远程仓库如果是你的, 证明你账号/密码输入错误(如果用的是http的git地址), 请输入正确的
远程仓库是你的, 用ssh地址进行推送, 请确认你的ssh秘钥是正确配置的(包括文件名是否在正确的默认位置)
2. 远程仓库别人的, 请让他在这个项目里把你加入到他的项目成员里, 你才有权限推送哦
- 解决: 权限不对, 请按照分析的去核对
自己的就配置ssh / 确认账号密码正确(登录你git远程仓库网站的账号和密码)
如果别人的, 请让他拉你进它的项目组里(如果是gitee.com, 你需要在右上角小铃铛的私信里确认邀请链接)
4.4. 问题: Repository Not Found
错误描述: 仓库没找到
- 分析
git 克隆说没有找到这个远程仓库
那肯定就是你的远程仓库地址不对
重新找一下复制一下
- 解决: 地址不对, 发现yiaoyu是jiaoyu地址用错了
5. 大事件项目
5.1. 问题: 表单提交 - 无反应
问题描述: 点击按钮提交表单, 本想着是Ajax提交, 但是发现==网页刷新闪了一下==
- 问题代码:
$("#register .layui-form").on("submit", ev => {
ev.preventDefalt();
var data = {
username: $("#register input[name=username]").val(),
password: md5($("#register input[name=password]").val())
}
registerAPI(data, () => {
// 显示登录页面 - 让用户登录
$("#register").stop().hide();
});
})
- 分析: 证明表单自己提交了, 你并未阻止了form默认的submit事件
排查: 所以找到绑定submit事件那里, 观察你的阻止默认行为的代码 (特别是单词 是否正确)
发现preventDefalt() 单词拼写错误, 正确应该是preventDefault()
- 解决: 把单词改成正确的即可
- 总结: 多在心中念, 念的时候就知道怎么拼写了, 如果上面单词对了, 请检查on绑定事件是否正确 - 以及前面标签获取是否正确
5.2. 问题: 提示 - 用户名/密码 undefined
- 问题代码
$("#register .layui-form").on("submit", ev => {
ev.preventDefault();
var data = {
username: $("#register .input[name=username]").val(),
password: md5($("#register .input[name=password]").val())
}
registerAPI(data, () => {
// 显示登录页面 - 让用户登录
$("#register").stop().hide();
});
})
- 分析 - 说明你的data里的值有问题, 在data上面打印一下, 然后操作下页面, 复现一下
// 既然说我用户名是undefined, 就打印下获取的用户名标签里的val()值
console.log($("#register .input[name=username]").val());
// 发现值确实是undefined
那肯定这行代码有问题, 逐个选择器分析, 发现是最后发现是input前面多了个. (input是标签名不是class)
5.3. 问题: 验证规则不生效
- 现象: 点击提交按钮 - 发现我故意违反了我定义的正则规则, 但是不给我出提示框
- 分析:
1. 我们使用的是layui.css和layui.js 2个文件里的样式和js功能代码 - 先确保正确引入
2. 这个 form标签内的按钮 身上 必须有layui-submit 属性 - 才会检验 (规定)
3. 如果上面2个都确定完了. 那么确定你表单标签身上有 lay-verify属性 而且值的格式是对的如下(==多个规则之间不能有空格==
4. 例如: <input lay-verify="required|usern">
5. 如果还不行 - 就是你规则里定义出问题了去检查
form.verify({
usern: [ // 用户名
/^[a-z0-9]{
6,10}$/
],
})
// 发现只有规则, 没有提示
- 解决: 把提示文字在数组第二个元素补上(layui规则规定, 第二个值是提示文字)
form.verify({
usern: [ // 用户名
/^[a-z0-9]{
6,10}$/,
"用户名6到10位的数字和小字母组成"
],
})
5.4. 问题: 后台返回400
错误描述: 后台在影响状态码为400, 后台通知我们这次http请求有问题
- 有问题代码:
let data = {
oldPwd: md5($("input[name=oldPwd]").val()),
newPwd: md5($("input[name=newPwd]").val())
}
// 后台不支持json, 所以必须用objToArg方法转成key=value
rePassAPI(data, () => {
// 重置成功
let s = setTimeout(() => {
sessionStorage.removeItem("token");
// 这里要格外注意, window指的是iframe内嵌的网页repwd页面, 而我们想让index.html整个网页跳转到登录页面, 所以window.parent - 返回当前窗口的父窗口对象
window.location.href = "/login.html";
clearTimeout(s)
}, 2000);
})
- 分析
后台提示我oldPwd的字段有问题
1. oldPwd参数名没错, 必须传的oldPwd字段传递了参数名
2. 那就是值有问题, 所以去打印js代码里, 发现值也是32位的字符了啊
3. axios在data请求体里发送的都是application/json的内容格式 - 也就是给后台发的json字符串格式 (而这个项目的后台只能解析key=value&key=value字符串 - 所以这个问题比较隐晦
- 解决
在发送参数对象时, 先把对象转成key=value&key=value字符串哦
5.5. 问题: 上传头像没反应
-
描述: 点击上传头像, 半天也没有反应, 也没有状态码, 而且看response后台没有任何的东西返回
-
原因: 因为前台还在发送字符串给后台, 后台还没接收完. 半天没反应, 证明前端上传的数据过大.
-
问题代码:
const canvas = cropper.getCroppedCanvas({
width: 500,
height: 500
}); // 因为canvas标签太大了. 图片太大, 改成100就好了
avatar有问题导致虽然接口成功, 但是图片获取还是没有
6. SQL相关
6.1. 解决ID不连续问题
可以把teacher换成自己具体的表名即可
ALTER TABLE teacher DROP id; ALTER TABLE teacher ADD id int NOT NULL FIRST; ALTER TABLE teacher MODIFY COLUMN id int NOT NULL AUTO_INCREMENT,ADD PRIMARY KEY(id);
7. Node
7.1. node相关
7.1.1. 问题: 安装弹窗error 2503
错误描述: 提示安装包和安装进程有问题
-
分析
这个安装程序, 这个安装包有问题, 可以百度搜索下2503的解决方案 如果都不行, 就不要用.msi安装程序了, 直接去官网下载硬盘版(二进制的文件)直接手动配置环境变量(可以百度搜索)
-
解决
硬盘版安装 或者 看这个地址操作: https://jingyan.baidu.com/article/cdddd41c97e94853ca00e17e.html
7.2. npm相关
7.2.1. 报错: 无法识别为可运行程序的名称
错误描述: 输入的命令不存在
-
分析
这是要node xxx 用node执行这个js文件吧? 报错说命令怎么是我这个js文件呢? 啊, 原来没写node
-
解决
node 下载的包引入使用.js
-
总结: 执行js文件, 要用node命令哦
7.2.2. 报错: 403 You cannot publish over the previously published versions:1.0.0
错误描述: 你不能发布这个版本
-
分析
403 You cannot publish over the previously published versions:1.0.0 不能在以前发布的版本上发布版本:1.0.0 原因是因为之前已经发布了1.0.0版本了, 你得修改下一个版本号再发布了
-
解决
去package.json文件中, 手动把1.0.0 改成1.0.1 或者自己按照自己规则往上增加, 大修改.中修改.小修改
7.2.3. 报错: 400 “xxx” is invalid for new packages
错误描述: 新包名不合法
-
分析
403 "Raincr" is invalid for new packages "自己的包名" 不是一个新的合法的包名 说你的R大写开头不合法
-
解决
去修改package.json的name属性的值(这是发布用的包名) - 但是建议文件夹名也一致(方便对应)
7.2.4. 报错: 403 Package name triggered spam detection
错误描述: 包名触发的垃圾邮件检测
-
分析
403 Package name triggered spam detection 包名太垃圾了 哈哈哈哈开个玩笑, 就是不能乱写一点规则都没有啊 改为正常的包名 一般英文开头, 单词含义, -中划线链接
-
解决
去package.json里改name的值, 文件夹最好保持一致
7.2.5. 问题: 网页 Too Many Request
错误描述: 太多请求了
-
分析
Too Many Requests 太多的请求了 这个网站短时间有太多的请求, 就会拒绝正常逻辑响应
-
解决
换个网络 / 等1个小时以后再来注册吧
7.2.6. 报错: operation not permitted
错误描述: 不允许操作
-
分析
operation not permitted 不允许操作 说你没有权限
-
解决
请以管理员方式打开终端, 可以百度看看怎么用管理员方式打开, 在搜索框里搜索右键图标, 有管理员方式打开
7.2.7. 报错: 403 tors can unpublish module
错误描述: 不能删除模块包
-
分析
```js 403 Forbidden - DELETE https://registry.npm.taobao.org/xxx -tors can unpublish module
说你没有权限删除, 发现发布的包都在官方的镜像地址上, 但是这里怎么有淘宝字样
所以你没有切换npm的镜像地址
* 解决
```js
npm config set registry https://registry.npmjs.org
然后在执行删除包命令
7.2.8. 报错: 502 Bad Gateway
错误描述: 网关错误
-
分析
502 5开头的一般都是服务器错误, 所以后台问题网络问题
-
解决
切换网络 / ctrl+c停止后, 再重新来一遍
7.2.9. 报错: this is a problem related to network connectivity
错误描述: 这是一个与网络连接有关的问题
-
分析
request to https://registry.npmjs.org/~/v1/login filed reason: getaddrinfo ENOTFOUND registry.npmjs.org 请求时, 找不到这个地址 一般是网络问题
-
解决
切换网络 / ctrl+c停止后, 再重新来一遍
7.2.10. 报错: xxxx不是内部或外部命令
错误描述: 本机没有这个命令
-
分析
nodeomon 不是内部或外部命令 一切的命令都要安装到电脑里的程序员用的软件, 而且要成功配置到计算机的环境变量里, cmd终端里才能执行这个命令程序 nodemon 是替代node命令来实时更新js代码运行的效果的, 很明显单词打错了 // 如果单词没错就是环境没安装对, 重新安装即可
-
解决
nodemon xxxx.js
7.2.11. 报错: 403
错误描述: 邮箱没有验证
-
分析
403 Forbidden 一般都是没有权限 1. 请确认你包的package.json文件名字 和 npmjs.com网站上没有重名的才可以 2. 在npmjs.com注册账号的时候, 会给你填写的邮箱里发一封右键, 必须点击右键里的verify按钮验证链接才算验证激活 (才能用这个账号向npm网站发布包)
-
解决
去npmjs.com登录你的账号 / 邮箱里找找有没有这个邮件 如果都没有重新注册一个邮箱再来注册这个网站 (如果不想发布也可以了解下就行了_ 哈哈)
7.3. express相关
8. webpack
8.1. 报错:An unexpected error occurred
错误描述: 发生意外的错误
- 分析:
看后面说package.json里的JSON格式有问题, 大概在177个字符位置
- 解决:
JSON格式非常严谨, 必须都是英文的标点, 而且只能用双引号, key也得是双引号
JSON格式: 大括号里往里嵌套, 最外层不能是并列的大括号, 所以看看是不是写外面了
可能会隐藏中文的空格, 自己调整输入法重写下
8.2. 报错:Unknown command or entry
错误描述: 不知道命令或入口
- 分析:
不知道命令或入口 --config webpack.config.js
- 解决:
- package.json并列处有无webpack.config.js (拼写啥的对不)
- 可能–config 周围有中文空格, 调整好输入法再重写下
8.3. 报错:Cannot find module xxx
错误描述: 找不到模块
- 分析:
找不到模块, 具体后面看是webpack.config.js这个模块文件
- 解决:
- 看看路径下有无这个文件(应该是package.json并列出, 因为你自定义命令就是并列路径)
- 路径上不要出现webpack名字的文件夹
8.4. 报错:Cannot resolve vue
错误描述: 不能引入vue
- 分析:
找不到模块vue, 这是个第三方的vue包
- 解决:
- 在当前所在工程下, 下载vue包即可
8.5. 报错:Invalid package name
错误描述: 包名称无效
- 分析:
yarn init为了初始化包环境得到package.json
终端会问你, 你的包名叫什么, 直接回车会用当前文件夹名也 就是括号里的
但是我们好像有中文/特殊符号
- 解决:
文件夹是文件夹, 包名是包名 不冲突, 所以在后面不能直接回车, 随便给个合法的名字即可
8.6. 报错:Can`t resolve xxx
错误描述: 不能引入xxx什么了
- 分析:
得能从这个报错信息里, 提取有用的信息, 发现说不能引入jquery了
- 解决:
发现好像忘记下jquery了, 或者重新下载一遍
8.7. 报错:无法将"yarn"识别为 cmdlet
错误描述: 终端不能识别yarn为命令使用
- 分析:
图里用的是powerShell终端, win10新出的, 执行策略帮助你防止执行不信任的脚本
- 解决:
在终端执行: set-ExecutionPolicy RemoteSigned
8.8. 报错:The engine “node” is incompatible
错误描述: node引擎不兼容
- 解决:
去node官网下载一个大于10.17的版本的nodejs, 在当前电脑覆盖式安装即可
8.9. 报错:webpack不是内部或外部命令
错误描述: 执行自定义命令时, 真正打包命令叫webpack
- 分析:
很有可能你当前工程下没有webpack, 去package.json确认下, 如果真没有就下载即可
- 解决:
重新在当前工程下载webpack (如果webpack4以上版本还需要下载webpack-cli)
8.10. 报错:Couldn’t find a package.json file
错误描述: 不能找到package.json文件
- 分析:
不能找到package.json文件, 在01_笔记和ppt目录下确定下是否有package.json文件
是否命令所在文件夹下没有这个package.json文件
因为yarn build自定义命令, 在当前目录下找到package.json文件的script的build命令
- 解决:
确认下终端敲命令时, 当前所在文件夹路径是否正确
8.11. 报错:yarn 不是内部或外部命令
错误描述: yarn不是命令, 无法使用
- 分析:
安装yarn软件, 会自动配置环境变量到电脑里, cmd终端所用的命令都是在我的电脑里的环境变量的
执行的命令其实都对应着电脑里的应用程序
- 解决:
方案1: 重新安装下yarn软件, 而且目录上不能出现yarn文件夹名字/叫yarn的文件名 – 否则就覆盖了环境变量使用不了真正的yarn应用程序了
方案2: 可以用npm install -g yarn (安装个全局yarn命令) - 如果还不行就把yarn和node都卸载后重新安装到c盘下
8.12. 报错: 系统找不到指令路径
错误描述: 执行yarn build打包找不到系统路径
- 分析:
yarn打包时, 要使用webpack命令, 内部需要node环境, 所以猜测应该是node有问题
- 解决:
node安装路径上不要出现中文, 建议yarn和node都安装到c盘的无中文路径下面
8.13. 报错: in ./public/index.html
错误描述: 模块解析失败, 不能处理html文件
- 分析:
你可能把html文件引入到js里了, webpack分析到了你的html文件, 但是你没有加载器/插件能打包html文件
- 解决:
其实我们是用插件,让html作为模板自动生成一个html文件, 而不是要在js里引入啊
8.14. 报错: Command “xxx” not found
错误描述: 命令没有找到
- 分析:
yarn serve命令来自于package.json中
- 解决:
发现package.json中名字写的跟要执行的不一样
9. Vue基础
9.1. JS语法类错误
9.1.1. 报错:xx is not defined
错误描述: 变量未定义
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app"></div>
<script> const vm = new Vue({
el: '#app', methods: {
add() {
// 使用了未申明的变量a a++ } }, mounted() {
this.add() } }) </script>
- 解决:
!> 这一类错误都是相同的排错方式 按照下面的步骤即可
- 根据1错误块得到错误发生在哪个组件以及具体发生在组件的哪个阶段
- 根据2错误块找到错误发生的调用栈位置 直接点击定位错误
- 根据错误信息提示在错误定位的地方修改即可
9.2. Vue框架规则类错误
9.2.1. 报错: Vue is not defined
错误提示: Vue没定义啊
- 有问题代码:
<body>
<div id="app"></div>
</body>
<script>
new Vue({
el:'#app'
})
</script>
- 分析
Vue全局变量哪里来的啊? 是不是引入vue.js才暴露在全局的啊, 就跟$变量也是引入jQuery.js才有的
所以证明你没有引入Vue.js
- 解决:
去引入vue.js源码到你的页面中即可
9.2.2. 问题: 不解析内容
错误描述: 运行后, 出现了双大括号, 不解析了
- 分析:
1. 先看看浏览器是否有报错 有报错提示根据提示解决问题
2. 可能把标签内容都写在了<div id="app"> </div> 外面去了
- 解决
把内容都写到div#app里面来, 因为vue指定了以#app为根标签, 按照你写的模板结构, vue会创建一套虚拟DOM解析真正的内容和标签, 然后替换到这个标签上来, 写外面你让vue咋解析?
9.2.3. 报错: Do not mount Vue to
错误描述: 不能使用html或body作为vue的模板根标签
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--错误!挂载到根元素-->
<body id="app"></body>
<script> new Vue({
el:'#app' }) </script>
- 分析
Vue框架不允许把html或者body作为挂载的根元素
- 解决:
把挂载根元素换成普通元素即可
<div id="app"></div>
9.2.4. 报错: Property or method ‘xxx’ is not defined on the instance
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<!--模板使用了name但是在实例选项中没有申明-->
{
{name}}
</div>
<script> const vm = new Vue({
el: '#app', computed:{
} data: {
}, methods: {
} }) </script>
- 分析
在vue组件实例的模板中使用到的属性值或者方法必须要在实例的配置项中定义好才可以使用
- 解决
根据错误提示的内容,去组件实例选项中查看是否未定义该属性,查找范围包括data,computed,methods,props
在data: {} 里面定义name变量
9.2.5. 报错: method ‘name’ has already been defined as a
9.2.6. 报错: the data property ‘name’ is already defined
错误描述: xxx already defined 就是已经定义过了的提示, 肯定重复定义了变量名哦
- 有问题代码:
<script>
const vm = new Vue({
el: '#app',
data: {
name: 'cp'
},
props: {
name: {
type: String
}
},
computed: {
name() {
}
},
methods: {
name() {
console.log(`cp`)
}
}
})
</script>
- 分析
Vue框架不允许data/props/computed/methods中任意两项出现重复的属性名,在初始化配置时会进行名称检测
- 解决
根据错误提示找到哪里发生了重复,找到重复属性名更改为不重复即可
9.2.7. 报错: Duplicate keys detected
错误描述: 发现重复的key
- 有问题代码
<script src="./vue.js"></script>
<div id="app">
<ul>
<li v-for="item in list" :key="item.id">
{
{item.name}}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
// 这里有重复id
list: [
{ id: 1, name: 'react' },
{ id: 2, name: 'vue' },
{ id: 1, name: 'angular' }
]
}
})
</script>
- 分析
为保证列表的高效更新 vue框架在我们使用v-for指令的时候要求为每一项绑定一个唯一的key属性,注意key必须是唯一不可重复的 代码中的存在重复的id 所以会报错
- 解决
每次给key绑定值时确保是唯一的值
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<ul>
<li v-for="item in list" :key="item.id">
{
{item.name}}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
// 这里有重复id
list: [
{ id: 1, name: 'react' },
{ id: 2, name: 'vue' },
{ id: 3, name: 'angular' }
]
}
})
</script>
9.2.8. 报错: the data option should be a function
错误描述: 说你的data选项必须是一个方法
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app"></div>
<script>
Vue.component('add-component', {
// 错误!!
data: {
name: 'cp'
}
})
const vm = new Vue({
el: '#app'
})
</script>
- 分析
上面申明的组件add-component上面的data属性直接配置了一个对象,这在vue的组件系统中是不允许的,因为组件的核心使用场景是复用,data如果直接赋值一个对象,那么多个重复的组件会共用一套数据,一个组件进行数据更改所有组件都会受到影响,违背了组件的功能独立性
- 解决:
任何一个组件的data都应该申明为一个函数,函数中返回一个对象,这个全新的对象作为组件的依赖数据
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app"></div>
<script>
Vue.component('add-component', {
// 正确
data(){
return {
name:'cp'
}
}
})
const vm = new Vue({
el: '#app'
})
</script>
9.2.9. 报错: Component template should contain exactly one root element
错误描述: 组件模板应该只包含一个根元素标签
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<add-component></add-component>
</div>
<script> Vue.component('add-component', {
template: ` <div></div> <p></p> ` }) new Vue({
el: '#app' }) </script>
-
分析:
vue组件的的template选项中只能拥有一个根元素 原因是因为一是为了做组件样式隔离,二是为了渲染时存放当前的组件对应的vnode,所以只能有一个根元素 这在vue3.0中会得到改善
-
解决:
只写一个根元素
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<add-component></add-component>
</div>
<script> Vue.component('add-component', {
template: ` <div></div> ` }) new Vue({
el: '#app' }) </script>
9.2.10. 报错: do not use build-in or reserved HTML elements as
错误描述: 不能将内置或保留的html元素用作组件
- 有问题代码
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app"></div>
<script> // 错误!! Vue.component('header', {
data(){
return {
} } }) const vm = new Vue({
el: '#app' }) </script>
- 分析
Vue框架对于组件的命名规则有一定限制,不允许和HTML内置标签发生名称重复,上面组件的名称header和HTML内置标签中的header标签重复,关于vue中的组件命名希望大家严格遵守
- 解决
将组件名称替换成规范的命名规则即可
9.2.11. 报错: Unknown custom element
错误描述: 不知道自定义的标签, 你注册了吗?
- 有问题代码
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<father-component></father-component>
</div>
<script> Vue.component('father-component', {
template:` <div> 我是父组件 <son-component></son-component> </div> ` }) const vm = new Vue({
el: '#app', components:{
'son-component':{
template:` <div>我是子组件</div> ` } } }) </script>
-
分析
组件 并没有在父组件 中注册,所以并不能正常使用,大家一定要记着,全局组件在每一个vue实例的模板中都能正常使用,而局部注册的组件只有在父组件的components选项中注册时候才能使用
-
解决
在父组件的components中注册一下组件即可
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<father-component></father-component>
</div>
<script>
Vue.component('father-component', {
template:`
<div>
我是父组件
<son-component></son-component>
</div>
`,
// 注册局部组件!!!
components:{
'son-component':{
template:`
<div>我是子组件</div>
`
}
}
})
const vm = new Vue({
el: '#app'
})
</script>
- 总结: 谁用谁注册哦~全局的不用注册, 直接用
9.2.12. 报错: Failed to mount component: template or render function not defined
错误描述: 无法装载组件:未定义模板或呈现函数
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<add-component></add-component>
</div>
<script>
Vue.component('add-component', {
data() {
return {
}
}
})
new Vue({
el: '#app'
})
</script>
-
分析
尝试渲染组件,但是组件中既没有tempalte选项又没有render函数,因为vue组件的渲染最终是要执行render函数的,如果render函数存在就以render函数为准,如果render函数不存在,则会把template选项编译成为render函数再执行 所以这俩个需要申明其中的一个
-
解决
申明template选项或者申明render函数
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('add-component', {
template:`
<div>this is add-component</div>
`,
data() {
return {}
}
})
new Vue({
el: '#app'
})
</script>
9.2.13. 报错: Avoid mutating a prop directly since the value will be overwritten
错误描述: 避免直接改变属性,因为值将被覆盖
- 有问题代码
<script src="./vue.js"></script>
<div id="app">
<add-component title="this is title"></add-component>
</div>
<script>
Vue.component('add-component', {
props: {
title: {
type: String
}
},
template: ` <div> {
{title}} <button @click="change">修改数据</button> </div> `,
methods:{
change(){
// 尝试直接修改父组件传过来的数据
this.title = 'new title'
}
}
})
new Vue({
el: '#app'
})
</script>
-
分析:
上面的代码中,title数据来源于父组件,在子组件按钮点击时尝试直接修改title数据,基于vue单向数据流的要求,我们不能反向子组件直接修改父组件的数据 所以会报错
-
解决:
可以通过事件传递的方式,通过调用父组件的一个方法进行修改title数据,这样的话就符合父组件修改自己数据的要求,或者我们可以把props中的title赋值给子组件data中的一个新的值,让它成为子组件自己的数据,这样的话就可以子组件自己修改了
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<add-component title="this is title"></add-component>
</div>
<script>
Vue.component('add-component', {
props: {
title: {
type: String
}
},
data() {
return {
childTitle: this.title
}
},
template: ` <div> {
{childTitle}} <button @click="change">修改数据</button> </div> `,
methods: {
change() {
this.childTitle = 'new title'
}
}
})
new Vue({
el: '#app'
})
</script>
9.2.14. 报错: Computed property “xxx” was assigned to but it has no setter
错误描述: 计算属性想被赋值, 但是它没有setter方法
- 有问题代码
<div id="app">
<input type="checkbox" v-model="isAll">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
computed: {
isAll(){
return true;
}
}
})
</script>
-
分析:
发现v-model会把标签的value值/状态值绑定给v-model指定的变量, 而变量又是给计算属性, 计算属性默认只返回值, 不是给它赋值
-
解决:
修改computed里的代码即可, 给计算属性一个set的机会, 但是千万不要在这里给计算 属性赋值, 会引起递归的
computed: {
isAll: {
set(val) {
// 设置isAll的值的时候触发此方法, 传入要设置的值
// val是全选框的true/false的值
this.arr.map(obj => {
obj['checked'] = val;
})
},
get() {
return this.arr.every(obj => obj['checked'] == true);
}
}
}
9.2.15. 报错: avoid using JavaScript unary operator as property name
错误描述: 避免使用JavaScript一元运算符作为属性名
- 有问题代码
<tr v-for="(obj, index) in list">
<td>{
{
obj.id }}</td>
<td>{
{
obj.name }}</td>
<td>{
{
obj.time }}</td>
<td>
<button @click="delete(index)">删除</button>
</td>
</tr>
- 分析:
报错的意思是说你使用了一元运算符作为属性名, 而且报错里一直说delete有问题
后来百度一查发现delete是个关键字
所以以后不要用delete作为变量名/方法名哦
-
解决:
把delete换个名字使用和定义即可
<tr v-for="(obj, index) in list">
<td>{
{
obj.id }}</td>
<td>{
{
obj.name }}</td>
<td>{
{
obj.time }}</td>
<td>
<button @click="delBtn(index)">删除</button>
</td>
</tr>
methods: {
delBtn(index){
// 2. 给删除按钮绑定点击事件 - 传递过来对应绑定的index索引值
// 删除数组里对应的元素, vue会自动更新页面
this.list.splice(index, 1);
}
}
9.2.16. 报错: Templates should only be responseible for mapping the state to the UI
错误描述: 模板应该只负责将状态映射到UI
- 有问题代码
<body>
<div id="app">
<ul>
<li v-for="item in arr">{
{
item}}</li>
</ul>
<!-- 2. 引入 vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 3. 实例化vue对象 (把视图配置进来让vue解析)
new Vue({
el: "#app", // 指向视图的名字(选择器/dom标签)
data: {
// vue世界用到的变量
arr: ["春天", "夏天", "秋天", "冬天"] // 变量名叫arr, 值是一个数组4个元素
}
})
// 哇哦, 真香
</script>
</div>
</body>
</html>
- 分析:
报错说只负责把状态更新到UI, 而且下面波浪线画的是script标签, 说明你script不是模板代码啊
Vue会把#app指定标签内的代码认为是模板代码, 怎么把script也认为了?
看代码结构, 发现把script写#app标签里了我的天啊...
- 解决: 把script标签等拿出来啊
9.3. 拼写类错误
9.3.1. 报错: Error in mounted hook: “TypeError: xxx is not a function”
错误描述: xxx不是一个方法
- 有问题代码:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
</div>
<script> const vm = new Vue({
el: '#app', data: {
name: "cp" }, // 拼写类错误 method:{
add(){
} }, mounted(){
this.add() } }) </script>
- 分析
!> 此类错误并不会直接告诉你是拼写错了,如果你发现貌似根据错误提示怎么找都找不到,那么试着检查下,vue的配置项是不是拼写错了
- 解决: methods 配置项
9.4. 其他错误
9.4.1. 报错: this.getOptions is not a function
错误描述: this.getOptions不是一个方法
-
代码环境: @vue/cli - 内部是webpack4.x版本, 而less-loader我们下的8.x版
-
分析
这也不是我写的代码啊, 再根据别的提示说我less相关有问题, 去百度下蓝色指向的这句关键字吧
- 解决
百度上很多人遇到了, 让我下载less-loader除了8以外的版本
- 具体为啥less-loader8.x版本就不行了呢? 因为webpack4.x配置引入less-loader方式 和less-loader8不同, 具体参考这个文档
https://segmentfault.com/a/1190000039190699
9.4.2. 报错: this dependency was not found
错误描述: 找不到此依赖项
- 有问题代码:
import "@api/hmmm/questions"
- 分析
说找不到@api/hmmm/questions模块, 但是这是我们自己建立的, 为啥让我们下载, 应该是路径写错了导致未找到
- 解决:
@代表的是src文件夹, 你想访问src文件夹下的api文件夹, 正确写法 @/api
import "@/api/hmmm/questions"
9.4.3. 报错: spawn cmd ENOENT
错误描述: spawn命令无法运行
-
分析
改端口号出现这个问题, 应该是电脑的命令未找到, 通过百度得知, 需要给环境变量配置system32下的命令
-
解决:
打开电脑的环境变量, 添加system32 或者你没有%SystemRoot%变量就换成这个填进去(最好挪到环境变量最上面) C:\Windows\System32
9.4.4. 报错: Invalild options in vue.config.js
错误描述: 在vue配置文件中非法的选项
-
分析
看报错提示红色, 在vue.config.js中 devServe不被允许, 知道devServer才是正确的选项对吧?
-
解决:
把devServe 改成 devServer即可
文章评论