跳到主要内容位置

Vue 3.0 + Express.js API 前后端交互

内容加载中…

上期视频我们添加了 Express.js 结合 Notion API 的后端服务,这一期我们看一下如和把 Vue 3.0 的前端应用和后端的 Express.js API 连接起来。

配置 Proxy​

我们的 Express server 部署在 3001 端口,而前端应用开发时的服务器是在 3000 端口,在浏览器访问的时候会有跨域问题,那么我们可以通过 Vite 2.0 的配置文件,添加一条 Proxy 代理配置,来让 Vite 的开发服务器帮我们转发请求,以避免跨域。

  1. 打开 vite.config.js 配置文件,在 plugins 的下方定义一个 server 属性,传递给它一个对象配置:
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
"/api": {
target: "http://localhost:3001",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});

在 server 配置对象中:

  • 配置 proxy 对象,设置 key 为 "/api" ,这样所有对于 /api 的请求都会交由这个代理去处理。
  • 配置 changeOrigin 为 true,发送请求的时候修改请求的 origin,避免跨域。
  • 配置 rewrite,把实际请求的 /api 这一段去掉,因为我们后端的服务 URL 中,没有 /api 这一段,它只是方便前端区分是否为调用后端的 URL。

现在服务代理就配置完了,我们尝试一下加载留言列表。

加载留言列表​

我们需要在应用一加载就去请求留言列表并展示,所以在我们的应用入口组件中,需要使用生命周期回调,在里边发送请求加载留言列表数据。

  1. 打开 CommentsApp.vue 组件,把之前定义的 comments ref 的示例数据删除,只保留一个空数组:
const comments = ref([]);
  1. 定义一个异步函数 getAllComments ,请求后端数据,并把结果放到 comments ref 中:
async function getAllComments() {
const res = await fetch("/api/comments");
comments.value = await res.json();
}
  1. 使用 onMounted() 生命周期回调,在组件加载完成之后,调用 getAllComments() 请求留言列表数据,记得导入进来:
import { ref, onMounted } from "vue";
onMounted(() => {
getAllComments();
});
  1. 保存一下,先在一个命令行窗口中运行 node server,启动 express 后端服务
node server
  1. 再运行 yarn dev,访问 http://localhost:3000,如果能加载到留言列表就说明成功了。

接下来,我们看一下发表留言。

发表留言和回复​

发表留言和回复的事件处理逻辑保持不变,但是现在需要调用后端服务,添加到 Notion 中。那么还是在 CommentsApp.vue 文件里,找到之前定义的 addNewComment 事件处理函数,在里边我们调用 API 把留言内容发送给后台:

const addNewComment = async (content, replyTo) => {
await fetch(`/api/comments`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
content,
...(replyTo && { replyTo }),
}),
});

// 新增完评论后,自动获取新的评论列表
// Notion API 有延迟,在添加完 page 之后,需要过一会才能获取到新的评论列表
setTimeout(async () => {
await getAllComments();
}, 1000);
};

这个函数我们可以让发表留言和回复共用,一并处理,因为我们不需要手动维护 comments 这个列表数组了,只是发送数据给后台,而唯一不同的地方就是 body 里,是否有 replyTo 属性,那么我们可以删除之前的 addReply() 函数,给 addNewComment 函数再加上 replyTo 参数,它接收要回复的留言的 id,再给它加上 async 关键字,因为它要发送网络请求。

  • 删除里边手动维护 comments 数组的代码。这时,constructNewComment() 也没用了,一并删除。
  • 在函数里,使用 fetch() 发送一个 post 请求。
  • 设置 content-type header 为 application/json,这一步是必须的,这样 express 才能把请求 body 转换为 json 格式。
  • body 里调用 JSON.toString() 把一个 JavaScript 对象转换为 JSON 字符串,里边同样用到了扩展运算符技巧,根据 replyTo 是否有值,来决定是否添加 replyTo 属性。
  • 后面,我们使用 setTimeout() 再请求一次获取留言列表的 API,来刷新列表。

接着把 ReplyBox 标签中,对 addReply 的调用改成 addNewComment:

<ReplyBox @submit="addNewComment($event, comment.id)" />

Notion API 的问题​

这里之所以用了一个 setTimeout() 是因为 Notion API 添加数据似乎并不是实时的,如果在创建一个 page 之后,立即获取 page,那么会获取不到它,只有在等待 700 毫秒或以上才能访问到,这个得看网络情况,后面我们再对这种情况优化一下,现在先实现主要功能。 ​

好了,现在我们发表留言和回复的接口也连接上了,打开咱们的页面,编写一些示例的留言,发表一下看看,稍等一会,能加到下面的列表中,就算成功了,如果好久没显示,可以把 setTimeout() 里的延迟调大一些。再接着试试回复,编写示例的回复并提交,稍等一会能加载出来,也就算是成功了。 ​

好了,这期视频我们连接了 Vue 3.0 的前端应用到我们的 Express 后端接口了,基本上实现了一个留言板的功能,后面看情况需要对它进行优化。Notion API 现在还在 Beta 阶段,有些不稳定,所以现在适合尝鲜,等它稳定了再开发一些比较重要的 APP。 ​

这个就是 Vue 3.0 与 Express.js 前后端交互的方法,你学会了吗?如果有帮助请三连,想学更多有用的前端开发知识,请关注峰华前端工程师,感谢观看!

提示

一系列的课程让你成为高级前端工程师。课程覆盖工作中所有常用的知识点和背后的使用逻辑,示例全部都为工作项目简化而来,学完即可直接上手开发!

即使你已经是高级前端工程师,在课程里也可能会发现新的知识点和技巧,让你的工作更加轻松!

《React 完全指南》课程,包含 React、React Router 和 Redux 详细介绍,所有示例改编自真实工作代码。点击查看详情。

《Vue 3.x 全家桶完全指南与实战课程》课程,包括 Vue 3.x、TypeScript、Vue Router 4.x、Vuex 4.x 所有初级到高级的语法特性详解,让你完全胜任 Vue 前端开发的工作。点击查看详情。

《React即时通信UI实战》课程,利用 Storybook、Styled-components、React-Spring 打造属于自己的组件库。

《JavaScript 基础语法详解》本人所著图书,包含 JavaScript 全面的语法知识和新特性, 可在京东、当当、淘宝等各大电商购买