Vue多页面路由与模版解析
上篇文章中我们成功打包并输出了多页文件,而构建一个多页应用能够让我们进一步了解项目配置的可拓展性,可以对学习 Vue 和 webpack 起到强化训练的效果,本文将在此基础上主要针对多页路由及模板的配置进行系列的介绍。
本案例代码地址:multi-page-project
路由配置
1. 跳转
在配置路由前,首先我们要明确一点就是,多页应用中的每个单页都是相互隔离的,即如果你想从 page1 下的路由跳到 page2 下的路由,你无法使用 vue-router 中的方法进行跳转,需要使用原生方法:location.href
或 location.replace
。
此外为了能够清晰的分辨路由属于哪个单页,我们应该给每个单页路由添加前缀,比如:
-
index 单页:/vue/
-
page1 单页:/vue/page1/
-
page2 单页:/vue/page2/
其中 /vue/ 为项目的二级目录,其后的目录代表路由属于哪个单页。因此我们每个单页的路由配置可以像这样:
/* page1 单页路由配置 */import Vue from 'vue'
import Router from 'vue-router'// 首页
const Home = (resolve => {//使用了 require.ensure 方法来实现懒加载require.ensure(['../views/home.vue'], () => {resolve(require('../views/home.vue'))})
})Vue.use(Router)//通过 process.env.BASE_URL 动态获取基础 URL,并添加 'page1' 作为前缀
let base = `${process.env.BASE_URL}` + 'page1'; // 添加单页前缀export default new Router({mode: 'history',base: base,routes: [{path: '/',name: 'home',//动态加载 Home 组件component: Home},]
})
我们通过设置路由的 base 值来为每个单页添加路由前缀,如果是 index 单页我们无需拼接路由前缀,直接跳转至二级目录即可。
那么在单页间跳转的地方,我们可以这样写:
<template><div id="app"><div id="nav"><a @click="goFn('')">Index</a> |<a @click="goFn('page1')">Page1</a> |<a @click="goFn('page2')">Page2</a> |</div><router-view/></div>
</template><script>
export default {methods: {goFn(name) {location.href = `${process.env.BASE_URL}` + name}}
}
</script>
用
location.href
进行导航会导致页面完全刷新,从而失去单页应用(SPA)的优点。为了保持 SPA 的特性,可以使用 Vue Router 提供的$router.push
方法进行路由导航,export default {
methods: {
goFn(name) {
this.$router.push(name); // 使用 Vue Router 进行路由导航
}
}
}
但是为了保持和 Vue 路由跳转同样的风格,我可以对单页之间的跳转做一下封装,实现一个 Navigator
类,类的代码可以查看本文最后的示例,封装完成后我们可以将跳转方法修改为:
this.$openRouter({name: name, // 跳转地址query: {text: 'hello' // 可以进行参数传递},
})
使用上述 this.$openRouter() 来调用 Navigator.openRouter
方法我们还需要一个前提条件,便是通过 Vue.prototype
将其绑定到 Vue 的原型链上,我们在所有单页的入口文件中添加:
//引入navigator对象
import { Navigator } from '../../common' // 引入 Navigator// 添加至 Vue 原型链
Vue.prototype.$openRouter = Navigator.openRouter;
Vue 3 示例
import { createApp } from 'vue';
import App from './App.vue';
import { Navigator } from '../../common';const app = createApp(App);// 添加到全局属性
app.config.globalProperties.$openRouter = Navigator.openRouter;app.mount('#app');
至此我们已经能够成功模仿 vue-router 进行单页间的跳转,但是需要注意的是因为其本质使用的是 location 跳转,所以必然会产生浏览器的刷新与重载。
2. 重定向
当我们完成上述路由跳转的功能后,可以在本地服务器上来进行一下测试,你会发现 Index 首页可以正常打开,但是跳转 Page1、Page2 却仍然处于 Index 父组件下,这是因为浏览器认为你所要跳转的页面还是在 Index 根路由下,同时又没有匹配到 Index 单页中对应的路由。这时候我们服务器需要做一次重定向,将下方路由指向对应的 html 文件即可:
/vue/page1 -> /vue/page1.html
/vue/page2 -> /vue/page2.html
在 vue.config.js 中,我们需要对 devServer 进行配置,添加 historyApiFallback
配置项,该配置项主要用于解决 HTML5 History API 产生的问题,比如其 rewrites 选项用于重写路由:
/* vue.config.js */let baseUrl = '/vue/';module.exports = {...devServer: {historyApiFallback: {rewrites: [{ from: new RegExp(baseUrl + 'page1'), to: baseUrl + 'page1.html' },{ from: new RegExp(baseUrl + 'page2'), to: baseUrl + 'page2.html' },]}}...
}
上方我们通过 rewrites 匹配正则表达式的方式将 /vue/page1
这样的路由替换为访问服务器下正确 html 文件的形式。当请求的路径符合 from
中的正则表达式时,会被重定向到 to
指定的 HTML 文件,例如,如果用户请求 /vue/page1
,则开发服务器会返回 /vue/page1.html
文件的内容。如此不同单页间便可以进行正确跳转和访问了。最后需要注意的是如果你的应用发布到正式服务器上,你同样需要让服务器或者中间层作出合理解析。
参考:HTML5 History 模式 # 后端配置例子
而更多关于 historyApiFallback 的信息可以访问:connect-history-api-fallback
拓展1
new RegExp的简易概括
new RegExp
是 JavaScript 中用于创建正则表达式对象的构造函数。正则表达式是一种强大的文本处理工具,可以用于模式匹配和搜索。通过 new RegExp
,你可以动态构造正则表达式,而不仅限于字面量表示法(使用斜杠 /
包围的形式)。
基本语法
let regex = new RegExp(pattern, flags);
- pattern: 一个字符串,定义了正则表达式的模式。
- flags: 可选字符串,定义了正则表达式的修饰符(例如,
g
表示全局匹配,i
表示不区分大小写,m
表示多行匹配等)。
示例
基本示例:
let pattern = 'abc';
let regex = new RegExp(pattern);
console.log(regex.test('abcdef')); // true
console.log(regex.test('xyz')); // false
使用修饰符:
let pattern = 'abc';
let regex = new RegExp(pattern, 'i'); // 'i' 表示不区分大小写
console.log(regex.test('ABCdef')); // true
动态构造正则表达式
使用 new RegExp
可以根据变量动态构造正则表达式:
let searchTerm = 'page';
let regex = new RegExp(searchTerm);
console.log(regex.test('This is a page.')); // true
在 Vue.js 配置中的使用
在之前的 vue.config.js
中,使用 new RegExp
创建动态正则表达式,用于匹配特定的 URL 路径。例如:
rewrites: [{ from: new RegExp(baseUrl + 'page1'), to: baseUrl + 'page1.html' },{ from: new RegExp(baseUrl + 'page2'), to: baseUrl + 'page2.html' },
]
new RegExp(baseUrl + 'page1')
创建了一个正则表达式,用于匹配以 /vue/page1
开头的 URL。当用户直接访问这个 URL 时,开发服务器会将请求重定向到 page1.html
。
总结
- 使用
new RegExp
可以动态创建正则表达式,适用于需要根据变量或用户输入构造正则的场景。 - 正则表达式在很多情况下非常有用,尤其是在处理文本、匹配模式和验证输入等方面。
- 在 Vue.js 或其他框架的配置中,可以利用正则表达式进行复杂的路由匹配和 URL 重写。
模板配置
上篇文章我们已经介绍了关于多模板的读取和配置,在配置 html-webpack-plugin 的时候我们提到了自定义配置,这里我将结合模板渲染的功能来进行统一介绍。
1. 模板渲染
这里所说的模板渲染是在我们的 html 模板文件中使用 html-webpack-plugin 提供的 default template 语法进行模板编写,比如:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>模板</title><% for (var chunk in htmlWebpackPlugin.files.css) { %><% if(htmlWebpackPlugin.files.css[chunk]) {%><link href="<%= htmlWebpackPlugin.files.css[chunk] %>" rel="stylesheet" /><%}%><% } %></head><body><div id="app"></div><!-- built files will be auto injected --><% for (var chunk in htmlWebpackPlugin.files.js) { %><% if(htmlWebpackPlugin.files.js[chunk]) {%><script type="text/javascript" src="<%= htmlWebpackPlugin.files.js[chunk] %>"></script><%}%><% } %></body>
</html>
-
文档类型声明和头部:
<!DOCTYPE html>
: 声明 HTML5 文档类型。<head>
部分包含页面的元数据,如字符集、视口设置和标题。
-
动态注入 CSS:
- 使用 EJS 模板语法 (
<% ... %>
) 来循环遍历htmlWebpackPlugin.files.css
中的 CSS 文件。 - 如果文件存在,则生成对应的
<link>
标签,将 CSS 文件链接到页面中。
- 使用 EJS 模板语法 (
-
主体内容:
<body>
部分包含一个<div id="app"></div>
,这是 Vue.js 或其他前端框架通常用于挂载应用的根元素。
-
动态注入 JavaScript:
- 类似于 CSS 的处理,使用 EJS 模板语法来遍历
htmlWebpackPlugin.files.js
中的 JavaScript 文件。 - 如果文件存在,则生成对应的
<script>
标签,将 JS 文件链接到页面中。
- 类似于 CSS 的处理,使用 EJS 模板语法来遍历
以上我们使用模板语法手动获取并遍历 htmlWebpackPlugin 打包后的文件并生成到模板中,其中的 htmlWebpackPlugin
变量是模板提供的可访问变量,其有以下特定数据:
"htmlWebpackPlugin": {"files": {"css": [ "main.css" ],"js": [ "assets/head_bundle.js", "assets/main_bundle.js"],"chunks": {"head": {"entry": "assets/head_bundle.js","css": [ "main.css" ]},"main": {"entry": "assets/main_bundle.js","css": []},}}
}
我们通过 htmlWebpackPlugin.files
可以获取打包输出的 js 及 css 文件路径,包括入口文件路径等。
结合 html 模板文件和的 htmlWebpackPlugin
配置,最终生成的 HTML 文件会像下面这样:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>模板</title><!-- 注入的 CSS --><link href="main.css" rel="stylesheet" /></head><body><div id="app"></div><!-- built files will be auto injected --><!-- 注入的 JavaScript --><script type="text/javascript" src="assets/head_bundle.js"></script><script type="text/javascript" src="assets/main_bundle.js"></script></body>
</html>
需要注意的是如果你在模板中编写了插入对应 js 及 css 的语法,你需要设置 inject
的值为 false 来关闭资源的自动注入:
/* utils.js */
...let conf = {entry: filePath, // page 的入口template: filePath, // 模板路径filename: filename + '.html', // 生成 html 的文件名chunks: ['manifest', 'vendor', filename],inject: false, // 关闭资源自动注入
}...
否则在页面会引入两次资源,如下图所示:
2. 自定义配置
在模板渲染中,我们只能够使用 htmlWebpackPlugin 内部的一些属性和方法来进行模板的定制化开发,那么如果遇到需要根据不同环境来引入不同资源,同时不同模板间的配置还可能不一样的需求情况的话,我们使用自定义配置会比较方便。比如我们需要在生产环境模板中引入第三方统计脚本:
/* vue.config.js */module.exports = {...pages: utils.setPages({addScript() {if (process.env.NODE_ENV === 'production') {return `<script src="https://s95.cnzz.com/z_stat.php?id=xxx&web_id=xxx" language="JavaScript"></script>`}return ''}}),...
}
然后在页面模板中通过 htmlWebpackPlugin.options
获取自定义配置对象并进行输出:
<% if(htmlWebpackPlugin.options.addScript){ %><%= htmlWebpackPlugin.options.addScript() %>
<%}%>
同时你也可以针对个别模板进行配置,比如我想只在 Index 单页中添加统计脚本,在 Page1 单页中添加其他脚本,那么你可以给 addScript 传入标识符来进行判断输出,比如:
<% if(htmlWebpackPlugin.options.addScript){ %><%= htmlWebpackPlugin.options.addScript('index') %>
<%}%>
同时为 addScript 方法添加参数 from:
addScript(from) {if (process.env.NODE_ENV === 'production') {let url = "https://xxx";if (from === 'index') {url = "https://s95.cnzz.com/z_stat.php?id=xxx&web_id=xxx";}return `<script src=${url} language="JavaScript"></script>`}return ''
}
这样我们就完成了自定义配置中的模板渲染功能。当然根据实际项目需求你的自定义配置项可能会更加复杂和灵活。
拓展2
1、多页应用中各自的 Vuex Store
信息能实现共享吗
1. 使用 Local Storage 或 Session Storage
通过使用浏览器的 Local Storage 或 Session Storage,可以在不同页面之间共享状态。每个页面在加载时可以从 Local Storage 中读取状态,在状态变化时更新 Local Storage。
// 设置状态到 Local Storage
localStorage.setItem('myStoreState', JSON.stringify(store.state));// 从 Local Storage 获取状态
const savedState = JSON.parse(localStorage.getItem('myStoreState'));
if (savedState) {store.replaceState(savedState);
}
这种方法具有一定的局限性,因为它不能实时同步状态,用户在一个页面上进行的修改不会立即反映到其他页面上。
2. 使用 URL 参数
如果状态比较简单,可以通过 URL 参数在页面间传递状态。例如,在一个页面中点击链接,带上状态参数:
<a href="page2.html?myState=value">Go to Page 2</a>
在目标页面中,可以读取 URL 参数来获取状态:
const urlParams = new URLSearchParams(window.location.search);
const myState = urlParams.get('myState');
3. 使用 WebSocket 或其他实时通信技术
如果需要在页面间实现实时的状态共享,可以使用 WebSocket、Server-Sent Events 或其他实时通信技术。每个页面都可以连接到同一个 WebSocket 服务器,以便在状态变化时进行广播。
4. 使用 Shared Worker
Shared Worker 是一种在多个浏览器上下文(如多个标签页或窗口)间共享的 Worker。通过 Shared Worker,你可以在多个页面间共享状态。
// sharedWorker.js
let connections = [];
const storeState = { /* initial state */ };self.onconnect = function(event) {const port = event.ports[0];connections.push(port);port.onmessage = function(e) {// 更新状态逻辑storeState.value = e.data;connections.forEach(conn => conn.postMessage(storeState));};
};
然后在每个页面中连接到这个 Shared Worker:
const worker = new SharedWorker('sharedWorker.js');worker.port.onmessage = function(e) {// 处理状态更新const sharedState = e.data;
};worker.port.postMessage(newState);
5. 使用 Service Workers
Service Workers 可以缓存数据并在多个页面间共享,虽然通常它们用于缓存请求和离线功能,但也可以通过 IndexedDB 或其他方式存储状态。
注意事项
- 复杂性: 实现状态共享可能会增加应用的复杂性,特别是在处理状态同步和冲突时。
- 性能: 考虑性能影响,尤其是当状态较大或更新频繁时,使用 WebSocket 或 Shared Worker 可能更合适。
- 设计模式: 设计时要考虑如何管理状态的生命周期,确保在适当的时间清理不再需要的状态。
2.html-webpack-plugin 如何解析非 .html 的模板,比如 .hbs,应该如何配置?
html-webpack-plugin
是用于生成 HTML 文件的 Webpack 插件,默认情况下,它使用 .html
文件作为模板。但是,如果想使用其他类型的模板文件(如 .hbs
,即 Handlebars 模板),可以通过配置相应的加载器来实现。
以下是如何配置 html-webpack-plugin
以解析 .hbs
模板的步骤:
1. 安装必要的依赖
首先,确保安装了 html-webpack-plugin
和 handlebars-loader
(用于处理 Handlebars 模板):
npm install html-webpack-plugin handlebars-loader --save-dev
2. 配置 Webpack
然后,需要在 Webpack 配置文件中配置这两个包。一个典型的 Webpack 配置可能类似于以下内容:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/index.js', // 你的入口文件output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},module: {rules: [{test: /\.hbs$/,loader: 'handlebars-loader', // 使用 Handlebars 加载器},// 其他加载器...],},plugins: [new HtmlWebpackPlugin({template: './src/template.hbs', // 指定你的 Handlebars 模板filename: 'index.html', // 输出的 HTML 文件名}),],
};
3. 使用 Handlebars 模板
在 .hbs
模板文件中,可以使用 Handlebars 的语法来定义 HTML 结构。例如:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{{title}}</title>
</head>
<body><div id="app"></div><script src="bundle.js"></script>
</body>
</html>
4. 提供模板数据
如果需要在模板中使用动态数据(如标题等),可以在插件配置中通过 templateParameters
属性提供这些数据:
new HtmlWebpackPlugin({template: './src/template.hbs',filename: 'index.html',templateParameters: {title: 'My Handlebars Template',// 其他参数...},
}),
这样,{{title}}
将会被替换为 'My Handlebars Template'
。
相关文章:

Vue多页面路由与模版解析
上篇文章中我们成功打包并输出了多页文件,而构建一个多页应用能够让我们进一步了解项目配置的可拓展性,可以对学习 Vue 和 webpack 起到强化训练的效果,本文将在此基础上主要针对多页路由及模板的配置进行系列的介绍。 本案例代码地址&#…...

Python爬虫(二)- Requests 高级使用教程
文章目录 前言一、Session 对象1. 简介2. 跨请求保持 Cookie3. 设置缺省数据4. 方法级别参数不被跨请求保持5. 会话作为上下文管理器6. 移除字典参数中的值 二、请求与响应1. 请求与响应对象1.1 获取响应头信息1.2 获取发送到服务器的请求头信息 三、SSL 证书验证1. 忽略 SSL 证…...

并联带阻滤波器带通滤波器对幅值和相位的影响(IIR)
一、背景 输入信号input分别经过bp(带通滤波器)和bs(带阻滤波器)处理后相加输出。分析输出信号的幅值和相位受到的影响。 根据上图公式推导可知,并联滤波器对输出的影响可以直接分析,带通滤波器与带阻滤波器在频域上的加和。 二、…...

攻防世界web新手第五题supersqli
这是题目,题目看起来像是sql注入的题,先试一下最常规的,输入1,回显正常 输入1‘,显示错误 尝试加上注释符号#或者–或者%23(注释掉后面语句,使1后面的单引号与前面的单引号成功匹配就不会报错…...

vue3学习笔记(10)-$subscribe,store组合式写法
1.$subscribe订阅,监视vuex中数据得修改 2.localStorage里面穿的都是字符串,关掉浏览器数据还在 只能获取字符串,用ts语法写明,作为字符串使用 3.组合式写法...

操作系统论文导读(八):Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个
Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个关键性规范的零星任务的可调度性分析 目录 一、论文核心思想 二、基本定义 2.1 关键性指标 2.2 任务及相关参数定义 2.3 几个基础定义 三、可调度性分析 3.1 调度算法分…...
计算机网络与通信复习
因特网的核心部分(电路交换与分组交换的不同点,分组交换的优点) 核心部分:路由器、交换机 我们假如数据就是一个货物,比如说一千公斤的大米,电路交换要有专用通道,不管从起点到终点经过多少个…...

【Scala】图书项目系统代码演练3.1/BookService
package org.app package serviceimport models.{BookModel, BorrowRecordModel}import org.app.dao.{BookDAO, BorrowRecordDAO}import java.time.LocalDateTime import scala.collection.mutable.ListBuffer// 图书业务逻辑层 class BookService {private val bookDAO new B…...

人工智能基础软件-Jupyter Notebook
简介: Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算:开发、文档编写、运行代码和展示结果。 Jupyter Notebook是以网页的形式打开,可以在网页页面中直接编写代码和运行代码,代码的运行结果也会直…...
C++ 设计模式:模板方法(Template Method)
链接:C 设计模式 链接:C 设计模式 - 策略模式 链接:C 设计模式 - 观察者模式 模板方法(Template Method)是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。通过这…...
GDPU Vue前端框架开发 跨年大礼包
目录 选择题 填空题 简答题 记住,年底陪你跨年的不会仅是方便面跟你的闺蜜,还有孑的笔记。 选择题 1.下列选项用于设置Vue.js页面视图的元素是()。 A. Template B. script C. style D. title 2.下列选项中能够定义Vuejs根…...
搭建一个高效且安全的APP分发平台
搭建一个高效且安全的APP分发平台需要经历一系列精心规划和实施的步骤。以下是一个详细的指南,涵盖从准备阶段到后续维护阶段的各个环节: 一、准备阶段 明确目标与需求 确定平台的目标用户群体,了解他们的需求和偏好。分析竞争对手的分发平台…...

Leetcode打卡:二叉树中的链表
执行结果:通过 题目 1367 二叉树中的链表 给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表。 如果在二叉树中,存在一条一直向下的路径,且每个点的数值恰好一一对应以 head 为首的链表中每个节点的值,那么请你返回 …...

大数据技术-Hadoop(四)Yarn的介绍与使用
目录 一、Yarn 基本结构 1、Yarn基本结构 2、Yarn的工作机制 二、Yarn常用的命令 三、调度器 1、Capacity Scheduler(容量调度器) 1.1、特点 1.2、配置 1.2.1、yarn-site.xml 1.2.2、capacity-scheduler.xml 1.3、重启yarn、刷新队列 测试 向hi…...

算法 class 004(选择,冒泡,插入)
选择排序: 刚进入 j 循环的样子 j 跳出循环后,b 指向最小值的坐标 然后交换 i 和 b 位置的 值 随后 i , b i , i j1; 开始新一轮的排序, void SelectAQort(int* arr,int size)//选择排序 {for (int i 0; i < size-1; i){ //i 的位置就是…...
linux---awk命令详细教程
awk是一种强大的编程语言,用于在Linux/Unix系统下对文本和数据进行处理。以下是对awk的详细教程: 一、awk简介 awk由Alfred Aho、Brian Kernighan和Peter Weinberger三人开发,其名称分别代表这三位作者姓氏的第一个字母。awk支持用户自定义…...

一个通用的居于 OAuth2的API集成方案
在现代 web 应用程序中,OAuth 协议是授权和认证的主流选择。为了与多个授权提供商进行无缝对接,我们需要一个易于扩展和维护的 OAuth 解决方案。本文将介绍如何构建一个灵活的、支持多提供商的 OAuth 系统,包括动态 API 调用、路径参数替换、…...

STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
SMEC88ST SDK开发包下载 目前市场上很多嵌入式产品方案都是可以破解复制的,主要是因为方案主芯片不具备防破解的功能,这就导致开发者投入大量精力、财力开发的新产品一上市就被别人复制,到市场上的只能以价格竞争,最后工厂复制的产…...

QML学习(五) 做出第一个简单的应用程序
通过前面四篇对QML已经有了基本的了解,今天先尝试做出第一个单页面的桌面应用程序。 1.首先打开Qt,创建项目,选择“QtQuick Application - Empty” 空工程。 2.设置项目名称和项目代码存储路径 3.这里要注意选择你的编译器类型,以及输出的程…...
深入解析Android Framework中的android.location包:架构设计、设计模式与系统定制
深入解析Android Framework中的android.location包:架构设计、设计模式与系统定制 目录 引言android.location包概述核心类解析 LocationManagerLocationProviderLocationCriteriaGpsStatusGpsStatus.ListenerLocationListener位置服务的工作原理位置信息的获取与处理GPS状态…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...