错误描述: 什么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, 就是你变量没有访问到, 检查下你的代码
错误描述: undefined不能读取属性forEach
// 1.2 (基础) - 把数组数据铺设到页面上
var arr = res.date;
arr.forEach(function(obj){
let {id, publisher, author, bookname} = obj;
var theTr = `
${id}
${bookname}
${author}
${publisher}
删除
`;
$("#tb").prepend(theTr);
})
在第80行有问题, 查看报错的代码
是arr读取的forEach方法, 报错说arr是个undefined(说明arr变量里的值是undefined)
顺藤摸瓜:
那么观察arr的值是在上面res.date给的
那打印res观察 (很关键, 一定要学会打印)
发现res的数据再data属性上, 而非date. 发现是拼写错误咯
var arr = res.data;
错误描述: 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
错误描述: 未能对“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); // 传参给后台, 参数名要跟后台对上
错误描述: 必须调用父类的constructor构造函数
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
constructor(x, y) {
this.x = x;
super();
}
}
new Son();
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();
描述: 发现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 哦
错误描述: 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)
// 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);
})
})
问题描述: 点了按钮什么反应也没有
$("#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();
})
错误描述: 因特网已经断开连接
错误描述: 没有找到你想访问的
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地址不对, 具体是哪一个, 根据报错的提示行数即可找到
问题描述, 点击Rest Client插件编写的.http文件上的Send Request本想发送这个http请求, 但是右下角报错
Header name must be a valid HTTP
请求头 名字 必须是一个合法的
注意, http请求报文结构中,
第一行是请求方式, 请求URL地址
第二行往下每行都是一对请求头的名字:值 (千万不能带分号后面, 这也不是js代码, 这是http请求报文)
空行 (必须的, 规定, 因为下面是请求体的参数不再是请求头的一部分了)
请求体的内容参数和值
错误描述: 没有一个git仓库(存储)
fatal: not a git repository (or any of the parent directories): .git
致命错误: 没有git仓库(或任何父目录中) 有.git文件夹的
这个.git文件夹 (要么git clone拉取远程仓库产生), 要么git本地仓库(git init)初始化的
你现在少这个.git隐藏的文件夹啊
补充知识: .git里管理着git相关的一切
错误描述: xxxx地址看你自己的, 跟我的可能不一样, 但是前面错误提示是一样的
error: src refspec master does not match any
错误: master分支里没有任何匹配的东西
error: failed to push some refs to 'gitee.com:itcz_jiaoyu/good122.git'
错误: 推送文件到'地址'的时候失败了
综上所述: 是你本地没有暂存和提交, 没什么可以推送的啊
错误描述: 您没有预授权,访问此存储库
1. 远程仓库如果是你的, 证明你账号/密码输入错误(如果用的是http的git地址), 请输入正确的
远程仓库是你的, 用ssh地址进行推送, 请确认你的ssh秘钥是正确配置的(包括文件名是否在正确的默认位置)
2. 远程仓库别人的, 请让他在这个项目里把你加入到他的项目成员里, 你才有权限推送哦
自己的就配置ssh / 确认账号密码正确(登录你git远程仓库网站的账号和密码)
如果别人的, 请让他拉你进它的项目组里(如果是gitee.com, 你需要在右上角小铃铛的私信里确认邀请链接)
错误描述: 仓库没找到
git 克隆说没有找到这个远程仓库
那肯定就是你的远程仓库地址不对
重新找一下复制一下
问题描述: 点击按钮提交表单, 本想着是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();
});
})
排查: 所以找到绑定submit事件那里, 观察你的阻止默认行为的代码 (特别是单词 是否正确)
发现preventDefalt() 单词拼写错误, 正确应该是preventDefault()
解决: 把单词改成正确的即可
总结: 多在心中念, 念的时候就知道怎么拼写了, 如果上面单词对了, 请检查on绑定事件是否正确 - 以及前面标签获取是否正确
$("#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();
});
})
// 既然说我用户名是undefined, 就打印下获取的用户名标签里的val()值
console.log($("#register .input[name=username]").val());
// 发现值确实是undefined
那肯定这行代码有问题, 逐个选择器分析, 发现是最后发现是input前面多了个. (input是标签名不是class)
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}$/
],
})
// 发现只有规则, 没有提示
form.verify({
usern: [ // 用户名
/^[a-z0-9]{6,10}$/,
"用户名6到10位的数字和小字母组成"
],
})
错误描述: 后台在影响状态码为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字符串哦
const canvas = cropper.getCroppedCanvas({
width: 500,
height: 500
}); // 因为canvas标签太大了. 图片太大, 改成100就好了
avatar有问题导致虽然接口成功, 但是图片获取还是没有
可以把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);
错误描述: 提示安装包和安装进程有问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5xOAf2It-1625746875785)(images/用硬盘版安装_自己配置环境变量.png)]
分析
这个安装程序, 这个安装包有问题, 可以百度搜索下2503的解决方案
如果都不行, 就不要用.msi安装程序了, 直接去官网下载硬盘版(二进制的文件)直接手动配置环境变量(可以百度搜索)
解决
硬盘版安装
或者
看这个地址操作: https://jingyan.baidu.com/article/cdddd41c97e94853ca00e17e.html
错误描述: 输入的命令不存在
分析
这是要node xxx 用node执行这个js文件吧?
报错说命令怎么是我这个js文件呢?
啊, 原来没写node
解决
node 下载的包引入使用.js
总结: 执行js文件, 要用node命令哦
错误描述: 你不能发布这个版本
分析
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 或者自己按照自己规则往上增加, 大修改.中修改.小修改
错误描述: 新包名不合法
分析
403 "Raincr" is invalid for new packages
"自己的包名" 不是一个新的合法的包名
说你的R大写开头不合法
解决
去修改package.json的name属性的值(这是发布用的包名) - 但是建议文件夹名也一致(方便对应)
错误描述: 包名触发的垃圾邮件检测
分析
403 Package name triggered spam detection
包名太垃圾了 哈哈哈哈开个玩笑, 就是不能乱写一点规则都没有啊
改为正常的包名
一般英文开头, 单词含义, -中划线链接
解决
去package.json里改name的值, 文件夹最好保持一致
错误描述: 太多请求了
分析
Too Many Requests
太多的请求了
这个网站短时间有太多的请求, 就会拒绝正常逻辑响应
解决
换个网络 / 等1个小时以后再来注册吧
错误描述: 不允许操作
分析
operation not permitted
不允许操作
说你没有权限
解决
请以管理员方式打开终端, 可以百度看看怎么用管理员方式打开, 在搜索框里搜索右键图标, 有管理员方式打开
错误描述: 不能删除模块包
分析
403 Forbidden - DELETE https://registry.npm.taobao.org/xxx -tors can unpublish module
说你没有权限删除, 发现发布的包都在官方的镜像地址上, 但是这里怎么有淘宝字样
所以你没有切换npm的镜像地址
解决
npm config set registry https://registry.npmjs.org
然后在执行删除包命令
错误描述: 网关错误
分析
502 5开头的一般都是服务器错误, 所以后台问题网络问题
解决
切换网络 / ctrl+c停止后, 再重新来一遍
错误描述: 这是一个与网络连接有关的问题
分析
request to https://registry.npmjs.org/~/v1/login filed reason: getaddrinfo ENOTFOUND registry.npmjs.org
请求时, 找不到这个地址
一般是网络问题
解决
切换网络 / ctrl+c停止后, 再重新来一遍
错误描述: 本机没有这个命令
分析
nodeomon 不是内部或外部命令
一切的命令都要安装到电脑里的程序员用的软件, 而且要成功配置到计算机的环境变量里, cmd终端里才能执行这个命令程序
nodemon 是替代node命令来实时更新js代码运行的效果的, 很明显单词打错了
// 如果单词没错就是环境没安装对, 重新安装即可
解决
nodemon xxxx.js
错误描述: 邮箱没有验证
分析
403 Forbidden
一般都是没有权限
1. 请确认你包的package.json文件名字 和 npmjs.com网站上没有重名的才可以
2. 在npmjs.com注册账号的时候, 会给你填写的邮箱里发一封右键, 必须点击右键里的verify按钮验证链接才算验证激活 (才能用这个账号向npm网站发布包)
解决
去npmjs.com登录你的账号 / 邮箱里找找有没有这个邮件
如果都没有重新注册一个邮箱再来注册这个网站 (如果不想发布也可以了解下就行了_ 哈哈)
错误描述: 发生意外的错误
看后面说package.json里的JSON格式有问题, 大概在177个字符位置
JSON格式非常严谨, 必须都是英文的标点, 而且只能用双引号, key也得是双引号
JSON格式: 大括号里往里嵌套, 最外层不能是并列的大括号, 所以看看是不是写外面了
可能会隐藏中文的空格, 自己调整输入法重写下
错误描述: 不知道命令或入口
不知道命令或入口 --config webpack.config.js
错误描述: 找不到模块
找不到模块, 具体后面看是webpack.config.js这个模块文件
错误描述: 不能引入vue
找不到模块vue, 这是个第三方的vue包
错误描述: 包名称无效
yarn init为了初始化包环境得到package.json
终端会问你, 你的包名叫什么, 直接回车会用当前文件夹名也 就是括号里的
但是我们好像有中文/特殊符号
文件夹是文件夹, 包名是包名 不冲突, 所以在后面不能直接回车, 随便给个合法的名字即可
错误描述: 不能引入xxx什么了
得能从这个报错信息里, 提取有用的信息, 发现说不能引入jquery了
发现好像忘记下jquery了, 或者重新下载一遍
错误描述: 终端不能识别yarn为命令使用
图里用的是powerShell终端, win10新出的, 执行策略帮助你防止执行不信任的脚本
在终端执行: set-ExecutionPolicy RemoteSigned
错误描述: node引擎不兼容
也可能这张
图1: 希望node版本大于10.17.0, 但是现在的是10.16.0
图2: 希望node版本在10.x 或者12.x 或者大于14, 但你是13(唯独不是那几个范围的) 去重新下个node即可
去node官网下载一个大于10.17的版本的nodejs, 在当前电脑覆盖式安装即可
错误描述: 执行自定义命令时, 真正打包命令叫webpack
很有可能你当前工程下没有webpack, 去package.json确认下, 如果真没有就下载即可
重新在当前工程下载webpack (如果webpack4以上版本还需要下载webpack-cli)
错误描述: 不能找到package.json文件
不能找到package.json文件, 在01_笔记和ppt目录下确定下是否有package.json文件
是否命令所在文件夹下没有这个package.json文件
因为yarn build自定义命令, 在当前目录下找到package.json文件的script的build命令
确认下终端敲命令时, 当前所在文件夹路径是否正确
错误描述: yarn不是命令, 无法使用
安装yarn软件, 会自动配置环境变量到电脑里, cmd终端所用的命令都是在我的电脑里的环境变量的
执行的命令其实都对应着电脑里的应用程序
方案1: 重新安装下yarn软件, 而且目录上不能出现yarn文件夹名字/叫yarn的文件名 – 否则就覆盖了环境变量使用不了真正的yarn应用程序了
方案2: 可以用npm install -g yarn (安装个全局yarn命令) - 如果还不行就把yarn和node都卸载后重新安装到c盘下
错误描述: 执行yarn build打包找不到系统路径
yarn打包时, 要使用webpack命令, 内部需要node环境, 所以猜测应该是node有问题
node安装路径上不要出现中文, 建议yarn和node都安装到c盘的无中文路径下面
错误描述: 模块解析失败, 不能处理html文件
你可能把html文件引入到js里了, webpack分析到了你的html文件, 但是你没有加载器/插件能打包html文件
其实我们是用插件,让html作为模板自动生成一个html文件, 而不是要在js里引入啊
错误描述: 命令没有找到
yarn serve命令来自于package.json中
发现package.json中名字写的跟要执行的不一样
错误描述: 变量未定义
<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>
vue框架针对这类错误会给出俩块错误提示
标记为1的地方是vue框架给出的发生错误的组件中的位置 上图的意思是错误发生在Root根组件的mounted声明周期函数中
标记为2的地方是vue框架给出的发生错误的js语言中调用栈的位置 上图的意思是错误发生在add方法调用的时候
!> 这一类错误都是相同的排错方式 按照下面的步骤即可
tsconfig.json
or jsconfig.json
in xxx警告提示:Vetur 插件在当前项目中没有找到 tsconfig.json
or jsconfig.json
配置
提示截图
这个是Vetur插件的警告提示,关掉提示有没有影响呀?
关掉提示没有大影响,只是不能充分发挥Vuter插件功能。
因为VsCode规定:jsconfig.json 文件表示该目录是 JavaScript 项目的根目录。
Vue 项目中配置 jsconfig.json 后,Vuter 插件语法关联功能更加强大。
在 项目根目录下,新建 jsconfig.json
并添加以下配置。
{
"compilerOptions": {
"target": "es2017",
"allowSyntheticDefaultImports": false,
"baseUrl": "./",
"paths": {
"@/*": [
"src/*"
]
}
},
"exclude": [
"node_modules",
"dist"
]
}
错误提示: Vue没定义啊
<body>
<div id="app"></div>
</body>
<script>
new Vue({
el:'#app'
})
</script>
报错图示:
分析
Vue全局变量哪里来的啊? 是不是引入vue.js才暴露在全局的啊, 就跟$变量也是引入jQuery.js才有的
所以证明你没有引入Vue.js
去引入vue.js源码到你的页面中即可
错误描述: 运行后, 出现了双大括号, 不解析了
1. 先看看浏览器是否有报错 有报错提示根据提示解决问题
2. 可能把标签内容都写在了<div id="app"> </div> 外面去了
把内容都写到div#app里面来, 因为vue指定了以#app为根标签, 按照你写的模板结构, vue会创建一套虚拟DOM解析真正的内容和标签, 然后替换到这个标签上来, 写外面你让vue咋解析?
错误描述: 不能使用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作为挂载的根元素
把挂载根元素换成普通元素即可
错误描述: 属性或方法没定义
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<div id="app">
{{name}}
div>
<script>
const vm = new Vue({
el: '#app',
computed:{}
data: {},
methods: {}
})
script>
在vue组件实例的模板中使用到的属性值或者方法必须要在实例的配置项中定义好才可以使用
根据错误提示的内容,去组件实例选项中查看是否未定义该属性,查找范围包括data,computed,methods,props
在data: {} 里面定义name变量
错误描述: 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中任意两项出现重复的属性名,在初始化配置时会进行名称检测
根据错误提示找到哪里发生了重复,找到重复属性名更改为不重复即可
错误描述: 发现重复的key
-
{{item.name}}
为保证列表的高效更新 vue框架在我们使用v-for指令的时候要求为每一项绑定一个唯一的key属性,注意key必须是唯一不可重复的 代码中的存在重复的id 所以会报错
每次给key绑定值时确保是唯一的值
-
{{item.name}}
错误描述: 说你的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>
错误描述: 组件模板应该只包含一个根元素标签
<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: `
`
})
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: `
`
})
new Vue({
el: '#app'
})
script>
错误描述: 不知道自定义的标签, 你注册了吗?
<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:`
我是父组件
`
})
const vm = new Vue({
el: '#app',
components:{
'son-component':{
template:`
我是子组件
`
}
}
})
script>
分析
组件 并没有在父组件 中注册,所以并不能正常使用,大家一定要记着,全局组件在每一个vue实例的模板中都能正常使用,而局部注册的组件只有在父组件的components选项中注册时候才能使用
解决
在父组件的components中注册一下组件即可
错误描述: 无法装载组件:未定义模板或呈现函数
<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="./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: `
{{title}}
`,
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: `
{{childTitle}}
`,
methods: {
change() {
this.childTitle = 'new title'
}
}
})
new Vue({
el: '#app'
})
</script>
错误描述: 计算属性想被赋值, 但是它没有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);
}
}
}
错误描述: 避免使用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);
}
}
错误描述: 模板应该只负责将状态映射到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标签里了我的天啊...
错误描述: 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的配置项是不是拼写错了
错误描述: this.getOptions不是一个方法
代码环境: @vue/cli - 内部是webpack4.x版本, 而less-loader我们下的8.x版
报错图示:
这也不是我写的代码啊, 再根据别的提示说我less相关有问题, 去百度下蓝色指向的这句关键字吧
百度上很多人遇到了, 让我下载less-loader除了8以外的版本
https://segmentfault.com/a/1190000039190699
错误描述: 找不到此依赖项
import "@api/hmmm/questions"
说找不到@api/hmmm/questions模块, 但是这是我们自己建立的, 为啥让我们下载, 应该是路径写错了导致未找到
@代表的是src文件夹, 你想访问src文件夹下的api文件夹, 正确写法 @/api
import "@/api/hmmm/questions"
错误描述: spawn命令无法运行
分析
改端口号出现这个问题, 应该是电脑的命令未找到, 通过百度得知, 需要给环境变量配置system32下的命令
解决:
打开电脑的环境变量, 添加system32 或者你没有%SystemRoot%变量就换成这个填进去(最好挪到环境变量最上面) C:\Windows\System32
错误描述: 在vue配置文件中非法的选项
分析
看报错提示红色, 在vue.config.js中 devServe不被允许, 知道devServer才是正确的选项对吧?
解决:
把devServe 改成 devServer即可