文章目录
- ⭐前言
- 💖vue3系列文章
- 💖node系列文章
- ⭐ 功能设计与实现
- 💖数据库设计
- 💖koa接口实现
- 💖vue3的展示代码模板页面
- ⭐效果
- ⭐总结
- ⭐结束
⭐前言
大家好,我是yma16,本文分享关于 前端vite+vue3结合后端node+koa——实现代码模板展示平台(助力初学者快速上手)。
背景
2024年已经步入春天,马上到了毕业季,为了帮助学生快速搭建毕设框架,于是想着搭建一个模板代码平台,支持下载。
技术选型
前端:vite+vue3+antd
后端:node koa
数据库:mysql、redis
vue3框架
Vue 3 是一种用于构建用户界面的 JavaScript 框架。它是 Vue.js 框架的最新版本,于2020年9月正式发布。Vue 3
相对于 Vue 2 来说,进行了一些重大的改进和优化。
koa框架
Koa框架是一个基于Node.js的轻量级的Web应用框架,由Express的原班人马开发。它使用了ES6的新特性,如async/await,来解决回调地狱的问题,并提供了更简洁、易理解的代码结构。
⭐ 功能设计与实现
用户使用账号邮箱进行登录注册,进入站点之后可以查看代码模板,支持模糊搜索关键词,可以看见代码模板的详情和介绍图片
所以提取出用户表和产品表
💖数据库设计
产品的表的结构如下
/*
Navicat Premium Data Transfer
Source Server : yongma16.xyz
Source Server Type : MySQL
Source Server Version : 80033
Source Host : yongma16.xyz:3306
Source Schema : threejs_data
Target Server Type : MySQL
Target Server Version : 80033
File Encoding : 65001
Date: 13/02/2024 23:07:30
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for product
-- ----------------------------
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
`id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'id',
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标题',
`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '内容',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
`type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '类型',
`html_text` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'html内容',
`img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '封面图片',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`create_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建用户',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
表字段结构图
💖koa接口实现
koa的实现对product表的分页查询、模糊查询。
sql的分页查询
在 SQL 中,我们可以使用 LIMIT 和 OFFSET 子句来实现分页查询。
LIMIT 子句用于限制查询结果的行数,OFFSET 子句用于指定从查询结果中的哪一行开始返回数据。
以下是一个示例:
SELECT * FROM 表名
LIMIT 查询数量 OFFSET 偏移量;
其中,“表名” 是你要查询的表的名称,“查询数量” 是每页显示的行数,“偏移量” 是从哪一行开始返回数据。
例如,下面的查询将返回从第 10 行开始的 5 条数据:
SELECT * FROM 表名
LIMIT 5 OFFSET 10;
注意:在一些数据库中,也可以使用其他语法来实现分页查询,比如 MySQL 中可以使用 LIMIT 和 OFFSET,而 Oracle 中可以使用 ROWNUM 和 BETWEEN 子句。具体的语法请根据你所使用的数据库而定。
sql的模糊查询
在SQL中,可以使用通配符来进行模糊查询。常用的通配符有%
和_
。
-
%
表示任意长度的字符,可以匹配0个或多个字符。 -
_
表示一个字符,可以匹配任意单个字符。
下面是几个使用模糊查询的例子:
- 查找名字以 “A” 开头的学生:
SELECT * FROM students WHERE name LIKE 'A%';
- 查找名字以 “son” 结尾的学生:
SELECT * FROM students WHERE name LIKE '%son';
- 查找名字中包含 “an” 的学生:
SELECT * FROM students WHERE name LIKE '%an%';
- 查找名字由3个字符组成的学生:
SELECT * FROM students WHERE name LIKE '___';
在使用模糊查询时,需要注意的是通配符的位置和数量。
koa的代码实现
const Router = require('koa-router');
const router = new Router();
const {execMysql}=require('../../utils/mysql/index')
// 获取product list
router.post('/product/list', async (ctx) => {
try{
// 解析参数
const bodyParams = ctx.request.body
const {pageSize,page,name} = bodyParams;
const start=Number(pageSize)*Number(page-1)
const end=Number(pageSize)
const search=await execMysql(`select * from product where title like '%${name}%' order by create_time desc limit ${start},${end};`);
const searchTotal=await execMysql(`select count(1 ) as total from product where title like '%${name}%';`);
ctx.body = {
code: 200,
data:search,
total:searchTotal?searchTotal[0].total:0,
msg: 'get product list success'};
}
catch(r){
ctx.body = {
code: 0,
data:null,
msg: JSON.stringify(r)};
}
});
💖vue3的展示代码模板页面
前端页面的封装如下
index.vue
<script lang="ts" setup>
// @ts-ignore
import {reactive,onMounted} from 'vue'
// @ts-ignore
import {getProductList} from '@/service/product/index.ts'
// @ts-ignore
const state:any=reactive({
loading:false,
title:'代码模板',
name:'',
productList:[],
pageSize:3,
page:1,
total:0,
pageSizeOptions:['3', '6', '9']
})
const searchProductAction=async ()=>{
state.loading=true
try{
const res=await getProductList({
name:state.name,
pageSize:state.pageSize,
page:state.page
});
console.log('res',res)
state.productList=res.data.data
state.total=res.data.total
}
catch (e) {
console.error(e)
state.productList=[]
state.total=0
}
finally {
state.loading=false
}
};
const searchBtn=()=>{
searchProductAction()
}
const changePage=(page,pageSize)=>{
state.page=page
state.pageSize=pageSize
searchBtn()
}
onMounted(()=>{
searchBtn()
})
</script>
<template>
<div>
{{state.title}}
</div>
<div>
<a-row>
<a-col :span="12">
<a-input v-model:value="state.name" placeholder="输入名称搜索" allowClear />
</a-col>
<a-col :span="12" style="padding-left: 20px">
<a-button type="primary" @click="searchBtn">查询</a-button>
</a-col>
</a-row>
</div>
<div style="margin-top: 10px;margin-bottom: 10px">
<a-spin :spinning="state.loading">
<div v-for="(item,index) in state.productList" :key="index" style="display: inline-block;margin: 2px">
<a-card hoverable style="width: 240px;">
<template #cover>
<a-image :alt="item.title" :src="item.img" />
</template>
<a-card-meta :title="item.title">
<template #description>{{item.description}}</template>
</a-card-meta>
</a-card>
</div>
<div style="margin-top: 10px">
<a-pagination showTotal showSizeChanger v-model:current="state.page" :total="state.total" :pageSize="state.pageSize" :pageSizeOptions="state.pageSizeOptions" @change="changePage"/>
</div>
</a-spin>
</div>
</template>
效果
⭐效果
模糊搜索
分页
loading查询效果
⭐总结
前端:
- 搜索输入
- 展示卡片
- 分页组件
后端:
- sql分页查询要返回前端总数
- 处理分页数越界的情况
全栈开发优势
前后端一起开发有以下几个优势:
- 提高开发效率:前后端一起开发可以减少沟通和协调的成本,前端开发人员和后端开发人员同时进行开发,可以减少等待对方完成工作的时间,从而加快项目的开发进度。
- 提高团队协作:前后端一起开发能够促进团队成员之间的沟通和协作,前后端开发人员可以更加紧密地合作,共同解决问题和提高代码质量。
- 提升用户体验:前后端一起开发可以更好地保持用户界面和后端逻辑的一致性,前端开发人员可以及时调整用户界面的设计和交互,与后端开发人员协作,确保用户体验的一致性和流畅性。
- 减少系统漏洞:前后端一起开发可以及时发现并修复系统漏洞,前端开发人员和后端开发人员可以共同测试和验证系统的安全性,从而减少潜在的漏洞和风险。
总之,前后端一起开发能够提高开发效率、团队协作和用户体验,更好地保证系统的稳定性和安全性。
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!