跳到主要内容位置

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 完全指南》课程,连载中现只需 48 元(领取优惠券)点击查看详情。

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

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

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