我的项目是基于Express框架+art-template模板的,用到的是MongoDB数据库,是个人的前后台博客开发,现在写写我在这个过程中遇到的问题和一些解决的方法,希望可以帮助和我有同样问题的人~
目录
举例1:TypeError: Joi.validate is not a function
举例2:错误 [ERR_REQUIRE_ESM]:不支持 ES 模块的 require()
遇到的问题:RangeError: Maximum call stack size exceeded
一、第三方模块的版本问题
算是第一次写比较完整的项目,没什么经验,下载模块的时候没有需要注意版本的意识,有60%的bug都是因为引进的第三方模块版本不匹配导致的!
举例1:TypeError: Joi.validate is not a function
起初以为是没正确引入,检查后发现是没引入指定版本
解决方法:安装指定版本joi@14.3,然后就不报错啦!
举例2:错误 [ERR_REQUIRE_ESM]:不支持 ES 模块的 require()
这个是在引入dateformat的时候报的错,报错原因是插件版本不支持require,版本降级到支持require的版本就可以解决!
【这个也可以改用import的方式导入,一样可以解决问题】
二、模态框的遮罩问题
遮罩主要讲的就是z-index的问题,当时遇到的情况是模态框在遮罩层的下方,我有把模态框的z-index修改为更大的值但是也依旧无法实现正确遮罩关系。
原因是没有注意到使用z-index的元素及其父元素的定位关系, position:fixed不支持z-index的修改,我当时没注意到我使用了fixed,这种情况下z-index的修改是会失效的!把定位改成relative问题就解决了。
通过z-index改变元素的层级关系的时候,一定要保证当前元素属于定位元素。
三、上传封面图片的问题
图片其实就是文件,文件上传的表单和普通表单上传的区别是:必须用二进制上传。
在非二进制的表单上传中,我们是用bodyPaser处理post请求参数,现在二进制的话我们需要用到第三方模块formidable。
在html写表单处,需要注意设置enctype="multipart/form-data"
<form action="#" method="post" id="articleForm"
enctype="multipart/form-data" >
上传图片处可以用accept限定上传的文件是图片类型
<div class="col-12">
<label for="file" class="form-label">文章封面</label><br/>
<input
type="file"
name="cover"
id="file"
class="file form-control"
value="{{article&&article.cover}}"
accept=".jpg,.jpeg,.png,.webp"
/>
</div>
引入formidable,然后在表单提交的路由处利用 formidable创建表单解析对象。
需要注意的是上传文件的后缀默认不保存,所以需要更改为true
//创建表单解析对象
const form = new formidable.IncomingForm();
//配置上传文件的文件存放位置
form.uploadDir = path.join(__dirname, "../", "public", "uploads");
//保留上传文件的后缀
form.keepExtensions = true;
//解析表单
form.parse(req, (err, fields, files) => {
//err错误对象 fields 对象类型存普通数据 files对象类型存文件数据
await Article.updateOne(
{ _id: id },
{
title: fields.title,
author: fields.author,
cover: files.cover.filepath
? files.cover.filepath.split("public")[1]
: " ",
content: fields.content,
brief: fields.brief,
}
});
封面的预览
在表单里需要创建一个img用来做封面的预览图
<!-- 封面的预览 -->
<div class="form-control imgbox">
<img class="img-thumbnail" src="{{article&&article.cover}}" id="preview">
</div>
然后在js里将图片放在#preview里
需要注意的是:readAsDataURL是异步方法,不可以通过返回值的方法获取结果,所以需要我们监听onload事件,在onload里将读取的结果作为图片的src
//文件图片显示
var file = document.querySelector('#file');
var preview = document.querySelector('#preview');
//当用户选择完文件以后
file.onchange = function () {
//创建文件读取对象
var reader = new FileReader();
//读取文件
reader.readAsDataURL(this.files[0]);
//监听onload事件
reader.onload = function () {
preview.src = reader.result;
}
}
四、多集合联合查询问题
使用MonogoDB的时候,会遇到多集合联合查询的问题。
比如文章表需要关联用户表,利用发布文章的作者的id关联用户表去寻找作者的用户名。
方法是populate()
let articles = await Article.find({}).populate("author");
遇到的问题:RangeError: Maximum call stack size exceeded
网上主要的错误方式是大量递归调用、死循环导致,还有的是组件名称冲突,重定向路径相同循环反复,但是我检查了我没有以上的这些问题。
这个地方我其实不太懂,但是找到了一个解决方法,只要加下面两行就可以解决问题!
articles = JSON.stringify(articles);
articles = JSON.parse(articles);
在写循环回复的时候,子评论也需要关联用户表,按照之前的Comment.find({}).populate("author")只可以让一级评论关联到,子评论则会报错
解决思路:多级填充
.populate({
path: "childComments",
populate: {
path: "uid"
}
});
按这样写就可以!
第一部分主要写了关于版本问题可能会引发的错误提醒大家一定一定要注意版本,然后就是我因为基础不牢会遇到的z-index问题,写出来是因为当时确实卡在这里很久没有头绪,提醒自己要再打好基础;然后写了上传文件表单的方法和在使用MongoDB数据库时关于多集合联合查询我遇到的问题。
提醒自己打好基础,也希望对你有帮助~