官网:
https://github.com/lenve/vhr2.0/tree/main
0. JS
这里列举常用的几个
Promise
参考官网:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises
使用
Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。本质上 Promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。
// 成功的回调函数
function successCallback(result) {
console.log("音频文件创建成功:" + result);
}
// 失败的回调函数
function failureCallback(error) {
console.log("音频文件创建失败:" + error);
}
createAudioFileAsync(audioSettings, successCallback, failureCallback);
等效于函数Promise
createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
链式调用及传参说明
then() 函数会返回一个和原来不同的新的 Promise
const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
第二个promise2 代表了doSometing()的完成和传入successCallback、failureCallback的完成。
如此,再promise2后面
假设有一个函数:
function doSomething() {
return new Promise((resolve) => {
setTimeout(() => {
// 在完成 Promise 之前的其他操作
console.log("完成了一些事情");
// promise 的兑现值
resolve("https://example.com/");
}, 200);
});
}
如下两个函数等效:
doSomething(function (result) {
doSomethingElse(result, function (newResult) {
doThirdThing(newResult, function (finalResult) {
console.log(`得到最终结果:${finalResult}`);
}, failureCallback);
}, failureCallback);
}, failureCallback);
doSomething()
.then((result) => doSomethingElse(result))
.then((newResult) => doThirdThing(newResult))
.then((finalResult) => {
console.log(`得到最终结果:${finalResult}`);
})
.catch(failureCallback);
1. 项目启动配置
1.1 数据库
运行对应sql文件,创建数据库。
1.2 配置前端
需要额外安装 @element-plus/icons-vue
前端的响应端口
后端的服务端口
1.3 后端配置
数据库连接配置:
vhr-web 的application.yaml中。
2 前端项目分析
2.1 vite配置:vite.config.js
该文件是面向vite的,加载vite的相关配置。只不过配置文件是用js写的。
vite是node下的一个开发服务器。vite运行时,会自动解析项目根目录下名为vite.config.js的配置文件。
export default defineConfig()
defineConfig 用于定义vite配置。
入口参数为对象 {}
补充:js用{}标识一个对象,无需集合数据类型。键值对形式组成,逗号分隔。
{
server:{},//后端服务器相关配置
plugins:[vue()],//使用vue插件
resolve:{//模块解析相关配置
alias:{
'@': fileURLToPath(new URL('./src', import.meta.url)) //将@别名指向src目录
}
},
}
还有一种别名的配置方法,是在jsconfig.js下配置,
参考
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";//引入包
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
//配置别名
resolve: {
alias: {
// 关键代码
"@": path.resolve(__dirname, "./src"),
},
},
});
//需要 npm i path
根据博文,服务器相关配置:
server: {
cors: true, // 默认启用并允许任何源
open: true, // 在服务器启动时自动在浏览器中打开应用程序
//反向代理配置,注意rewrite写法,开始没看文档在这里踩了坑
proxy: {
'/api': {
target: 'http://192.168.99.223:3000', //代理接口
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
2.2 index.html 单页面应用SAP
SPA(Single Page Application,单页应用)是一种特别的网页应用程序,它通过加载一个单个 HTML 页面并在用户与应用程序交互时动态更新该页面的相关部分,而不是加载新的页面来提供与传统网页应用程序类似的用户体验。
在 Vue 中,SPA 架构通常通过 Vue Router 这个官方的路由插件来实现,与组件系统一起运作,Vue Router 让你可以为不同的路径定义你的页面组件,而无需在服务器上设置多个页面。
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 网页标题(会显示在浏览器分页上) -->
<title>Vue3</title>
</head>
<body>
<!-- Vue 挂载点(必须与 main.js 中的挂载目标一致) -->
<div id="app"></div>
<!-- 主入口文件(Vite 会自动处理模块解析) -->
<script type="module" src="/src/main.js"></script>
</body>
</html>
其中,如下内容是關鍵:
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
- id属性指定了vue3项目的挂载点。(在main.js中,要設置程序挂載至 id=app的DOM上。
- type=module src=xxx ,xxx指定了入口文件。
2.3 router
一般定义在./src/router/index.js中
导入的时候,可直接简写为: (这是因为js的默认查找规则,模块系统会自动查找./router文件夹下一个名为index.js的文件,进一步,如果import xxx 在index.js文件中并不存在,xxx将被赋予文件下的export default的对象。)
import router from './router'
一般,router用createRouter定义,并且,在页面跳转时需要设置 路由导航受委。监听页面跳转。
import UserList from '../views/UserList.vue'
import HomePage from '../views/HomView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path:'/home',
name:'主页',
hidden: true,
component: () => import('../views/HomeView.vue'),
// 这种是动态加载
// 靜態加載方式: compoent:HomePage
},
{
path:'/list',
name:'用户列表',
hidden: true,
component: UserList, //直接加载
children: [
{
//与普通路由一样,添加子路由
},
]
},
]
})
<RouterView/>
上述标签相当于占位符,这个位置显示的内容有浏览器地址栏决定。
浏览器地址和页面之间的映射关系定义在路由router中。
2.4 axios
官网:https://www.axios-http.cn/docs/example
与后端交互:axios是基于Promise的网路请求库(具体而言,是HTTP)
响应拦截器:所谓请求拦截器,就是在请求相应前和响应后,自定义一些操作,等这些操作处理完后,再进行响应
// @/utils/request.js
import axios from "axios";
import {ElMessage} from "element-plus";
import router from "@/router/index.js";
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
const service = axios.create({
timeout: 10000
})
//这个是请求拦截器,如果是使用 JWT 或者其他令牌登录的话,那么可以在请求拦截器中统一添加令牌
service.interceptors.request.use();
service.interceptors.response.use(success => {
//获取服务端返回的状态码,如果服务端没有设置状态码,默认就是 200
const code = success.data.status || 200;
if (code == 200) {
//说明请求成功
if (success.data.message) {
ElMessage.success(success.data.message)
}
//返回服务端返回的 JSON
return success.data;
} else {
ElMessage.error(success.data.message)
return Promise.reject(success.data.message);
}
}, error => {
if (error.response.status == 401) {
//说明未登录
router.replace('/');
}
//HTTP 状态码不是 200,就会进入到这个回调中
ElMessage.error(error);
return Promise.reject(error);
})
export default service;
实际使用的时候,我们会在这基础上进行请求封装
2.4.1 请求封装
import request from "@/utils/request.js";
export function login(hr) {
return request({
url: '/api/login',
method: 'post',
data: hr
})
}
export function logout() {
return request({
url: '/api/logout',
method: 'get'
})
}
这里request就是调用的在 @/utils/request.js 定义的service,結果返回是一個Promise。
2.5 pinia (store)
https://pinia.web3doc.top/
Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。
// 在main.js中,创建Pinia实例并挂载
import { createApp } from 'vue';
import { createPinia } from 'pinia';
const app = createApp(App);
app.use(createPinia()); // 必须步骤:ml-citation{ref="2,3" data="citationList"}
// 定義一個store
const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
}
}
})
2.3 登录页面响应逻辑
3 后端项目
几个关键的配置
- 依赖配置: pom.xml
- 基本信息配置(数据库、端口、全局变量等): src/main/resources/application.properties
- 其他代碼
3.1 代码撰写一般逻辑
4 前后端交互
前后端交互,使用的是json格式。json格式就是javaScript中的对象格式。{}包裹,键值对形式的数据。
通过变量名,一 一对应数据。
关于响应式数据的误区
响应式指得是在 < script/> 部分,一但变量内容发生变化,在 < template/> 中,使用的变量也会同步变化。
而响应式数据值得改变,还是需要在< script/>部分,手动更新,或者设置函数更新(就像正常变量那样更新)。
响应式数据reactive,ref, toRefs, toRef
参考博文:
https://blog.csdn.net/m0_57836225/article/details/142725646