创建前后端项目¶
创建项目¶
版本
npm --version
# 9.5.0
node -v
# v18.15.0
npm init vite@latest database-front-web
element-plus¶
下载 element-plus
npm install element-plus --save
main.js 中
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus);
router¶
下载 router
npm install vue-router --save
main.js 中
import router from 'vue-router'
app.use(router)
在 src 下创建 router 文件夹,在 router 文件夹中创建 index.js 文件
index.js 中
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: "login", // 这个名字可以随便起
component: () => import('@/views/Login.vue'),
}
]
})
export default router
写第一个页面 Login¶
进入网址即显示的界面
前端¶
配置路由¶
src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: "Login",
component: () => import('@/views/Login.vue'),
}
]
})
export default router
写界面¶
在 views 文件夹下创建一个文件 Login
<template>
<div>注册登录页面</div>
</template>
<script setup>
</script>
<style lang="scss"></style>
发送请求¶
axios.get(url, { params: params }).then(function (response) {
console.log(response);
if (response.data.code == 200) {
proxy.Message.success("登录成功");
router.push({ path: '/home' });
} else {
proxy.Message.error("登录失败");
}
}).catch(function (error) {
console.log(error);
});
后端¶
主要做的时候就是写 Model(模型) 和 Controller(控制器),每写一个模型都要去数据库上下文中进行配置
配置 MySQL 数据库¶
添加数据库上下文
- 数据库上下文类是为给定数据模型协调 EF Core 功能的主类。
- 上下文派生自 Microsoft.EntityFrameworkCore.DbContext。
- 上下文指定数据模型中包含哪些实体。
using auth.Models;
using Microsoft.EntityFrameworkCore;
namespace auth.Database;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<User> Users { get; set; } // 对应 Models/User.cs
}
下载需要的包
dotnet add package Pomelo.EntityFrameworkCore.Mysql
没有这个包的话,下面代码中的 UseMySQL 和 ServerVersion 都不能使用
在 Program.cs 中注册数据库上下文
builder.Services.AddDbContext<auth.Database.AppDbContext>(options =>
{
options.UseMySql(builder.Configuration.GetConnectionString("mysql"), // dotnet add package Pomelo.EntityFrameworkCore.Mysql
ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("mysql")));
});
写 Model¶
模型是一组表示应用管理的数据的类。
(简单理解为 Model 与数据库中的表一一对应)
在 Models 文件夹下创建一个名为 User.cs 的文件
using System.ComponentModel.DataAnnotations; // for Key
using System.ComponentModel.DataAnnotations.Schema; // for Column
namespace auth.Models;
[Table("t_user")]
public class User
{
// 请与数据库中表字段保持一致
[Key]
[Column("UserId")]
public int UserId { get; set; }
[Column("UserName")]
public string? UserName { get; set; }
[Column("PassWord")]
public string? PassWord { get; set; }
}
写 Controller¶
在 Controllers 文件夹下创建一个名为 LoginController.cs 的文件
(简单理解为一个 xxxController.cs 文件对应一个 api,对应一个功能点)
using Microsoft.AspNetCore.Mvc;
using auth.Database;
using Microsoft.EntityFrameworkCore;
[ApiController]
[Route("api/[controller]")] // RESTful 风格
public class loginController : ControllerBase // 命名规范,继承自 ControllerBase 类的类名必须与 Controller 结尾
{
private readonly AppDbContext _database;
public loginController(AppDbContext appDbContext)
{
_database = appDbContext;
}
// http://localhost:5045/api/login?id=1&password=xxx
[HttpGet]
public IActionResult CheckUser(int id, string password) // 对外暴露的接口参数名为 id 和 password
{
var code = 200;
var msg = "success";
object data = _database.Users.ToListAsync().Result;
// 遍历 data,找到id和password匹配的用户
foreach (var user in (System.Collections.Generic.List<auth.Models.User>)data)
{
if (user.UserId == id && user.PassWord == password)
{
code = 200;
msg = "登录成功";
break;
}
else
{
code = 400;
msg = "用户名或密码错误";
}
}
return Ok(new
{
code = code,
msg = msg,
});
}
}
知识点¶
- 修改配置文件后,要重新运行项目
npm run dev
配置跨域 CROS¶
在 vue3 中 vite.config.js
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) // 为 src 创建一个别名
}
},
server: {
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true, // 允许跨域请求
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
})
封装 axis 请求¶
在 src/utils 文件夹下创建 Request.js 文件
import axios from 'axios'; // 引入axios
// 创建axios实例
const instance = axios.create({
baseURL: '/api', // api的base_url
timeout: 5000 // 请求超时时间
});
// 请求前过滤器
install.interceptors.request.use();
// 请求后过滤器
install.interceptors.response.use();
const request = (config) => {
}
export default request;
el-form 组件¶
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
model | 表单数据对象 | object |
— |
rules | 表单验证规则 | object |
— |
Vue3 中的 ref 属性¶
参考:https://cn.vuejs.org/guide/essentials/template-refs.html
在 <script setup></script>
中定义函数的两种形式¶
// 箭头函数
const log = () => {
console.log(msg)
}
function log() {
console.log(msg)
}
尽量使用箭头函数
组合式 API 和选项式 API¶
使用组合式 API,配合 setup
语法糖,不要使用选项式 API,组合式 API 和选项式 API 是 Vue 组件编写的两种风格,参考 https://cn.vuejs.org/guide/introduction.html#api-styles
选项式 API¶
使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 data
、methods
和 mounted
。选项所定义的属性都会暴露在函数内部的 this
上,它会指向当前的组件实例。
<script>
export default {
// data() 返回的属性将会成为响应式的状态
// 并且暴露在 `this` 上
data() {
return {
count: 0
}
},
// methods 是一些用来更改状态与触发更新的函数
// 它们可以在模板中作为事件监听器绑定
methods: {
increment() {
this.count++
}
},
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
// 例如这个函数就会在组件挂载完成后被调用
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
</script>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
组合式 API¶
通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与 <script setup>
搭配使用。这个 setup
attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup>
中的导入和顶层变量/函数都能够在模板中直接使用。
下面是使用了组合式 API 与 <script setup>
改造后和上面的模板完全一样的组件:
<script setup>
import { ref, onMounted } from 'vue'
// 响应式状态
const count = ref(0)
// 用来修改状态、触发更新的函数
function increment() {
count.value++
}
// 生命周期钩子
onMounted(() => {
console.log(`The initial count is ${count.value}.`)
})
</script>
<template>
<button @click="increment">Count is: {{ count }}</button>
</template>
关于 .vue 文件的几点说明¶
<template>
<div></div>
</template>
<script setup>
</script>
<style lang="scss"></style>
上面是我们项目的推荐格式,script 标签后面有 setup,style 标签后有 lang="scss"
在网上查/找代码时,你可能会看到有的代码没有这些,问题也不大,尽量用我们给的格式。
style lang="scss"></style>
包含 <style></style>
,即前者是后者的超集,所以不管你写的是什么,直接加上 lang="scss"
。
有无 setup
的区别比较大,一两句话也说不清楚,可以自己百度搜搜看。简单来说就说就是,加上 setup
后,就不需要 export xxx
。请不要使用 <script setup lang="ts"><script>
,即不要使用 typescript
语法。
可以看看这篇文章,https://blog.csdn.net/u013505589/article/details/122718376,以及官方文档,https://cn.vuejs.org/api/sfc-script-setup.html
API 开发指南
Controllers
Models
下载软件:Apifox (https://apifox.com)